rheolef  6.3
field_nonlinear_expr.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_FIELD_EXPR_NONLINEAR_H
2 #define _RHEOLEF_FIELD_EXPR_NONLINEAR_H
3 #include "rheolef/field_evaluate.h"
4 #include "rheolef/tensor4.h"
5 
6 #include <boost/functional.hpp>
7 
8 namespace rheolef {
9 namespace detail {
11 } // namespace detail
12 
13 template<class Function> class field_expr_terminal_function;
14 
15 template<class Function>
17 field_function (const Function& f)
18 {
20 }
21 
22 template<class Function>
24 public:
25 
28  typedef typename boost::unary_traits<Function>::function_type function_type;
29  typedef typename boost::unary_traits<Function>::result_type result_type;
33  typedef quadrature<float_type> pointset; // TODO: extends
34 
35 
37  : _f(f),
38  _is_initialized(false),
39  _omega(),
40  _piola_ops()
41  {}
42 
43 
45 
48 
49  void evaluate (const geo_element& K, std::vector<result_type>& value) const {
50  check_macro (_is_initialized, "may be initialized");
51  _omega.dis_inod (K, _dis_inod);
52  reference_element hat_K = K.variant();
53  value.resize (_piola_ops.size(hat_K));
54  size_type q = 0;
55  for (typename std::vector<result_type>::iterator
56  iter = value.begin(),
57  last = value.end(); iter != last; ++iter, ++q) {
59  *iter = _f (xq);
60  }
61  }
62  void initialize (const geo_basic<float_type,memory_type>& omega, const pointset& hat_x) const {
63  _omega = omega;
64  _piola_ops.set (hat_x, omega.get_piola_basis());
65  _is_initialized = true;
66  }
68  _omega = Xh.get_geo();
69  _piola_ops.set (Xh.get_numbering().get_basis(), _omega.get_piola_basis());
70  _is_initialized = true;
71  return true;
72  }
73 protected:
75  mutable bool _is_initialized;
78  mutable std::vector<size_type> _dis_inod;
79 };
80 template<class Function>
83  public smart_pointer<field_expr_terminal_function_rep<Function> >
84 {
85 public:
86 
89  typedef typename rep::size_type size_type;
90  typedef typename rep::memory_type memory_type;
91  typedef typename rep::result_type result_type;
92  typedef typename rep::value_type value_type;
93  typedef typename rep::scalar_type scalar_type;
94  typedef typename rep::float_type float_type;
95  typedef typename rep::pointset pointset;
97 
98 
99  field_expr_terminal_function(const Function& f) : base(new_macro(rep(f))) {}
100 
101 
102  space_constant::valued_type valued_tag() const { return base::data().valued_tag(); }
103 
104  void evaluate (const geo_element& K, std::vector<result_type>& value) const {
105  base::data().evaluate(K,value); }
106 
107  void initialize (const geo_basic<float_type,memory_type>& omega, const pointset& hat_x) const {
108  base::data().initialize(omega,hat_x);
109  }
111  return base::data().initialize(Xh);
112  }
113 };
114 template<class T, class M>
116 public:
117 
119  typedef M memory_type;
122  typedef T scalar_type;
124  typedef quadrature<float_type> pointset; // TODO: extends
125 
126 
128  : _uh(uh), _is_initialized(false), _bops(), _dis_idof() {}
129 
130  template <class Expr>
132  : _uh(expr), _is_initialized(false), _bops(), _dis_idof() {}
133 
134 
136 
137  space_constant::valued_type valued_tag() const { return _uh.valued_tag(); }
138 
139  template<class Result>
140  void evaluate (const geo_element& K, std::vector<Result>& value) const {
141  check_macro (_is_initialized, "may be initialized");
142  _check<Result>(); // run-time check :-(
143  reference_element hat_K = K.variant();
144  value.resize (_bops.size(hat_K));
145  _uh.get_space().dis_idof (K, _dis_idof);
146  size_type q = 0;
147  for (typename std::vector<Result>::iterator
148  iter = value.begin(),
149  last = value.end(); iter != last; ++iter, ++q) {
150  generic_field_evaluate (_uh, _bops, hat_K, _dis_idof, q, *iter);
151  }
152  }
153  void initialize (const geo_basic<float_type,memory_type>& omega, const pointset& hat_x) const {
154  _bops.set (hat_x, _uh.get_space().get_numbering().get_basis());
155  _uh.dis_dof_update();
156  _is_initialized = true;
157  }
159  _bops.set (Xh.get_numbering().get_basis(), _uh.get_space().get_numbering().get_basis());
160  _uh.dis_dof_update();
161  _is_initialized = true;
162  return are_compatible (_uh.get_space(), Xh);
163  }
164 protected:
165  template<class Result>
166  void _check () const {
168  check_macro (_uh.valued_tag() == result_valued_tag, "unexpected "<<_uh.valued()
169  << "-valued field for " << space_constant::valued_name(result_valued_tag)
170  << "-valued evaluator");
171  }
173  mutable bool _is_initialized;
175  mutable std::vector<size_type> _dis_idof;
176 };
177 template<class T, class M>
180  public smart_pointer<field_expr_terminal_field_rep<T,M> >
181 {
182 public:
183 
186  typedef typename rep::size_type size_type;
187  typedef typename rep::memory_type memory_type;
188  typedef typename rep::result_type result_type;
189  typedef typename rep::pointset pointset;
190  typedef typename rep::float_type float_type;
191  typedef typename rep::scalar_type scalar_type;
192  typedef typename rep::value_type value_type;
194 
195 
197  : base(new_macro(rep(uh))) {}
198 
199  template <class Expr>
201  : base(new_macro(rep(expr))) {}
202 
203 
204  space_constant::valued_type valued_tag() const { return base::data().valued_tag(); }
205 
206  template<class Result>
207  void evaluate (const geo_element& K, std::vector<Result>& value) const {
208  base::data().evaluate(K,value); }
209 
210  void initialize (const geo_basic<float_type,memory_type>& omega, const pointset& hat_x) const {
211  base::data().initialize(omega,hat_x);
212  }
214  return base::data().initialize(Xh);
215  }
216 };
217 template<class RawExpr>
219 public:
220 
222  typedef typename RawExpr::memory_type memory_type;
223  typedef typename RawExpr::result_type result_type;
224  typedef typename RawExpr::value_type value_type;
225  typedef typename RawExpr::float_type float_type;
226  typedef typename RawExpr::scalar_type scalar_type;
227  typedef quadrature<float_type> pointset; // TODO: extends
228 
229 
230  field_nonlinear_expr (const RawExpr& raw_expr)
231  : _raw_expr(raw_expr) {}
232 
233 
235 
236  space_constant::valued_type valued_tag() const { return _raw_expr.valued_tag(); }
237 
238  template<class Result>
239  void evaluate (const geo_element& K, std::vector<Result>& value) const {
240  _raw_expr.evaluate (K, value);
241  }
242  void initialize (const geo_basic<float_type,memory_type>& omega, const pointset& hat_x) const {
243  _raw_expr.initialize (omega, hat_x);
244  }
246  return _raw_expr.initialize (Xh);
247  }
248 
249 protected:
250  RawExpr _raw_expr;
251 };
252 template<class Function>
254  template<class T>
255  struct with {
256  typedef typename boost::remove_const<
257  typename boost::remove_reference<
258  typename boost::unary_traits<Function>::argument_type>::type>::type
260  typedef typename boost::unary_traits<Function>:: result_type result_type;
261  typedef typename boost::unary_traits<Function>::function_type function_type;
262  };
263  template <class Arg>
264  struct result_hint {
265  typedef typename boost::unary_traits<Function>::result_type type;
266  };
270  }
271 };
272 template<class Function, class Expr>
274 public:
275 
277  typedef typename Expr::memory_type memory_type;
278  typedef typename generic_unary_traits<Function>::template result_hint<typename Expr::result_type>::type result_type;
279  typedef Float float_type; // TODO
280  typedef Float scalar_type; // TODO
283 
284 
285  field_nonlinear_expr_uf (const Function& f, const field_nonlinear_expr<Expr>& expr)
286  : _f(f), _expr(expr) {}
287 
288 
290 
293  }
294 
295 
296  template<class Result, class Arg>
297  void evaluate_internal (const geo_element& K, std::vector<Result>& value) const {
298  _check<Result> ();
299  std::vector<Arg> tmp_value;
300  _expr.evaluate (K, tmp_value);
301  value.resize(tmp_value.size());
302  typename std::vector<Arg>::const_iterator tmp = tmp_value.begin();
303  for (typename std::vector<Result>::iterator
304  iter = value.begin(),
305  last = value.end(); iter != last; ++iter, ++tmp) {
306  *iter = _f(*tmp);
307  }
308  }
309  template<class This, class Result, class Arg, space_constant::valued_type ArgTag>
311  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
312  typedef typename scalar_traits<Arg>::type T;
313  space_constant::valued_type arg_valued_tag = obj._expr.valued_tag();
314  switch (arg_valued_tag) {
316  obj.template evaluate_internal<Result,T> (K, value);
317  break;
319  obj.template evaluate_internal<Result, point_basic<T> > (K, value);
320  break;
322  obj.template evaluate_internal<Result, tensor_basic<T> > (K, value);
323  break;
324  default:
325  error_macro ("unexpected valued tag="<<obj.valued_tag());
326  }
327  }
328  };
329  template<class This, class Result, class Arg>
330  struct evaluate_switch <This, Result, Arg, space_constant::scalar> {
331  typedef typename scalar_traits<Arg>::type T;
332  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
333  obj.template evaluate_internal<Result,T> (K, value);
334  }
335  };
336  template<class This, class Result, class Arg>
337  struct evaluate_switch <This, Result, Arg, space_constant::vector> {
338  typedef typename scalar_traits<Arg>::type T;
339  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
340  obj.template evaluate_internal<Result, point_basic<T> > (K, value);
341  }
342  };
343  template<class This, class Result, class Arg>
344  struct evaluate_switch <This, Result, Arg, space_constant::tensor> {
345  typedef typename scalar_traits<Arg>::type T;
346  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
347  obj.template evaluate_internal<Result, tensor_basic<T> > (K, value);
348  }
349  };
350  template<class Result>
351  void evaluate (const geo_element& K, std::vector<Result>& value) const
352  {
353  typedef typename generic_unary_traits<Function>::template with<Result>::argument_type argument_hint1_type;
354  typedef typename Expr::result_type argument_hint2_type;
355  typedef typename promote<argument_hint1_type, argument_hint2_type>::type argument_type;
359  eval (*this, K, value);
360  }
361 
362 
363  void initialize (const geo_basic<float_type,memory_type>& omega, const pointset& hat_x) const {
364  _expr.initialize (omega, hat_x);
365  }
367  return _expr.initialize (Xh);
368  }
369 
370 protected:
371  template<class Result>
372  void _check() const {
373 #ifdef TODO
375  check_macro (_expr.valued_tag() == arg_valued_tag, "invalid "
377  << "-valued expression for "
378  << space_constant::valued_name(arg_valued_tag)
379  << "-valued function argument");
380 #endif // TODO
381  }
382  Function _f;
384 };
385 template<class Function>
387  template<class T>
388  struct with {
389  typedef typename boost::remove_const<
390  typename boost::remove_reference<
391  typename boost::binary_traits<Function>::first_argument_type>::type>::type
393  typedef typename boost::remove_const<
394  typename boost::remove_reference<
395  typename boost::binary_traits<Function>::second_argument_type>::type>::type
397  typedef typename boost::binary_traits<Function>:: result_type result_type;
398  typedef typename boost::binary_traits<Function>:: function_type function_type;
399  };
400  template <class Arg1, class Arg2>
401  struct result_hint {
402  typedef typename boost::binary_traits<Function>::result_type type;
403  };
407  }
408 };
409 template<class Function, class Expr1, class Expr2>
411 public:
412 
414  typedef typename generic_binary_traits<Function>::template result_hint<typename Expr1::result_type,typename Expr2::result_type>::type result_type;
415  typedef Float float_type; // TODO
416  typedef Float scalar_type; // TODO
419  typedef typename Expr1::memory_type memory_type;
420 
421 
422  field_nonlinear_expr_bf (const Function& f,
423  const Expr1& expr1,
424  const Expr2& expr2)
425  : _f(f), _expr1(expr1), _expr2(expr2)
426  {
427  }
428 
429 
431 
433  return generic_binary_traits<Function>::valued_tag(_expr1.valued_tag(), _expr2.valued_tag());
434  }
435  template<class Result, class Arg1, class Arg2>
436  void evaluate_internal2 (const geo_element& K, std::vector<Result>& value) const {
437  _check<Result,Arg1,Arg2> ();
438  std::vector<Arg1> tmp1_value;
439  std::vector<Arg2> tmp2_value;
440  _expr1.evaluate (K, tmp1_value);
441  _expr2.evaluate (K, tmp2_value);
442  value.resize(tmp1_value.size());
443  typename std::vector<Arg1>::const_iterator tmp1 = tmp1_value.begin();
444  typename std::vector<Arg2>::const_iterator tmp2 = tmp2_value.begin();
445  for (typename std::vector<Result>::iterator
446  iter = value.begin(),
447  last = value.end(); iter != last; ++iter, ++tmp1, ++tmp2) {
448  *iter = _f (*tmp1, *tmp2);
449  }
450  }
451  template<class This, class Result, class ReturnType, class Arg1, class Arg2>
453  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
454  fatal_macro ("unexpected return type "
455  << pretty_typename_macro(ReturnType) << ": "
456  << pretty_typename_macro(Result) << " was expected for function "
457  << pretty_typename_macro(Function) << "("
458  << pretty_typename_macro(Arg1) << ","
459  << pretty_typename_macro(Arg2) << ")");
460  }
461  };
462  template<class This, class Result, class Arg1, class Arg2>
463  struct evaluate_internal<This,Result,Result,Arg1,Arg2> {
464  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
465  obj.template evaluate_internal2 <Result,Arg1,Arg2> (K, value);
466  }
467  };
468  template<class Result, class Arg1, class Arg2>
469  void evaluate_call (const geo_element& K, std::vector<Result>& value) const {
470  typedef typename generic_binary_traits<Function>::template result_hint<Arg1,Arg2>::type ReturnType;
473  eval_int (*this, K, value);
474  }
475  template<class This, class Result,
476  class Arg1, space_constant::valued_type Arg1Tag,
477  class Arg2, space_constant::valued_type Arg2Tag>
479  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
480  obj.template evaluate_call<Result, Arg1, Arg2> (K, value);
481  }
482  };
483  template<class This, class Result,
484  class Arg1,
485  class Arg2>
486  struct evaluate_switch<This, Result,
487  Arg1, space_constant::last_valued,
489  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
490  typedef typename scalar_traits<Arg1>::type T1;
491  typedef typename scalar_traits<Arg2>::type T2;
492  space_constant::valued_type arg1_valued_tag = obj._expr1.valued_tag();
493  space_constant::valued_type arg2_valued_tag = obj._expr2.valued_tag();
494  switch (arg1_valued_tag) {
495  case space_constant::scalar: {
496  switch (arg2_valued_tag) {
498  obj.template evaluate_call<Result, T1, T2> (K, value); break;
500  obj.template evaluate_call<Result, T1, point_basic<T2> > (K, value); break;
502  obj.template evaluate_call<Result, T1, tensor_basic<T2> > (K, value); break;
503  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
504  }
505  break;
506  }
507  case space_constant::vector: {
508  switch (arg2_valued_tag) {
510  obj.template evaluate_call<Result, point_basic<T1>, T2> (K, value); break;
512  obj.template evaluate_call<Result, point_basic<T1>, point_basic<T2> > (K, value); break;
514  obj.template evaluate_call<Result, point_basic<T1>, tensor_basic<T2> > (K, value); break;
515  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
516  }
517  break;
518  }
519  case space_constant::tensor: {
520  switch (arg2_valued_tag) {
522  obj.template evaluate_call<Result, tensor_basic<T1>, T2> (K, value); break;
524  obj.template evaluate_call<Result, tensor_basic<T1>, point_basic<T2> > (K, value); break;
526  obj.template evaluate_call<Result, tensor_basic<T1>, tensor_basic<T2> > (K, value); break;
527  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
528  }
529  break;
530  }
531  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
532  }
533  }
534  };
535  template<class This, class Result,
536  class Arg1, space_constant::valued_type Arg1Tag,
537  class Arg2>
538  struct evaluate_switch<This, Result,
539  Arg1, Arg1Tag,
540  Arg2, space_constant::last_valued> {
541  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
542  typedef typename scalar_traits<Arg2>::type T2;
543  space_constant::valued_type arg2_valued_tag = obj._expr2.valued_tag();
544  switch (arg2_valued_tag) {
546  obj.template evaluate_call<Result, Arg1, T2> (K, value); break;
548  obj.template evaluate_call<Result, Arg1, point_basic<T2> > (K, value); break;
550  obj.template evaluate_call<Result, Arg1, tensor_basic<T2> > (K, value); break;
551  default: error_macro ("unexpected second argument valued tag="<<arg2_valued_tag);
552  }
553  }
554  };
555  template<class This, class Result,
556  class Arg1,
557  class Arg2, space_constant::valued_type Arg2Tag>
558  struct evaluate_switch<This, Result,
559  Arg1, space_constant::last_valued,
560  Arg2, Arg2Tag> {
561  void operator() (const This& obj, const geo_element& K, std::vector<Result>& value) const {
562  typedef typename scalar_traits<Arg1>::type T1;
563  space_constant::valued_type arg1_valued_tag = obj._expr1.valued_tag();
564  switch (arg1_valued_tag) {
566  obj.template evaluate_call<Result, T1, Arg2> (K, value); break;
568  obj.template evaluate_call<Result, point_basic<T1>, Arg2> (K, value); break;
570  obj.template evaluate_call<Result, tensor_basic<T1>, Arg2> (K, value); break;
571  default: error_macro ("unexpected first argument valued tag="<<arg1_valued_tag);
572  }
573  }
574  };
575  template<class Result>
576  void evaluate (const geo_element& K, std::vector<Result>& value) const
577  {
578  typedef typename generic_binary_traits<Function>::template with<Result>::first_argument_type first_argument_hint1_type;
579  typedef typename Expr1::result_type first_argument_hint2_type;
580  typedef typename promote<first_argument_hint1_type, first_argument_hint2_type>::type first_argument_type;
581  typedef typename generic_binary_traits<Function>::template with<Result>::second_argument_type second_argument_hint1_type;
582  typedef typename Expr1::result_type second_argument_hint2_type;
583  typedef typename promote<second_argument_hint1_type, second_argument_hint2_type>::type second_argument_type;
587  evaluate_switch <This, Result,
588  first_argument_type, first_argument_tag,
589  second_argument_type, second_argument_tag> eval;
590  eval (*this, K, value);
591  }
592  void initialize (const geo_basic<float_type,memory_type>& omega, const pointset& hat_x) const
593  {
594  _expr1.initialize (omega, hat_x);
595  _expr2.initialize (omega, hat_x);
596  }
598  bool is_homogeneous1 = _expr1.initialize (Xh);
599  bool is_homogeneous2 = _expr2.initialize (Xh);
600  return is_homogeneous1 && is_homogeneous2;
601  }
602 
603 protected:
604  template<class Result, class Arg1, class Arg2>
605  void _check() const
606  {
607  typedef typename generic_binary_traits<Function>::template result_hint<Arg1,Arg2>::type Result2;
612  check_macro (_expr1.valued_tag() == arg1_valued_tag, "invalid "
613  << space_constant::valued_name(_expr1.valued_tag())
614  << "-valued expression for "
615  << space_constant::valued_name(arg1_valued_tag)
616  << "-valued function first argument");
617  check_macro (_expr2.valued_tag() == arg2_valued_tag, "invalid "
618  << space_constant::valued_name(_expr2.valued_tag())
619  << "-valued expression for "
620  << space_constant::valued_name(arg2_valued_tag)
621  << "-valued function second argument");
622  check_macro (resu_valued_tag == res2_valued_tag, "invalid "
623  << space_constant::valued_name(resu_valued_tag)
624  << "-valued result field for "
625  << space_constant::valued_name(res2_valued_tag)
626  << "-valued function return type");
627  }
628  Function _f;
629  Expr1 _expr1;
630  Expr2 _expr2;
631 };
632 
633 #ifndef TO_CLEAN
634 template<class Function, class Expr>
637 };
638 
639 template<class Function, class T, class M>
640 struct compose_result<Function, field_basic<T,M> > {
642 };
643 #endif // TO_CLEAN
644 
645 } // namespace rheolef
646 #endif // _RHEOLEF_FIELD_EXPR_NONLINEAR_H
647