Rheolef  7.1
an efficient C++ finite element environment
field_expr_variational.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_FIELD_EXPR_VARIATIONAL_H
2 #define _RHEOLEF_FIELD_EXPR_VARIATIONAL_H
23 //
24 // variational expressions are used for field assembly
25 // e.g. for right-hand-side of linear systems
26 //
27 // author: Pierre.Saramito@imag.fr
28 //
29 // date: 21 september 2015
30 //
31 // Notes: use template expressions and SFINAE techniques
32 //
33 // SUMMARY:
34 // 1. unary function
35 // 1.1. unary node
36 // 1.2. unary calls
37 // 2. binary operators +- between two variational exprs
38 // 2.1. binary node
39 // 2.2. binary calls
40 // 3. binary operators */ between a variational and a nonlinear expr
41 // 3.1. helper
42 // 3.2. binary node
43 // 3.3. binary calls
44 //
45 #include "rheolef/field_expr_variational_terminal.h"
46 
47 namespace rheolef {
48 
49 // ---------------------------------------------------------------------------
50 // 1. unary function
51 // ---------------------------------------------------------------------------
52 // 1.1. unary node
53 // ---------------------------------------------------------------------------
54 // ex: -v, 2*v, v/3
55 namespace details {
56 
57 template <class UnaryFunction, class Expr>
59 public:
60 // typedefs:
61 
63  typedef typename Expr::memory_type memory_type;
64  typedef typename details::generic_unary_traits<UnaryFunction>::template result_hint<typename Expr::value_type>::type
69  typedef typename Expr::vf_tag_type vf_tag_type;
75 
76 // alocators:
77 
78  field_expr_v2_variational_unary (const UnaryFunction& f, const Expr& expr)
79  : _f(f), _expr(expr) {}
80 
82  : _f(x._f), _expr(x._expr) {}
83 
84 // accessors:
85 
86  static bool have_test_space() { return true; } // check !
87  const space_type& get_vf_space() const { return _expr.get_vf_space(); }
91  }
92  size_type n_derivative() const { return _expr.n_derivative(); }
93 
94 // mutable modifiers:
95 
96  void initialize (const piola_on_pointset<float_type>& pops, const integrate_option& iopt) const {
97  _expr.initialize (pops, iopt);
98  }
100  _expr.initialize (gh, pops, iopt);
101  }
102  // -------------
103  // evaluate
104  // -------------
105  // evaluate when all arg types are determinated
106  template<class Result, class Arg, class Status>
108  template<class M>
110  const self_type& obj,
111  const geo_basic<float_type,M>& omega_K,
112  const geo_element& K, Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
113  {
114  fatal_macro ("invalid type resolution: Result="<<typename_macro(Result)
115  << ", Arg="<<typename_macro(Arg)
116  << ", UnaryFunction="<<typename_macro(UnaryFunction)
117  );
118  }
119  };
120  template<class Result, class Arg>
121  struct evaluate_call_check<Result,Arg,std::true_type> {
122  template<class M>
124  const self_type& obj,
125  const geo_basic<float_type,M>& omega_K,
126  const geo_element& K,
127  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
128  {
129  Eigen::Matrix<Arg,Eigen::Dynamic,Eigen::Dynamic> arg_value;
130  obj._expr.evaluate (omega_K, K, arg_value);
131  value = arg_value.unaryExpr (obj._f);
132  }
133  template<class M>
135  const self_type& obj,
136  const geo_basic<float_type,M>& omega_K,
137  const geo_element& K,
138  const side_information_type& sid,
139  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
140  bool do_local_component_assembly) const
141  {
142  Eigen::Matrix<Arg,Eigen::Dynamic,Eigen::Dynamic> arg_value;
143  obj._expr.evaluate_on_side (omega_K, K, sid, arg_value, do_local_component_assembly);
144  value = arg_value.unaryExpr (obj._f);
145  }
146  };
147  template<class Result, class Arg, class M>
149  const geo_basic<float_type,M>& omega_K,
150  const geo_element& K,
151  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
152  {
153  // check if Result is a valid return_type for this function:
154  typedef typename scalar_traits<Result>::type S;
155  typedef undeterminated_basic<S> undet;
156  typedef typename details::generic_unary_traits<UnaryFunction>::template hint<Arg,undet>::result_type result_type;
157  // TODO: instead of is_equal, could have compatible scalars T1,T2 ?
158  typedef typename details::is_equal<Result,result_type>::type status_t;
160  eval (*this, omega_K, K, value);
161  }
162  template<class Result, class Arg, class M>
164  const geo_basic<float_type,M>& omega_K,
165  const geo_element& K,
166  const side_information_type& sid,
167  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
168  bool do_local_component_assembly) const
169  {
170  // check if Result is a valid return_type for this function:
171  typedef typename scalar_traits<Result>::type S;
172  typedef undeterminated_basic<S> undet;
173  typedef typename details::generic_unary_traits<UnaryFunction>::template hint<Arg,undet>::result_type result_type;
174  // TODO: instead of is_equal, could have compatible scalars T1,T2 ?
175  typedef typename details::is_equal<Result,result_type>::type status_t;
177  eval (*this, omega_K, K, sid, value, do_local_component_assembly);
178  }
179  // when Arg is defined at compile time:
180  template<class This, class Result, class Arg, class Status>
182  template<class M>
184  const This& obj,
185  const geo_basic<float_type,M>& omega_K,
186  const geo_element& K,
187  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
188  {
189  obj.template evaluate_internal<Result, Arg> (omega_K, K, value);
190  }
191  template<class M>
193  const This& obj,
194  const geo_basic<float_type,M>& omega_K,
195  const geo_element& K,
196  const side_information_type& sid,
197  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
198  bool do_local_component_assembly) const
199  {
200  obj.template evaluate_internal<Result, Arg> (omega_K, K, sid, value, do_local_component_assembly);
201  }
202  };
203  // when Arg is undeterminated at compile time
204  template<class This, class Result, class Arg>
205  struct evaluate_switch<This, Result, Arg, std::true_type> {
206  template<class M>
208  const This& obj,
209  const geo_basic<float_type,M>& omega_K,
210  const geo_element& K,
211  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
212  {
213  typedef typename scalar_traits<Arg>::type T;
214  space_constant::valued_type arg_valued_tag = obj._expr.valued_tag();
215  switch (arg_valued_tag) {
216 #define _RHEOLEF_switch(VALUED,VALUE) \
217  case space_constant::VALUED: \
218  obj.template evaluate_internal<Result, VALUE>(omega_K, K, value); break;
225 #undef _RHEOLEF_switch
226  default: error_macro ("unexpected argument valued tag="<<arg_valued_tag);
227  }
228  }
229  template<class M>
231  const This& obj,
232  const geo_basic<float_type,M>& omega_K,
233  const geo_element& K,
234  const side_information_type& sid,
235  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
236  bool do_local_component_assembly) const
237  {
238  typedef typename scalar_traits<Arg>::type T;
239  space_constant::valued_type arg_valued_tag = obj._expr.valued_tag();
240  switch (arg_valued_tag) {
241 #define _RHEOLEF_switch(VALUED,VALUE) \
242  case space_constant::VALUED: \
243  obj.template evaluate_internal<Result, VALUE>(omega_K, K, sid,value, do_local_component_assembly); break;
250 #undef _RHEOLEF_switch
251  default: error_macro ("unexpected argument valued tag="<<arg_valued_tag);
252  }
253  }
254  };
255  template<class Result, class M>
256  void evaluate (
257  const geo_basic<float_type,M>& omega_K,
258  const geo_element& K,
259  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
260  {
261  typedef typename details::generic_unary_traits<UnaryFunction>::template hint<typename Expr::value_type,Result>::argument_type
262  A1;
263  typedef typename is_undeterminated<A1>::type status_t;
265  eval (*this, omega_K, K, value);
266  }
267  template<class Result, class M>
269  const geo_basic<float_type,M>& omega_K,
270  const geo_element& K,
271  const side_information_type& sid,
272  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
273  bool do_local_component_assembly) const
274  {
275  typedef typename details::generic_unary_traits<UnaryFunction>::template hint<typename Expr::value_type,Result>::argument_type
276  A1;
277  typedef typename is_undeterminated<A1>::type status_t;
279  eval (*this, omega_K, K, sid, value, do_local_component_assembly);
280  }
281  template<class Result>
282  void valued_check() const {
283  typedef typename details::generic_unary_traits<UnaryFunction>::template hint<typename Expr::value_type,Result>::argument_type
284  A1;
285  if (! is_undeterminated<A1>::value) _expr.template valued_check<A1>();
286  }
287 protected:
288 // data:
289  UnaryFunction _f;
290  Expr _expr;
291 };
292 template<class F, class Expr> struct is_field_expr_v2_variational_arg <field_expr_v2_variational_unary<F,Expr> > : std::true_type {};
293 
294 } // namespace details
295 
296 // ---------------------------------------------------------------------------
297 // 1.2. unary calls
298 // ---------------------------------------------------------------------------
299 
300 #define _RHEOLEF_make_field_expr_v2_variational_unary_operator(FUNCTION,FUNCTOR) \
301 template<class Expr> \
302 inline \
303 typename \
304 std::enable_if< \
305  details::is_field_expr_v2_variational_arg<Expr>::value \
306  ,details::field_expr_v2_variational_unary< \
307  FUNCTOR \
308  ,Expr \
309  > \
310 >::type \
311 FUNCTION (const Expr& expr) \
312 { \
313  return details::field_expr_v2_variational_unary <FUNCTOR,Expr> (FUNCTOR(), expr); \
314 }
315 
320 #undef _RHEOLEF_make_field_expr_v2_variational_unary_operator
321 
322 // ---------------------------------------------------------------------------
323 // 2. binary operators +- between variationals
324 // ---------------------------------------------------------------------------
325 // 2.1. binary node
326 // ---------------------------------------------------------------------------
327 // ex: v+v, v-v
328 
329 namespace details {
330 
331 template<class BinaryFunction, class Expr1, class Expr2>
333 public:
334 // typedefs:
335 
340  typename Expr1::value_type
341  ,typename Expr2::value_type>::type result_hint;
343  typename Expr1::value_type
344  ,typename Expr2::value_type
348  typedef space_basic<scalar_type,memory_type> space_type; // TODO: deduce from Exprs
349  typedef typename details::bf_vf_tag<BinaryFunction,
350  typename Expr1::vf_tag_type,
351  typename Expr2::vf_tag_type>::type vf_tag_type;
357 
358 // alocators:
359 
361  const Expr1& expr1,
362  const Expr2& expr2)
363  : _f(f), _expr1(expr1), _expr2(expr2) {}
364 
365 // accessors:
366 
367  static bool have_test_space() { return true; }
368  const space_type& get_vf_space() const { return _expr1.get_vf_space(); }
372  }
373  size_type n_derivative() const { return std::min(_expr1.n_derivative(), _expr2.n_derivative()); }
374 
375 // mutable modifiers:
376 
377  // TODO: check that expr1 & expr2 have the same get_vf_space()
378  void initialize (const piola_on_pointset<float_type>& pops, const integrate_option& iopt) const {
379  _expr1.initialize (pops, iopt);
380  _expr2.initialize (pops, iopt);
381  }
383  _expr1.initialize (gh, pops, iopt);
384  _expr2.initialize (gh, pops, iopt);
385  }
386  // evaluate when all arg types are determinated
387  template<class Result, class Arg1, class Arg2, class Status>
390  const self_type& obj,
391  const geo_basic<float_type,memory_type>& omega_K,
392  const geo_element& K,
393  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
394  {
395  fatal_macro ("invalid type resolution");
396  }
398  const self_type& obj,
399  const geo_basic<float_type,memory_type>& omega_K,
400  const geo_element& K,
401  const side_information_type& sid,
402  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
403  {
404  fatal_macro ("invalid type resolution");
405  }
406  };
407  template<class Result, class Arg1, class Arg2>
408  struct evaluate_call_check<Result,Arg1,Arg2,std::true_type> {
410  const self_type& obj,
411  const geo_basic<float_type,memory_type>& omega_K,
412  const geo_element& K,
413  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
414  {
415  Eigen::Matrix<Arg1,Eigen::Dynamic,Eigen::Dynamic> value1; obj._expr1.evaluate (omega_K, K, value1);
416  Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> value2; obj._expr2.evaluate (omega_K, K, value2);
417  // TODO: DVT_EIGEN_BLAS2
418  value.resize (value1.rows(), value1.cols());
419  for (size_type loc_inod = 0, loc_nnod = value1.rows(); loc_inod < loc_nnod; ++loc_inod) {
420  for (size_type loc_jdof = 0, loc_ndof = value1.cols(); loc_jdof < loc_ndof; ++loc_jdof) {
421  value(loc_inod,loc_jdof) = obj._f (value1(loc_inod,loc_jdof), value2(loc_inod,loc_jdof));
422  }}
423  }
425  const self_type& obj,
426  const geo_basic<float_type,memory_type>& omega_K,
427  const geo_element& K,
428  const side_information_type& sid,
429  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
430  bool do_local_component_assembly) const
431  {
432  Eigen::Matrix<Arg1,Eigen::Dynamic,Eigen::Dynamic> value1; obj._expr1.evaluate_on_side (omega_K, K, sid, value1, do_local_component_assembly);
433  Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> value2; obj._expr2.evaluate_on_side (omega_K, K, sid, value2, do_local_component_assembly);
434  // TODO: DVT_EIGEN_BLAS2
435  value.resize (value1.rows(), value1.cols());
436  for (size_type loc_inod = 0, loc_nnod = value1.rows(); loc_inod < loc_nnod; ++loc_inod) {
437  for (size_type loc_jdof = 0, loc_ndof = value1.cols(); loc_jdof < loc_ndof; ++loc_jdof) {
438  value(loc_inod,loc_jdof) = obj._f (value1(loc_inod,loc_jdof), value2(loc_inod,loc_jdof));
439  }}
440  }
441  };
442  template<class Result, class Arg1, class Arg2>
444  const geo_basic<float_type,memory_type>& omega_K,
445  const geo_element& K,
446  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
447  {
449  // TODO: instead of is_equal, could have compatible scalars T1,T2 ?
450  typedef typename details::is_equal<Result,result_type>::type status_t;
452  eval (*this, omega_K, K, value);
453  }
454  template<class Result, class Arg1, class Arg2>
456  const geo_basic<float_type,memory_type>& omega_K,
457  const geo_element& K,
458  const side_information_type& sid,
459  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
460  bool do_local_component_assembly) const
461  {
463  // TODO: instead of is_equal, could have compatible scalars T1,T2 ?
464  typedef typename details::is_equal<Result,result_type>::type status_t;
466  eval (*this, omega_K, K, sid, value, do_local_component_assembly);
467  }
468  template<class This, class Result, class Arg1, class Arg2, class Undet1, class Undet2>
469  struct evaluate_switch {};
470  // --------------------------------------------------------------------------
471  // when both args are defined at compile time:
472  // --------------------------------------------------------------------------
473  template<class This, class Result, class Arg1, class Arg2>
474  struct evaluate_switch<This, Result, Arg1, Arg2, std::false_type, std::false_type> {
475  void operator() (
476  const This& obj,
477  const geo_basic<float_type,memory_type>& omega_K,
478  const geo_element& K,
479  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
480  {
481  obj.template evaluate_internal<Result, Arg1, Arg2> (omega_K, K, value);
482  }
483  void operator() (
484  const This& obj,
485  const geo_basic<float_type,memory_type>& omega_K,
486  const geo_element& K,
487  const side_information_type& sid,
488  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
489  bool do_local_component_assembly) const
490  {
491  obj.template evaluate_on_side_internal<Result, Arg1, Arg2> (omega_K, K, sid, value, do_local_component_assembly);
492  }
493  };
494  // --------------------------------------------------------------------------
495  // when first arg is undeterminated
496  // --------------------------------------------------------------------------
497  template<class This, class Result, class Arg1, class Arg2>
498  struct evaluate_switch<This, Result, Arg1, Arg2, std::true_type, std::false_type> {
499  void operator() (
500  const This& obj,
501  const geo_basic<float_type,memory_type>& omega_K,
502  const geo_element& K,
503  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
504  {
505  typedef typename scalar_traits<Arg1>::type T1;
506  space_constant::valued_type arg1_valued_tag = obj._expr1.valued_tag();
507  switch (arg1_valued_tag) {
508 #define _RHEOLEF_switch1(VALUED1,VALUE1) \
509  case space_constant::VALUED1: \
510  obj.template evaluate_internal<Result, VALUE1, Arg2>(omega_K, K, value); break;
517 #undef _RHEOLEF_switch1
518  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
519  }
520  }
521  void operator() (
522  const This& obj,
523  const geo_basic<float_type,memory_type>& omega_K,
524  const geo_element& K,
525  const side_information_type& sid,
526  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
527  bool do_local_component_assembly) const
528  {
529  typedef typename scalar_traits<Arg1>::type T1;
530  space_constant::valued_type arg1_valued_tag = obj._expr1.valued_tag();
531  switch (arg1_valued_tag) {
532 #define _RHEOLEF_switch1(VALUED1,VALUE1) \
533  case space_constant::VALUED1: \
534  obj.template evaluate_on_side_internal<Result, VALUE1, Arg2>(omega_K, K, sid, value, do_local_component_assembly); break;
541 #undef _RHEOLEF_switch1
542  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
543  }
544  }
545  };
546  // --------------------------------------------------------------------------
547  // when second arg is undeterminated
548  // --------------------------------------------------------------------------
549  template<class This, class Result, class Arg1, class Arg2>
550  struct evaluate_switch<This, Result, Arg1, Arg2, std::false_type, std::true_type> {
551  void operator() (
552  const This& obj,
553  const geo_basic<float_type,memory_type>& omega_K,
554  const geo_element& K,
555  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
556  {
557  typedef typename scalar_traits<Arg2>::type T2;
558  space_constant::valued_type arg2_valued_tag = obj._expr2.valued_tag();
559  switch (arg2_valued_tag) {
560 #define _RHEOLEF_switch2(VALUED2,VALUE2) \
561  case space_constant::VALUED2: \
562  obj.template evaluate_internal<Result, Arg1, VALUE2>(omega_K, K, value); break;
569 #undef _RHEOLEF_switch2
570  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
571  }
572  }
573  void operator() (
574  const This& obj,
575  const geo_basic<float_type,memory_type>& omega_K,
576  const geo_element& K,
577  const side_information_type& sid,
578  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
579  bool do_local_component_assembly) const
580  {
581  typedef typename scalar_traits<Arg2>::type T2;
582  space_constant::valued_type arg2_valued_tag = obj._expr2.valued_tag();
583  switch (arg2_valued_tag) {
584 #define _RHEOLEF_switch2(VALUED2,VALUE2) \
585  case space_constant::VALUED2: \
586  obj.template evaluate_on_side_internal<Result, Arg1, VALUE2>(omega_K, K, sid, value, do_local_component_assembly); break;
593 #undef _RHEOLEF_switch2
594  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
595  }
596  }
597  };
598  // --------------------------------------------------------------------------
599  // when both are undefined at compile time:
600  // --------------------------------------------------------------------------
601  template<class This, class Result, class Arg1, class Arg2>
602  struct evaluate_switch<This, Result, Arg1, Arg2, std::true_type, std::true_type> {
603  void operator() (
604  const This& obj,
605  const geo_basic<float_type,memory_type>& omega_K,
606  const geo_element& K,
607  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
608  {
609  typedef typename scalar_traits<Arg1>::type T1;
610  typedef typename scalar_traits<Arg2>::type T2;
611  space_constant::valued_type arg1_valued_tag = obj._expr1.valued_tag();
612  space_constant::valued_type arg2_valued_tag = obj._expr2.valued_tag();
613  switch (arg1_valued_tag) {
614 #define _RHEOLEF_switch2(VALUE1,VALUED2,VALUE2) \
615  case space_constant::VALUED2: \
616  obj.template evaluate_internal<Result, VALUE1, VALUE2>(omega_K, K, value); break;
617 #define _RHEOLEF_switch1(VALUED1,VALUE1) \
618  case space_constant::VALUED1: { \
619  switch (arg2_valued_tag) { \
620 _RHEOLEF_switch2(VALUE1,scalar,T2) \
621 _RHEOLEF_switch2(VALUE1,vector,point_basic<T2>) \
622 _RHEOLEF_switch2(VALUE1,tensor,tensor_basic<T2>) \
623 _RHEOLEF_switch2(VALUE1,unsymmetric_tensor,tensor_basic<T2>) \
624 _RHEOLEF_switch2(VALUE1,tensor3,tensor3_basic<T2>) \
625 _RHEOLEF_switch2(VALUE1,tensor4,tensor4_basic<T2>) \
626  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag); \
627  } \
628  break; \
629  }
636 #undef _RHEOLEF_switch2
637 #undef _RHEOLEF_switch1
638  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
639  }
640  }
641  void operator() (
642  const This& obj,
643  const geo_basic<float_type,memory_type>& omega_K,
644  const geo_element& K,
645  const side_information_type& sid,
646  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
647  bool do_local_component_assembly) const
648  {
649  typedef typename scalar_traits<Arg1>::type T1;
650  typedef typename scalar_traits<Arg2>::type T2;
651  space_constant::valued_type arg1_valued_tag = obj._expr1.valued_tag();
652  space_constant::valued_type arg2_valued_tag = obj._expr2.valued_tag();
653  switch (arg1_valued_tag) {
654 #define _RHEOLEF_switch2(VALUE1,VALUED2,VALUE2) \
655  case space_constant::VALUED2: \
656  obj.template evaluate_on_side_internal<Result, VALUE1, VALUE2>(omega_K, K, sid, value, do_local_component_assembly); break;
657 #define _RHEOLEF_switch1(VALUED1,VALUE1) \
658  case space_constant::VALUED1: { \
659  switch (arg2_valued_tag) { \
660 _RHEOLEF_switch2(VALUE1,scalar,T2) \
661 _RHEOLEF_switch2(VALUE1,vector,point_basic<T2>) \
662 _RHEOLEF_switch2(VALUE1,tensor,tensor_basic<T2>) \
663 _RHEOLEF_switch2(VALUE1,unsymmetric_tensor,tensor_basic<T2>) \
664 _RHEOLEF_switch2(VALUE1,tensor3,tensor3_basic<T2>) \
665 _RHEOLEF_switch2(VALUE1,tensor4,tensor4_basic<T2>) \
666  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag); \
667  } \
668  break; \
669  }
676 #undef _RHEOLEF_switch2
677 #undef _RHEOLEF_switch1
678  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
679  }
680  }
681  };
682  // --------------------------------------------------------------------------
683  // main eval call:
684  // --------------------------------------------------------------------------
685  template<class Result>
686  struct hint {
688  typename Expr1::value_type
689  ,typename Expr2::value_type
690  ,Result>::first_argument_type A1;
692  typename Expr1::value_type
693  ,typename Expr2::value_type
694  ,Result>::second_argument_type A2;
695  };
696  template<class Result>
697  void evaluate (
698  const geo_basic<float_type,memory_type>& omega_K,
699  const geo_element& K,
700  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
701  {
702  typedef typename hint<Result>::A1 A1;
703  typedef typename hint<Result>::A2 A2;
704  typedef typename is_undeterminated<A1>::type undet_1;
705  typedef typename is_undeterminated<A2>::type undet_2;
707  eval (*this, omega_K, K, value);
708  }
709  template<class Result>
711  const geo_basic<float_type,memory_type>& omega_K,
712  const geo_element& K,
713  const side_information_type& sid,
714  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
715  bool do_local_component_assembly) const
716  {
717  typedef typename hint<Result>::A1 A1;
718  typedef typename hint<Result>::A2 A2;
719  typedef typename is_undeterminated<A1>::type undet_1;
720  typedef typename is_undeterminated<A2>::type undet_2;
722  eval (*this, omega_K, K, sid, value, do_local_component_assembly);
723  }
724  template<class Result>
725  void valued_check() const {
726  typedef typename hint<Result>::A1 A1;
727  typedef typename hint<Result>::A2 A2;
728  if (! is_undeterminated<A1>::value) _expr1.template valued_check<A1>();
729  if (! is_undeterminated<A2>::value) _expr2.template valued_check<A2>();
730  }
731 protected:
732 // data:
735  Expr2 _expr2;
736 };
737 template <class F, class Expr1, class Expr2> struct is_field_expr_v2_variational_arg <field_expr_v2_variational_binary<F,Expr1,Expr2> > : std::true_type {};
738 
739 } // namespace details
740 // ---------------------------------------------------------------------------
741 // 2.2. binary call
742 // ---------------------------------------------------------------------------
743 namespace details {
744 
745 template<class Expr1, class Expr2, class Sfinae = void>
747 
748 template<class Expr1, class Expr2>
750  Expr1
751  ,Expr2
752  ,typename
753  std::enable_if<
754  is_field_expr_v2_variational_arg<Expr1>::value
755  && is_field_expr_v2_variational_arg<Expr2>::value
756  >::type
757 >
758 : and_type<
759  is_field_expr_v2_variational_arg<Expr1>
760  ,is_field_expr_v2_variational_arg<Expr2>
761  ,std::is_same <
762  typename Expr1::vf_tag_type
763  ,typename Expr2::vf_tag_type
764  >
765  >
766 {};
767 
768 } // namespace details
769 
770 #define _RHEOLEF_make_field_expr_v2_variational_binary_operator_plus_minus(FUNCTION,FUNCTOR) \
771 template<class Expr1, class Expr2> \
772 inline \
773 typename \
774 std::enable_if< \
775  details::is_field_expr_v2_variational_binary_plus_minus <Expr1,Expr2>::value \
776  ,details::field_expr_v2_variational_binary< \
777  FUNCTOR \
778  ,Expr1 \
779  ,Expr2 \
780  > \
781 >::type \
782 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
783 { \
784  return details::field_expr_v2_variational_binary <FUNCTOR, Expr1, Expr2> (FUNCTOR(), expr1, expr2); \
785 }
786 
789 #undef _RHEOLEF_make_field_expr_v2_variational_binary_operator_plus_minus
790 
791 // ---------------------------------------------------------------------------
792 // 3. binary operators */ between a variational and a nonlinear expr
793 // ---------------------------------------------------------------------------
794 // 3.1. helper
795 // ---------------------------------------------------------------------------
796 namespace details {
797 
798  template<class This, class Arg1>
799  struct nl_switch {
800  typedef typename This::size_type size_type;
801  void element_initialize (const This& obj, const geo_element& K) const {
802  space_constant::valued_type nl_arg_valued_tag = obj._nl_expr.valued_tag();
803  switch (nl_arg_valued_tag) {
805  obj._nl_expr.evaluate (K, obj._scalar_nl_value_quad); break;
807  obj._nl_expr.evaluate (K, obj._vector_nl_value_quad); break;
810  obj._nl_expr.evaluate (K, obj._tensor_nl_value_quad); break;
812  obj._nl_expr.evaluate (K, obj._tensor3_nl_value_quad); break;
814  obj._nl_expr.evaluate (K, obj._tensor4_nl_value_quad); break;
815  default: error_macro ("unexpected first argument valued tag="<<nl_arg_valued_tag); // ICI
816  }
817  }
818  void element_initialize_on_side (const This& obj, const geo_element& K, const side_information_type& sid) const {
819  space_constant::valued_type nl_arg_valued_tag = obj._nl_expr.valued_tag();
820  switch (nl_arg_valued_tag) {
822  obj._nl_expr.evaluate_on_side (K, sid, obj._scalar_nl_value_quad); break;
824  obj._nl_expr.evaluate_on_side (K, sid, obj._vector_nl_value_quad); break;
827  obj._nl_expr.evaluate_on_side (K, sid, obj._tensor_nl_value_quad); break;
829  obj._nl_expr.evaluate_on_side (K, sid, obj._tensor3_nl_value_quad); break;
831  obj._nl_expr.evaluate_on_side (K, sid, obj._tensor4_nl_value_quad); break;
832  default: error_macro ("unexpected first argument valued tag="<<nl_arg_valued_tag);
833  }
834  }
835  Arg1 get_nl_value (const This& obj, size_type q) const {
836  // Arg1 may be solved at compile time for real evaluation
837  fatal_macro ("unexpected argument type="<<typename_macro(Arg1));
838  return Arg1();
839  }
840  };
841  template<class This> struct nl_switch<This,typename This::scalar_type> {
842  typedef typename This::size_type size_type;
843  typedef typename This::scalar_type scalar_type;
844  void element_initialize (const This& obj, const geo_element& K) const {
845  obj._nl_expr.evaluate (K, obj._scalar_nl_value_quad); }
846  void element_initialize_on_side (const This& obj, const geo_element& K, const side_information_type& sid) const {
847  obj._nl_expr.evaluate_on_side (K, sid, obj._scalar_nl_value_quad); }
848  const scalar_type& get_nl_value (const This& obj, size_type q) const {
849  return obj._scalar_nl_value_quad[q]; }
850  };
851  template<class This> struct nl_switch<This,point_basic<typename This::scalar_type> > {
852  typedef typename This::size_type size_type;
853  typedef typename This::scalar_type scalar_type;
854  void element_initialize (const This& obj, const geo_element& K) const {
855  obj._nl_expr.evaluate (K, obj._vector_nl_value_quad); }
856  void element_initialize_on_side (const This& obj, const geo_element& K, const side_information_type& sid) const {
857  obj._nl_expr.evaluate_on_side (K, sid, obj._vector_nl_value_quad); }
858  const point_basic<scalar_type>& get_nl_value (const This& obj, size_type q) const {
859  return obj._vector_nl_value_quad[q]; }
860  };
861  template<class This> struct nl_switch<This,tensor_basic<typename This::scalar_type> > {
862  typedef typename This::size_type size_type;
863  typedef typename This::scalar_type scalar_type;
864  void element_initialize (const This& obj, const geo_element& K) const {
865  obj._nl_expr.evaluate (K, obj._tensor_nl_value_quad); }
866  void element_initialize_on_side (const This& obj, const geo_element& K, const side_information_type& sid) const {
867  obj._nl_expr.evaluate_on_side (K, sid, obj._tensor_nl_value_quad); }
868  const tensor_basic<scalar_type>& get_nl_value (const This& obj, size_type q) const {
869  return obj._tensor_nl_value_quad[q]; }
870  };
871  template<class This> struct nl_switch<This,tensor3_basic<typename This::scalar_type> > {
872  typedef typename This::size_type size_type;
873  typedef typename This::scalar_type scalar_type;
874  void element_initialize (const This& obj, const geo_element& K) const {
875  obj._nl_expr.evaluate (K, obj._tensor3_nl_value_quad); }
876  void element_initialize_on_side (const This& obj, const geo_element& K, const side_information_type& sid) const {
877  obj._nl_expr.evaluate_on_side (K, sid, obj._tensor3_nl_value_quad); }
878  const tensor3_basic<scalar_type>& get_nl_value (const This& obj, size_type q) const {
879  return obj._tensor3_nl_value_quad[q]; }
880  };
881  template<class This> struct nl_switch<This,tensor4_basic<typename This::scalar_type> > {
882  typedef typename This::size_type size_type;
883  typedef typename This::scalar_type scalar_type;
884  void element_initialize (const This& obj, const geo_element& K) const {
885  obj._nl_expr.evaluate (K, obj._tensor4_nl_value_quad); }
886  void element_initialize_on_side (const This& obj, const geo_element& K, const side_information_type& sid) const {
887  obj._nl_expr.evaluate_on_side (K, sid, obj._tensor4_nl_value_quad); }
888  const tensor4_basic<scalar_type>& get_nl_value (const This& obj, size_type q) const {
889  return obj._tensor4_nl_value_quad[q]; }
890  };
891 
892 } // namespace details
893 
894 // ---------------------------------------------------------------------------
895 // 3.2. binary node
896 // ---------------------------------------------------------------------------
897 //
898 // function call: (f nl_expr vf_expr)
899 // examples: f = operator*, operator/
900 // eta_h*v
901 // v/eta_h
902 // dot(v,normal())
903 // at any quadrature node xq, the compuation eta_h(xq) is performed
904 // and then we loop on the basis functions for v :
905 // eta_q = eta_h(xq);
906 // for i=0..nk-1
907 // value[i] = f (eta_q, v(xq)[i]);
908 // since we can swap the two args (see the details::swap_fun<f> class),
909 // we assume that the first argument is a field or a general field_nl_expr
910 // and that the second argument is a test of a general field_vf_expr
911 //
912 // Implementation note: this operation do not reduces to field_expr_v2_variational_unary
913 // with a class-function that contains eta_h since :
914 // - the value of eta_h may be refreshed at each xq
915 // (this could be achieved by replacing std::binder1st with an adequate extension)
916 // - the valued category of eta_h is not always known at compile-time.
917 // It is known in dot(eta_h,v) but not with eta_h*v
918 // and the class-functions for field_expr_v2_variational_unary may have Arg1 and Result determined.
919 // So we switch to a specific field_expr_v2_variational_binary_binded that is abble to solve the
920 // valued type at run time. When it is possible, it is determined at compile-time.
921 //
922 namespace details {
923 
924 template<class BinaryFunction, class NLExpr, class VFExpr>
926 public:
927 // typedefs:
928 
933  typename NLExpr::value_type
934  ,typename VFExpr::value_type>::type result_hint;
936  typename NLExpr::value_type
937  ,typename VFExpr::value_type
941  typedef space_basic<scalar_type,memory_type> space_type; // TODO: deduce from Exprs
942  typedef typename VFExpr::vf_tag_type vf_tag_type;
948 
949 // alocators:
950 
952  const NLExpr& nl_expr,
953  const VFExpr& vf_expr)
954  : _f(f),
955  _nl_expr(nl_expr),
956  _vf_expr(vf_expr)
957  {}
958 
960  : _f(x._f),
961  _nl_expr(x._nl_expr),
962  _vf_expr(x._vf_expr)
963  {}
964 
965 // accessors:
966 
967  static bool have_test_space() { return true; } // deduce & check !
968  const space_type& get_vf_space() const { return _vf_expr.get_vf_space(); }
972  }
973  size_type n_derivative() const { return _vf_expr.n_derivative(); }
974 
975 // mutable modifiers:
976 
977  void initialize (const piola_on_pointset<float_type>& pops, const integrate_option& iopt) const {
978  _nl_expr.initialize (pops, iopt);
979  _vf_expr.initialize (pops, iopt);
980  }
982  _nl_expr.initialize ( pops, iopt);
983  _vf_expr.initialize (gh, pops, iopt);
984  }
985  // ---------------------------------------------
986  // evaluate
987  // ---------------------------------------------
988  // evaluate when all arg types are determinated
989  template<class Result, class Arg1, class Arg2, class Status>
992  const self_type& obj,
993  const geo_basic<float_type,memory_type>& omega_K,
994  const geo_element& K,
995  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
996  {
997  fatal_macro ("invalid type resolution");
998  }
1000  const self_type& obj,
1001  const geo_basic<float_type,memory_type>& omega_K,
1002  const geo_element& K,
1003  const side_information_type& sid,
1004  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1005  bool do_local_component_assembly) const
1006  {
1007  fatal_macro ("invalid type resolution");
1008  }
1009  };
1010  template<class Result, class Arg1, class Arg2>
1011  struct evaluate_call_check<Result,Arg1,Arg2,std::true_type> {
1013  const self_type& obj,
1014  const geo_basic<float_type,memory_type>& omega_K,
1015  const geo_element& K,
1016  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
1017  {
1018  Eigen::Matrix<Arg1,Eigen::Dynamic,1> value1; obj._nl_expr.evaluate (omega_K, K, value1);
1019  Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> value2; obj._vf_expr.evaluate (omega_K, K, value2);
1020  check_macro (value1.size() == value2.rows(), "invalid sizes value1(nnod="<<value1.size()
1021  <<") and value2(nnod="<<value2.rows()<<",ndof="<<value2.cols()<<")");
1022  value.resize (value2.rows(), value2.cols());
1023  for (size_type loc_inod = 0, loc_nnod = value2.rows(); loc_inod < loc_nnod; ++loc_inod) {
1024  for (size_type loc_jdof = 0, loc_ndof = value2.cols(); loc_jdof < loc_ndof; ++loc_jdof) {
1025  value(loc_inod,loc_jdof) = obj._f (value1[loc_inod], value2(loc_inod,loc_jdof)); // TODO: DVT_EIGEN_BLAS2
1026  }}
1027  }
1029  const self_type& obj,
1030  const geo_basic<float_type,memory_type>& omega_K,
1031  const geo_element& K,
1032  const side_information_type& sid,
1033  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1034  bool do_local_component_assembly) const
1035  {
1036  Eigen::Matrix<Arg1,Eigen::Dynamic,1> value1; obj._nl_expr.evaluate_on_side (omega_K, K, sid, value1);
1037  Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> value2; obj._vf_expr.evaluate_on_side (omega_K, K, sid, value2, do_local_component_assembly);
1038  check_macro (value1.size() == value2.rows(), "invalid sizes value1(nnod="<<value1.size()
1039  <<") and value2(nnod="<<value2.rows()<<",ndof="<<value2.cols()<<")");
1040  value.resize (value2.rows(), value2.cols());
1041  for (size_type loc_inod = 0, loc_nnod = value2.rows(); loc_inod < loc_nnod; ++loc_inod) {
1042  for (size_type loc_jdof = 0, loc_ndof = value2.cols(); loc_jdof < loc_ndof; ++loc_jdof) {
1043  value(loc_inod,loc_jdof) = obj._f (value1[loc_inod], value2(loc_inod,loc_jdof)); // TODO: DVT_EIGEN_BLAS2
1044  }}
1045  }
1046  };
1047  template<class Result, class Arg1, class Arg2>
1049  const geo_basic<float_type,memory_type>& omega_K,
1050  const geo_element& K,
1051  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
1052  {
1054  // TODO: instead of is_equal, could have compatible scalars T1,T2 ?
1055  typedef typename details::is_equal<Result,result_type>::type status_t;
1057  eval (*this, omega_K, K, value);
1058  }
1059  template<class Result, class Arg1, class Arg2>
1061  const geo_basic<float_type,memory_type>& omega_K,
1062  const geo_element& K,
1063  const side_information_type& sid,
1064  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1065  bool do_local_component_assembly) const
1066  {
1068  // TODO: instead of is_equal, could have compatible scalars T1,T2 ?
1069  typedef typename details::is_equal<Result,result_type>::type status_t;
1071  eval (*this, omega_K, K, sid, value, do_local_component_assembly);
1072  }
1073  template<class This, class Result, class Arg1, class Arg2, class Undet1, class Undet2>
1074  struct evaluate_switch {};
1075  // --------------------------------------------------------------------------
1076  // when both args are defined at compile time:
1077  // --------------------------------------------------------------------------
1078  template<class This, class Result, class Arg1, class Arg2>
1079  struct evaluate_switch<This, Result, Arg1, Arg2, std::false_type, std::false_type> {
1080  void operator() (
1081  const This& obj,
1082  const geo_basic<float_type,memory_type>& omega_K,
1083  const geo_element& K,
1084  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
1085  {
1086  obj.template evaluate_internal<Result, Arg1, Arg2> (omega_K, K, value);
1087  }
1088  void operator() (
1089  const This& obj,
1090  const geo_basic<float_type,memory_type>& omega_K,
1091  const geo_element& K,
1092  const side_information_type& sid,
1093  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1094  bool do_local_component_assembly) const
1095  {
1096  obj.template evaluate_on_side_internal<Result, Arg1, Arg2> (omega_K, K, sid, value, do_local_component_assembly);
1097  }
1098  };
1099  // --------------------------------------------------------------------------
1100  // when first arg is undeterminated
1101  // --------------------------------------------------------------------------
1102  template<class This, class Result, class Arg1, class Arg2>
1103  struct evaluate_switch<This, Result, Arg1, Arg2, std::true_type, std::false_type> {
1104  void operator() (
1105  const This& obj,
1106  const geo_basic<float_type,memory_type>& omega_K,
1107  const geo_element& K,
1108  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
1109  {
1110  typedef typename scalar_traits<Arg1>::type T1;
1111  space_constant::valued_type arg1_valued_tag = obj._nl_expr.valued_tag();
1112  switch (arg1_valued_tag) {
1113 #define _RHEOLEF_switch(A1_VALUED,A1_VALUE) \
1114  case space_constant::A1_VALUED: \
1115  obj.template evaluate_internal<Result, A1_VALUE, Arg2> (omega_K, K, value); break;
1122 #undef _RHEOLEF_switch
1123  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
1124  }
1125  }
1126  void operator() (
1127  const This& obj,
1128  const geo_basic<float_type,memory_type>& omega_K,
1129  const geo_element& K,
1130  const side_information_type& sid,
1131  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1132  bool do_local_component_assembly) const
1133  {
1134  typedef typename scalar_traits<Arg1>::type T1;
1135  space_constant::valued_type arg1_valued_tag = obj._nl_expr.valued_tag();
1136  switch (arg1_valued_tag) {
1137 #define _RHEOLEF_switch(A1_VALUED,A1_VALUE) \
1138  case space_constant::A1_VALUED: \
1139  obj.template evaluate_on_side_internal<Result, A1_VALUE, Arg2> (omega_K, K, sid, value, do_local_component_assembly); break;
1146 #undef _RHEOLEF_switch
1147  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
1148  }
1149  }
1150  };
1151  // --------------------------------------------------------------------------
1152  // when second arg is undeterminated
1153  // --------------------------------------------------------------------------
1154  template<class This, class Result, class Arg1, class Arg2>
1155  struct evaluate_switch<This, Result, Arg1, Arg2, std::false_type, std::true_type> {
1156  void operator() (
1157  const This& obj,
1158  const geo_basic<float_type,memory_type>& omega_K,
1159  const geo_element& K,
1160  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
1161  {
1162  typedef typename scalar_traits<Arg2>::type T2;
1163  space_constant::valued_type arg2_valued_tag = obj._vf_expr.valued_tag();
1164  switch (arg2_valued_tag) {
1165 #define _RHEOLEF_switch(A2_VALUED,A2_VALUE) \
1166  case space_constant::A2_VALUED: \
1167  obj.template evaluate_internal<Result, Arg1, A2_VALUE> (omega_K, K, value); break;
1174 #undef _RHEOLEF_switch
1175  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
1176  }
1177  }
1178  void operator() (
1179  const This& obj,
1180  const geo_basic<float_type,memory_type>& omega_K,
1181  const geo_element& K,
1182  const side_information_type& sid,
1183  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1184  bool do_local_component_assembly) const
1185  {
1186  typedef typename scalar_traits<Arg2>::type T2;
1187  space_constant::valued_type arg2_valued_tag = obj._vf_expr.valued_tag();
1188  switch (arg2_valued_tag) {
1189 #define _RHEOLEF_switch(A2_VALUED,A2_VALUE) \
1190  case space_constant::A2_VALUED: \
1191  obj.template evaluate_on_side_internal<Result, Arg1, A2_VALUE> (omega_K, K, sid, value, do_local_component_assembly); break;
1198 #undef _RHEOLEF_switch
1199  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
1200  }
1201  }
1202  };
1203  // --------------------------------------------------------------------------
1204  // when both are undefined at compile time:
1205  // --------------------------------------------------------------------------
1206  template<class This, class Result, class Arg1, class Arg2>
1207  struct evaluate_switch<This, Result, Arg1, Arg2, std::true_type, std::true_type> {
1208  void operator() (
1209  const This& obj,
1210  const geo_basic<float_type,memory_type>& omega_K,
1211  const geo_element& K,
1212  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
1213  {
1214  typedef typename scalar_traits<Arg1>::type T1;
1215  typedef typename scalar_traits<Arg2>::type T2;
1216  space_constant::valued_type arg1_valued_tag = obj._nl_expr.valued_tag();
1217  space_constant::valued_type arg2_valued_tag = obj._vf_expr.valued_tag();
1218  switch (arg1_valued_tag) {
1219 #define _RHEOLEF_switch_A2(A1_VALUE,A2_VALUED,A2_VALUE) \
1220  case space_constant::A2_VALUED: \
1221  obj.template evaluate_internal<Result, A1_VALUE, A2_VALUE> (omega_K, K, value); break;
1222 
1223 #define _RHEOLEF_switch(A1_VALUED,A1_VALUE) \
1224  case space_constant::A1_VALUED: { \
1225  switch (arg2_valued_tag) { \
1226 _RHEOLEF_switch_A2(A1_VALUE,scalar,T2) \
1227 _RHEOLEF_switch_A2(A1_VALUE,vector,point_basic<T2>) \
1228 _RHEOLEF_switch_A2(A1_VALUE,tensor,tensor_basic<T2>) \
1229 _RHEOLEF_switch_A2(A1_VALUE,unsymmetric_tensor,tensor_basic<T2>) \
1230 _RHEOLEF_switch_A2(A1_VALUE,tensor3,tensor3_basic<T2>) \
1231 _RHEOLEF_switch_A2(A1_VALUE,tensor4,tensor4_basic<T2>) \
1232  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag); \
1233  } \
1234  break; \
1235  }
1242 #undef _RHEOLEF_switch
1243 #undef _RHEOLEF_switch_A2
1244  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
1245  }
1246  }
1247  void operator() (
1248  const This& obj,
1249  const geo_basic<float_type,memory_type>& omega_K,
1250  const geo_element& K,
1251  const side_information_type& sid,
1252  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1253  bool do_local_component_assembly) const
1254  {
1255  typedef typename scalar_traits<Arg1>::type T1;
1256  typedef typename scalar_traits<Arg2>::type T2;
1257  space_constant::valued_type arg1_valued_tag = obj._nl_expr.valued_tag();
1258  space_constant::valued_type arg2_valued_tag = obj._vf_expr.valued_tag();
1259  switch (arg1_valued_tag) {
1260 #define _RHEOLEF_switch_A2(A1_VALUE,A2_VALUED,A2_VALUE) \
1261  case space_constant::A2_VALUED: \
1262  obj.template evaluate_on_side_internal<Result, A1_VALUE, A2_VALUE> (omega_K, K, sid, value, do_local_component_assembly); break;
1263 
1264 #define _RHEOLEF_switch(A1_VALUED,A1_VALUE) \
1265  case space_constant::A1_VALUED: { \
1266  switch (arg2_valued_tag) { \
1267 _RHEOLEF_switch_A2(A1_VALUE,scalar,T2) \
1268 _RHEOLEF_switch_A2(A1_VALUE,vector,point_basic<T2>) \
1269 _RHEOLEF_switch_A2(A1_VALUE,tensor,tensor_basic<T2>) \
1270 _RHEOLEF_switch_A2(A1_VALUE,unsymmetric_tensor,tensor_basic<T2>) \
1271 _RHEOLEF_switch_A2(A1_VALUE,tensor3,tensor3_basic<T2>) \
1272 _RHEOLEF_switch_A2(A1_VALUE,tensor4,tensor4_basic<T2>) \
1273  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag); \
1274  } \
1275  break; \
1276  }
1283 #undef _RHEOLEF_switch
1284 #undef _RHEOLEF_switch_A2
1285  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
1286  }
1287  }
1288  };
1289  // --------------------------------------------------------------------------
1290  // hint fort argument's types when Result is known
1291  // --------------------------------------------------------------------------
1292  template<class Result>
1293  struct hint {
1294  typedef typename promote<
1295  typename NLExpr::value_type
1297  typename NLExpr::value_type
1298  ,typename VFExpr::value_type
1299  ,Result>::first_argument_type
1301  typedef typename promote<
1302  typename VFExpr::value_type
1304  typename NLExpr::value_type
1305  ,typename VFExpr::value_type
1306  ,Result>::second_argument_type
1308  };
1309  // --------------------------------------------------------------------------
1310  // evaluate : main call with possibly runtime type resolutiion
1311  // --------------------------------------------------------------------------
1312  template<class Result>
1313  void evaluate (
1314  const geo_basic<float_type,memory_type>& omega_K,
1315  const geo_element& K,
1316  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value) const
1317  {
1318  typedef typename hint<Result>::A1 A1;
1319  typedef typename hint<Result>::A2 A2;
1322  typedef typename is_undeterminated<A1>::type undet_1;
1323  typedef typename is_undeterminated<A2>::type undet_2;
1325  eval (*this, omega_K, K, value);
1326  }
1327  template<class Result>
1329  const geo_basic<float_type,memory_type>& omega_K,
1330  const geo_element& K,
1331  const side_information_type& sid,
1332  Eigen::Matrix<Result,Eigen::Dynamic,Eigen::Dynamic>& value,
1333  bool do_local_component_assembly) const
1334  {
1335  typedef typename hint<Result>::A1 A1;
1336  typedef typename hint<Result>::A2 A2;
1339  typedef typename is_undeterminated<A1>::type undet_1;
1340  typedef typename is_undeterminated<A2>::type undet_2;
1342  eval (*this, omega_K, K, sid, value, do_local_component_assembly);
1343  }
1344  template<class Value>
1346  const geo_basic<float_type,memory_type>& omega_K,
1347  const geo_element& S,
1348  const geo_element& K0,
1349  const geo_element& K1,
1350  const Eigen::Matrix<Value,Eigen::Dynamic,Eigen::Dynamic>& value0,
1351  const Eigen::Matrix<Value,Eigen::Dynamic,Eigen::Dynamic>& value1,
1352  Eigen::Matrix<Value,Eigen::Dynamic,Eigen::Dynamic>& value) const
1353  {
1354  _vf_expr.local_dg_merge_on_side (omega_K, S, K0, K1, value0, value1, value);
1355  }
1356  template<class Result>
1357  void valued_check() const {
1358  typedef typename hint<Result>::A1 A1;
1359  typedef typename hint<Result>::A2 A2;
1360  if (! is_undeterminated<A1>::value) _nl_expr.template valued_check<A1>();
1361  if (! is_undeterminated<A2>::value) _vf_expr.template valued_check<A2>();
1362  }
1363 //protected:
1364 // data:
1366  NLExpr _nl_expr;
1367  VFExpr _vf_expr;
1368 };
1369 template<class F, class Expr1, class Expr2> struct is_field_expr_v2_variational_arg <field_expr_v2_variational_binary_binded<F,Expr1,Expr2> > : std::true_type {};
1370 
1371 } // namespace details
1372 // ---------------------------------------------------------------------------
1373 // 3.3. binary calls
1374 // ---------------------------------------------------------------------------
1375 namespace details {
1376 
1377 template<class Expr1, class Expr2, class Sfinae = void>
1379 
1380 template<class Expr1, class Expr2>
1382  Expr1
1383  ,Expr2
1384  ,typename
1385  std::enable_if<
1386  is_field_expr_v2_nonlinear_arg <Expr1>::value
1387  && ! is_field_expr_v2_constant <Expr1>::value
1388  && is_field_expr_v2_variational_arg<Expr2>::value
1389  >::type
1390 >
1391 : std::true_type
1392 {};
1393 
1394 template<class Expr1, class Expr2>
1397 
1398 } // namespace details
1399 
1400 #define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_left(FUNCTION,FUNCTOR) \
1401 template<class Expr1, class Expr2> \
1402 inline \
1403 typename \
1404 std::enable_if< \
1405  details::is_field_expr_v2_variational_binary_multiplies_divides_left <Expr1,Expr2>::value \
1406  ,details::field_expr_v2_variational_binary_binded< \
1407  FUNCTOR \
1408  ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type \
1409  ,Expr2 /* vf */ \
1410  > \
1411 >::type \
1412 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
1413 { \
1414  typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type wrap1_t; \
1415  return details::field_expr_v2_variational_binary_binded \
1416  <FUNCTOR, wrap1_t, Expr2> \
1417  (FUNCTOR(), wrap1_t(expr1), expr2); \
1418 }
1419 
1420 #define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_right(FUNCTION,FUNCTOR) \
1421 template<class Expr1, class Expr2> \
1422 inline \
1423 typename \
1424 std::enable_if< \
1425  details::is_field_expr_v2_variational_binary_multiplies_divides_right <Expr1,Expr2>::value \
1426  ,details::field_expr_v2_variational_binary_binded< \
1427  details::swapper<FUNCTOR> \
1428  , typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type \
1429  ,Expr1 /* vf */ \
1430  > \
1431 >::type \
1432 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
1433 { \
1434  typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type wrap2_t; \
1435  return details::field_expr_v2_variational_binary_binded \
1436  <details::swapper<FUNCTOR>, wrap2_t, Expr1> \
1437  (details::swapper<FUNCTOR>(FUNCTOR()), wrap2_t(expr2), expr1); \
1438 }
1439 #define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides(FUNCTION,FUNCTOR) \
1440  _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_left (FUNCTION,FUNCTOR) \
1441  _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_right (FUNCTION,FUNCTOR)
1442 
1447 #undef _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_left
1448 #undef _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_right
1449 #undef _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides
1450 
1451 // ---------------------------------------------------------------------------
1452 // 5. binary operators */ between one variational and a constant
1453 // ---------------------------------------------------------------------------
1454 namespace details {
1455 
1456 template<class Expr1, class Expr2, class Sfinae = void>
1458 
1459 template<class Expr1, class Expr2>
1461  Expr1
1462  ,Expr2
1463  ,typename
1464  std::enable_if<
1465  is_field_expr_v2_constant <Expr1>::value
1466  && is_field_expr_v2_variational_arg<Expr2>::value
1467  >::type
1468 >
1469 : std::true_type
1470 {};
1471 
1472 template<class Expr1, class Expr2>
1475 
1476 } // namespace details
1477 
1478 #define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_left(FUNCTION,FUNCTOR) \
1479 template<class Expr1, class Expr2> \
1480 inline \
1481 typename \
1482 std::enable_if< \
1483  details::is_field_expr_v2_variational_binary_multiplies_divides_constant_left <Expr1,Expr2>::value \
1484  ,details::field_expr_v2_variational_unary< \
1485  details::binder_first <FUNCTOR, Expr1> \
1486  ,Expr2 /* vf */ \
1487  > \
1488 >::type \
1489 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
1490 { \
1491  return details::field_expr_v2_variational_unary \
1492  <details::binder_first <FUNCTOR,Expr1>, Expr2> \
1493  (details::binder_first <FUNCTOR,Expr1> (FUNCTOR(), expr1), expr2); \
1494 }
1495 
1496 #define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_right(FUNCTION,FUNCTOR) \
1497 template<class Expr1, class Expr2> \
1498 inline \
1499 typename \
1500 std::enable_if< \
1501  details::is_field_expr_v2_variational_binary_multiplies_divides_constant_right <Expr1,Expr2>::value \
1502  ,details::field_expr_v2_variational_unary< \
1503  details::binder_second <FUNCTOR, Expr2> \
1504  ,Expr1 /* vf */ \
1505  > \
1506 >::type \
1507 FUNCTION (const Expr1& expr1, const Expr2& expr2) \
1508 { \
1509  return details::field_expr_v2_variational_unary \
1510  <details::binder_second <FUNCTOR,Expr2>, Expr1> \
1511  (details::binder_second <FUNCTOR,Expr2> (FUNCTOR(), expr2), expr1); \
1512 }
1513 
1514 #define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant(FUNCTION,FUNCTOR) \
1515  _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_left (FUNCTION,FUNCTOR) \
1516  _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_right (FUNCTION,FUNCTOR)
1517 
1518 
1523 
1524 #undef _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_right
1525 #undef _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_left
1526 #undef _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant
1527 
1528 } // namespace rheolef
1529 #endif // _RHEOLEF_FIELD_EXPR_VARIATIONAL_H
field::size_type size_type
Definition: branch.cc:425
field gh(Float epsilon, Float t, const field &uh, const test &v)
void evaluate_on_side_internal(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, const side_information_type &sid, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value, bool do_local_component_assembly) const
details::generic_binary_traits< BinaryFunction >::template result_hint< typename NLExpr::value_type,typename VFExpr::value_type >::type result_hint
field_expr_v2_variational_binary_binded(const field_expr_v2_variational_binary_binded< BinaryFunction, NLExpr, VFExpr > &x)
void initialize(const band_basic< float_type, memory_type > &gh, const piola_on_pointset< float_type > &pops, const integrate_option &iopt) const
details::generic_binary_traits< BinaryFunction >::template hint< typename NLExpr::value_type,typename VFExpr::value_type,result_hint >::result_type value_type
field_expr_v2_variational_binary_binded< BinaryFunction, NLExpr, VFExpr > self_type
void initialize(const piola_on_pointset< float_type > &pops, const integrate_option &iopt) const
field_expr_v2_variational_binary_binded(const BinaryFunction &f, const NLExpr &nl_expr, const VFExpr &vf_expr)
details::dual_vf_tag< vf_tag_type >::type vf_dual_tag_type
void local_dg_merge_on_side(const geo_basic< float_type, memory_type > &omega_K, const geo_element &S, const geo_element &K0, const geo_element &K1, const Eigen::Matrix< Value, Eigen::Dynamic, Eigen::Dynamic > &value0, const Eigen::Matrix< Value, Eigen::Dynamic, Eigen::Dynamic > &value1, Eigen::Matrix< Value, Eigen::Dynamic, Eigen::Dynamic > &value) const
void evaluate_on_side(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, const side_information_type &sid, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value, bool do_local_component_assembly) const
void evaluate(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
promote_memory< typename NLExpr::memory_type, typename VFExpr::memory_type >::type memory_type
field_expr_v2_variational_binary_binded< BinaryFunction, NLExpr, typename VFExpr::dual_self_type > dual_self_type
void evaluate_internal(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
void evaluate_on_side_internal(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, const side_information_type &sid, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value, bool do_local_component_assembly) const
details::generic_binary_traits< BinaryFunction >::template result_hint< typename Expr1::value_type,typename Expr2::value_type >::type result_hint
space_basic< scalar_type, memory_type > space_type
promote_memory< typename Expr1::memory_type, typename Expr2::memory_type >::type memory_type
void initialize(const band_basic< float_type, memory_type > &gh, const piola_on_pointset< float_type > &pops, const integrate_option &iopt) const
details::generic_binary_traits< BinaryFunction >::template hint< typename Expr1::value_type,typename Expr2::value_type,result_hint >::result_type value_type
field_expr_v2_variational_binary< BinaryFunction, typename Expr1::dual_self_type, typename Expr2::dual_self_type > dual_self_type
field_expr_v2_variational_binary< BinaryFunction, Expr1, Expr2 > self_type
field_expr_v2_variational_binary(const BinaryFunction &f, const Expr1 &expr1, const Expr2 &expr2)
void initialize(const piola_on_pointset< float_type > &pops, const integrate_option &iopt) const
details::bf_vf_tag< BinaryFunction, typename Expr1::vf_tag_type, typename Expr2::vf_tag_type >::type vf_tag_type
static const space_constant::valued_type valued_hint
details::dual_vf_tag< vf_tag_type >::type vf_dual_tag_type
void evaluate_on_side(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, const side_information_type &sid, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value, bool do_local_component_assembly) const
void evaluate(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
void evaluate_internal(const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
space_basic< scalar_type, memory_type > space_type
field_expr_v2_variational_unary< UnaryFunction, typename Expr::dual_self_type > dual_self_type
field_expr_v2_variational_unary< UnaryFunction, Expr > self_type
field_expr_v2_variational_unary(const field_expr_v2_variational_unary< UnaryFunction, Expr > &x)
void initialize(const band_basic< float_type, memory_type > &gh, const piola_on_pointset< float_type > &pops, const integrate_option &iopt) const
void evaluate_internal(const geo_basic< float_type, M > &omega_K, const geo_element &K, const side_information_type &sid, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value, bool do_local_component_assembly) const
void evaluate_internal(const geo_basic< float_type, M > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
void initialize(const piola_on_pointset< float_type > &pops, const integrate_option &iopt) const
static const space_constant::valued_type valued_hint
details::dual_vf_tag< vf_tag_type >::type vf_dual_tag_type
field_expr_v2_variational_unary(const UnaryFunction &f, const Expr &expr)
void evaluate(const geo_basic< float_type, M > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
details::generic_unary_traits< UnaryFunction >::template result_hint< typename Expr::value_type >::type value_type
void evaluate_on_side(const geo_basic< float_type, M > &omega_K, const geo_element &K, const side_information_type &sid, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value, bool do_local_component_assembly) const
generic mesh with rerefence counting
Definition: geo.h:1089
see the geo_element page for the full documentation
Definition: geo_element.h:102
reference_element::size_type size_type
Definition: geo_element.h:125
see the integrate_option page for the full documentation
the finite element space
Definition: space.h:352
rheolef::std type
typename details::generic_binary_traits< BinaryFunction >::template result_hint< typename Expr1::result_type, typename Expr2::result_type >::type result_type
rheolef::std BinaryFunction
rheolef::std value
rheolef::std Expr1
dot(x,y): see the expression page for the full documentation
see the tensor3 page for the full documentation
see the tensor4 page for the full documentation
see the tensor page for the full documentation
#define error_macro(message)
Definition: dis_macros.h:49
#define fatal_macro(message)
Definition: dis_macros.h:33
Expr1::float_type T
Definition: field_expr.h:261
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
#define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_right(FUNCTION, FUNCTOR)
#define _RHEOLEF_switch(VALUED, VALUE)
#define _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_right(FUNCTION, FUNCTOR)
#define _RHEOLEF_switch2(VALUED2, VALUE2)
#define _RHEOLEF_switch1(VALUED1, VALUE1)
This file is part of Rheolef.
_RHEOLEF_make_field_expr_v2_variational_unary_operator(operator+, details::unary_plus) _RHEOLEF_make_field_expr_v2_variational_unary_operator(operator-
csr< T, sequential > trans(const csr< T, sequential > &a)
trans(a): see the form page for the full documentation
Definition: csr.h:455
rheolef::std enable_if ::type dot const Expr1 expr1, const Expr2 expr2 dot(const Expr1 &expr1, const Expr2 &expr2)
dot(x,y): see the expression page for the full documentation
Definition: vec_expr_v2.h:415
_RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides(operator*, details::multiplies) _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_right(operator/
_RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant(operator*, details::multiplies) _RHEOLEF_make_field_expr_v2_variational_binary_operator_multiplies_divides_constant_right(operator/
U tr(const tensor_basic< U > &a, size_t d=3)
T ddot(const tensor_basic< T > &a, const tensor_basic< T > &b)
ddot(x,y): see the expression page for the full documentation
Definition: tensor.cc:278
_RHEOLEF_make_field_expr_v2_variational_binary_operator_plus_minus(operator+, details::plus) _RHEOLEF_make_field_expr_v2_variational_binary_operator_plus_minus(operator-
Definition: cavity_dg.h:29
void operator()(const self_type &obj, const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
details::generic_binary_traits< BinaryFunction >::template hint< typename Expr1::value_type,typename Expr2::value_type,Result >::first_argument_type A1
details::generic_binary_traits< BinaryFunction >::template hint< typename Expr1::value_type,typename Expr2::value_type,Result >::second_argument_type A2
void operator()(const self_type &obj, const geo_basic< float_type, memory_type > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
promote< typename NLExpr::value_type,typename details::generic_binary_traits< BinaryFunction >::template hint< typename NLExpr::value_type,typename VFExpr::value_type,Result >::first_argument_type >::type A1
promote< typename VFExpr::value_type,typename details::generic_binary_traits< BinaryFunction >::template hint< typename NLExpr::value_type,typename VFExpr::value_type,Result >::second_argument_type >::type A2
void operator()(const self_type &obj, const geo_basic< float_type, M > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
void operator()(const This &obj, const geo_basic< float_type, M > &omega_K, const geo_element &K, Eigen::Matrix< Result, Eigen::Dynamic, Eigen::Dynamic > &value) const
static space_constant::valued_type valued_tag(space_constant::valued_type, space_constant::valued_type)
Definition: expression.h:421
static space_constant::valued_type valued_tag(space_constant::valued_type)
Definition: expression.h:199
void element_initialize_on_side(const This &obj, const geo_element &K, const side_information_type &sid) const
const point_basic< scalar_type > & get_nl_value(const This &obj, size_type q) const
void element_initialize_on_side(const This &obj, const geo_element &K, const side_information_type &sid) const
const tensor3_basic< scalar_type > & get_nl_value(const This &obj, size_type q) const
void element_initialize_on_side(const This &obj, const geo_element &K, const side_information_type &sid) const
const tensor4_basic< scalar_type > & get_nl_value(const This &obj, size_type q) const
void element_initialize_on_side(const This &obj, const geo_element &K, const side_information_type &sid) const
const tensor_basic< scalar_type > & get_nl_value(const This &obj, size_type q) const
void element_initialize_on_side(const This &obj, const geo_element &K, const side_information_type &sid) const
const scalar_type & get_nl_value(const This &obj, size_type q) const
void element_initialize(const This &obj, const geo_element &K) const
void element_initialize_on_side(const This &obj, const geo_element &K, const side_information_type &sid) const
Arg1 get_nl_value(const This &obj, size_type q) const
void element_initialize(const This &obj, const geo_element &K) const
helper for generic field value_type: T, point_basic<T> or tensor_basic<T>