NiHu  2.0
field.hpp
Go to the documentation of this file.
1 // This file is a part of NiHu, a C++ BEM template library.
2 //
3 // Copyright (C) 2012-2014 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2014 Peter Rucz <rucz@hit.bme.hu>
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
28 #ifndef NIHU_FIELD_HPP_INCLUDED
29 #define NIHU_FIELD_HPP_INCLUDED
30 
31 #include "../util/crtp_base.hpp"
32 #include "corner_angle.hpp"
33 #include "element.hpp"
34 #include "field_dimension.hpp"
35 
36 namespace NiHu
37 {
38 
40 namespace field_option
41 {
43 struct isoparametric {};
45 struct constant {};
46 }
47 
48 namespace field_traits
49 {
51 template <class Derived>
52 struct elem_type;
53 
55 template <class Derived>
56 struct nset_type;
57 
59 template <class Derived>
61 
63 template <class Derived>
64 struct is_dof_vector_stored : std::false_type {};
65 
67 template <class Derived>
68 struct is_dirac : std::false_type {};
69 
71 template <class Derived>
72 struct id
73 {
75  enum {
76  value =
78  };
79 };
80 
82 template <class Derived>
84 {
85  typedef Eigen::Matrix<
86  unsigned,
88  1
89  > type;
90 };
91 
93 template <class Derived>
94 struct dof_vector_return_type : std::conditional<
95  is_dof_vector_stored<Derived>::value,
96  typename dof_vector_type<Derived>::type const &,
97  typename dof_vector_type<Derived>::type
98 > {};
99 
101 template <class Derived>
102 struct eval_return_type : shape_set_traits::shape_return_type<typename nset_type<Derived>::type, 0> {};
103 } // namespace NiHu::field_traits
104 
105 
110 template <class Derived>
112 {
113 public:
115 
117  typedef Derived type;
118 
122  typedef typename elem_t::x_t x_t;
124  typedef typename elem_t::xi_t xi_t;
128  typedef typename field_traits::dof_vector_type<Derived>::type dofs_t;
131 
132  typedef typename field_traits::eval_return_type<Derived>::type eval_return_t;
133 
134  enum {
140  num_dofs = quantity_dimension * nset_t::num_nodes
141  };
142 
143  eval_return_t eval(xi_t const &xi) const
144  {
145  return derived().eval(xi);
146  }
147 
149  elem_t const &get_elem() const
150  {
151  return derived().get_elem();
152  }
153 
156  {
157  return derived().get_dofs();
158  }
159 
160  double get_corner_angle(unsigned nset_corner_idx) const
161  {
162  return corner_angle_computer<elem_t, nset_t>::eval(get_elem(), nset_corner_idx);
163  }
164 };
165 
166 
167 
169 template <class Derived>
171 
172 
173 // forward declaration
174 template <class Field>
176 
177 namespace field_traits
178 {
179 template <class Derived>
180 struct elem_type<dirac_field<Derived> > : elem_type<Derived> {};
181 
182 template <class Derived>
183 struct nset_type<dirac_field<Derived> > : nset_type<Derived> {};
184 
185 template <class Derived>
186 struct quantity_dimension<dirac_field<Derived> > : quantity_dimension<Derived> {};
187 
188 template <class Derived>
189 struct is_dirac<dirac_field<Derived> > : std::true_type {};
190 }
191 
192 
196 template <class Field>
197 class dirac_field :
198  public field_base<dirac_field<Field> >,
199  public field_impl<Field>
200 {
201 public:
203  typedef dirac_field type;
204 
207 
211  typedef Field field_t;
212 
213  typedef typename field_base<dirac_field<Field>>::nset_t nset_t;
214 
215  using impl_t::get_elem;
216  using impl_t::get_dofs;
217 };
218 
219 
220 // forward declaration
221 template <class ElemType, class FieldOption, class Dimension = field_dimension::_1d>
223 
224 namespace field_traits
225 {
227 template <class ElemType, class FieldOption, class Dimension>
228 struct elem_type<field_view<ElemType, FieldOption, Dimension> > : ElemType {};
229 
231 template <class ElemType, class Dimension>
232 struct nset_type<field_view<ElemType, field_option::isoparametric, Dimension> >
233 {
234  typedef typename ElemType::lset_t type;
235 };
236 
238 template <class ElemType, class Dimension>
239 struct nset_type<field_view<ElemType, field_option::constant, Dimension> >
240 {
242 };
243 
245 template <class ElemType, class FieldOption, class Dimension>
246 struct quantity_dimension<field_view<ElemType, FieldOption, Dimension> > : Dimension {};
247 }
248 
249 
255 template <class ElemType, class Dimension>
256 class field_impl<field_view<ElemType, field_option::isoparametric, Dimension> > :
257  public ElemType
258 {
260  typedef typename field_traits::dof_vector_type<Derived>::type dofs_t;
261  typedef typename field_traits::dof_vector_return_type<Derived>::type dofs_return_t;
262  typedef typename field_traits::eval_return_type<Derived>::type eval_return_t;
263  typedef typename field_traits::nset_type<Derived>::type nset_t;
264  typedef typename ElemType::xi_t xi_t;
265 public:
266 
267  eval_return_t eval(xi_t const &xi) const
268  {
269  return nset_t::template eval_shape<0>(xi);
270  }
271 
272 
274  ElemType const &get_elem() const
275  {
276  return *this; // static cast
277  }
278 
280  dofs_return_t get_dofs() const
281  {
282  enum { D = Dimension::value };
283  dofs_t dofs;
284  for (unsigned n = 0; n < ElemType::num_nodes; ++n)
285  for (unsigned d = 0; d < D; ++d)
286  dofs(n*D + d) = ElemType::get_nodes()(n)*D + d;
287  return dofs;
288  }
289 };
290 
291 
292 
293 
298 template <class ElemType, class Dimension>
299 class field_impl<field_view< ElemType, field_option::constant, Dimension> > :
300  public ElemType
301 {
302 private:
304  typedef typename field_traits::dof_vector_type<Derived>::type dofs_t;
305  typedef typename field_traits::dof_vector_return_type<Derived>::type dofs_return_t;
306  typedef typename field_traits::eval_return_type<Derived>::type eval_return_t;
307  typedef typename field_traits::nset_type<Derived>::type nset_t;
308  typedef typename ElemType::xi_t xi_t;
309 public:
310 
311  eval_return_t eval(xi_t const &xi) const
312  {
313  return nset_t::template eval_shape<0>(xi);
314  }
315 
317  ElemType const &get_elem() const
318  {
319  return *this; // static cast
320  }
321 
323  dofs_return_t get_dofs() const
324  {
325  enum { D = Dimension::value };
326  return dofs_t::LinSpaced(D, ElemType::get_id()(0)*D, ElemType::get_id()(0)*D + D - 1);
327  }
328 };
329 
330 
336 template <class ElemType, class Option, class Dimension>
337 class field_view :
338  public field_base<field_view<ElemType, Option, Dimension> >,
339  public field_impl<field_view<ElemType, Option, Dimension> >
340 {
342  typedef field_base<field_view<ElemType, Option, Dimension> > crtp_base_t;
344  typedef field_impl<field_view<ElemType, Option, Dimension> > impl_t;
345 
346 public:
348  typedef field_view type;
349 
351  typedef typename crtp_base_t::elem_t elem_t;
352 
353  enum {
354  id = crtp_base_t::id
355  };
356 
357  typedef typename crtp_base_t::nset_t nset_t;
358 
359  using impl_t::eval;
360  using impl_t::get_elem;
361  using impl_t::get_dofs;
362 };
363 
364 
366 template <class ElemType, class NSet, class Dimension>
367 class field;
368 
369 
370 namespace field_traits
371 {
373 template <class ElemType, class NSet, class Dimension>
374 struct elem_type<field<ElemType, NSet, Dimension> > : ElemType {};
375 
377 template <class ElemType, class NSet, class Dimension>
378 struct nset_type<field<ElemType, NSet, Dimension> >
379 {
380  typedef NSet type;
381 };
382 
384 template <class ElemType, class NSet, class Dimension>
385 struct quantity_dimension<field<ElemType, NSet, Dimension> > : Dimension {};
386 } // end of namespace field_traits
387 
388 
394 template <class ElemType, class NSet, class Dimension>
395 class field_impl<field<ElemType, NSet, Dimension> >
396 {
397 public:
401  typedef ElemType elem_t;
403  typedef typename ElemType::xi_t xi_t;
405  typedef typename field_traits::dof_vector_type<Derived>::type dofs_t;
408 
409  typedef typename field_traits::eval_return_type<Derived>::type eval_return_t;
410 
415  field_impl(element_base<elem_t> const &elem, dofs_t const &dofs) :
416  m_elem(elem.derived()), m_dofs(dofs)
417  {
418  }
419 
420  eval_return_t eval(xi_t const &xi) const
421  {
422  return NSet::template eval_shape<0>(xi);
423  }
424 
426  elem_t const &get_elem() const
427  {
428  return m_elem;
429  }
430 
433  {
434  return m_dofs;
435  }
436 
437 protected:
442 };
443 
449 template <class ElemType, class NSet, class Dimension = field_dimension::_1d>
450 class field :
451  public field_base<field<ElemType, NSet, Dimension> >,
452  public field_impl<field<ElemType, NSet, Dimension> >
453 {
454 public:
456  typedef field type;
461 
463  typedef typename base_t::elem_t elem_t;
465  typedef typename base_t::dofs_t dofs_t;
466 
467  using impl_t::eval;
468  using impl_t::get_elem;
469  using impl_t::get_dofs;
470 
475  field(element_base<elem_t> const &elem, dofs_t const &dofs) :
476  impl_t(elem, dofs)
477  {
478  }
479 };
480 
482 template <class Elem, class Option, class Dimension = field_dimension::_1d>
483 field_view<Elem, Option, Dimension> const &
484 create_field_view(element_base<Elem> const & e, Option, Dimension dim = Dimension())
485 {
486  return static_cast<field_view<Elem, Option, Dimension> const &>(e.derived());
487 }
488 
489 
490 
491 
495 template <class Field>
497 
498 
499 namespace field_traits
500 {
501 template <class Field>
503 
504 template <class Field>
506 
507 template <class Field>
509 
510 template <class Field>
512  : shape_set_traits::shape_value_type<typename nset_type<directional_derivative_field<Field>>::type, 0> {};
513 
514 } // end of namespace field_traits
515 
516 
521 template <class Field>
523  public field_base<directional_derivative_field<Field>>
524 {
525 public:
528 
531 
533  typedef typename crtp_base_t::nset_t nset_t;
535  typedef typename crtp_base_t::elem_t elem_t;
537  typedef typename crtp_base_t::xi_t xi_t;
539  typedef typename crtp_base_t::x_t x_t;
543  typedef typename crtp_base_t::eval_return_t eval_return_t;
544 
550  template <class Direction>
551  directional_derivative_field(Field const &field, Eigen::MatrixBase<Direction> const &direction)
552  : m_field(field)
553  , m_direction(direction.derived())
554  {
555  }
556 
561  eval_return_t eval(xi_t const &xi) const
562  {
563  auto dx = get_elem().get_dx(xi);
564  double dx_xi = dx.col(0).norm(); // dx / dxi
565  double dx_eta = dx.col(1).norm(); // dx / deta
566  x_t s = dx.col(0).normalized(); // tangential unit vector
567  x_t t_eta = dx.col(1).normalized();
568  x_t n = s.cross(t_eta).normalized(); // unit normal
569  x_t t = n.cross(s); // second tangential unit vector
570 
571  x_t const &m = m_direction;
572  double a = (s.dot(m) - s.dot(t_eta) / t.dot(t_eta) * t.dot(m)) / dx_xi;
573  double b = t.dot(m) / t.dot(t_eta) / dx_eta;
574 
575  auto dN = nset_t::template eval_shape<1>(xi);
576  return a * dN.col(0) + b * dN.col(1);
577  }
578 
580  elem_t const &get_elem() const
581  {
582  return m_field.get_elem();
583  }
584 
587  {
588  return m_field.get_dofs();
589  }
590 
591 private:
592  Field const &m_field;
593  x_t const &m_direction;
594 };
595 
602 template <class Field, class Direction>
603 directional_derivative_field<Field>
604 directional_derivative(field_base<Field> const &field, Eigen::MatrixBase<Direction> const &direction)
605 {
606  return directional_derivative_field<Field>(field.derived(), direction);
607 }
608 
609 
611 template <class Elem, class Dimension = field_dimension::_1d>
612 field_view<Elem, field_option::constant, Dimension> const &
613 constant_view(element_base<Elem> const & e, Dimension dim = Dimension())
614 {
615  return create_field_view(e, field_option::constant(), dim);
616 }
617 
619 template <class Elem, class Dimension = field_dimension::_1d>
620 field_view<Elem, field_option::isoparametric, Dimension> const &
621 isoparametric_view(element_base<Elem> const & e, Dimension dim = Dimension())
622 {
624 }
625 
627 template <class Field>
628 dirac_field<Field> const &
630 {
631  return static_cast<dirac_field<Field> const &>(
632  static_cast<field_impl<Field> const &>(f.derived()));
633 }
634 
635 } // end of namespace NiHu
636 
637 #endif // NIHU_FIELD_HPP_INCLUDED
NiHu::field_base::elem_t
field_traits::elem_type< Derived >::type elem_t
the element type
Definition: field.hpp:120
NiHu::dirac_field::field_t
Field field_t
store the original field type for the iterator
Definition: field.hpp:211
NiHu::directional_derivative_field::nset_t
crtp_base_t::nset_t nset_t
the field shape set type
Definition: field.hpp:533
NiHu::field_impl< field< ElemType, NSet, Dimension > >::get_dofs
dofs_return_t get_dofs() const
Definition: field.hpp:432
NiHu::field_impl
implementation class of a general field
Definition: field.hpp:170
NiHu::field_option::constant
tag to describe a constant field
Definition: field.hpp:45
NiHu::field_impl< field< ElemType, NSet, Dimension > >::xi_t
ElemType::xi_t xi_t
the intrinsic location type
Definition: field.hpp:403
NiHu::field_traits::dof_vector_return_type
assign the DOF vector return type to the field type
Definition: field.hpp:94
NiHu::directional_derivative_field::dofs_return_t
crtp_base_t::dofs_return_t dofs_return_t
the return type for the dof vector
Definition: field.hpp:541
NiHu::field_impl< field< ElemType, NSet, Dimension > >::Derived
field< ElemType, NSet, Dimension > Derived
the derived field type
Definition: field.hpp:399
NiHu::directional_derivative_field::elem_t
crtp_base_t::elem_t elem_t
the element type
Definition: field.hpp:535
NiHu::corner_angle_computer
Definition: corner_angle.hpp:14
NiHu::field_impl< field_view< ElemType, field_option::constant, Dimension > >::get_elem
const ElemType & get_elem() const
return underlying element
Definition: field.hpp:317
NiHu::field_impl< field< ElemType, NSet, Dimension > >::get_elem
const elem_t & get_elem() const
return underlying element
Definition: field.hpp:426
NiHu::constant_view
const field_view< Elem, field_option::constant, Dimension > & constant_view(element_base< Elem > const &e, Dimension dim=Dimension())
constant field view factory
Definition: field.hpp:613
NiHu::field_traits::dof_vector_type
assign the DOF vector value type to the field type
Definition: field.hpp:83
NiHu::field_impl< field< ElemType, NSet, Dimension > >::field_impl
field_impl(element_base< elem_t > const &elem, dofs_t const &dofs)
constructor from element and dof vector
Definition: field.hpp:415
NiHu::field::impl_t
field_impl< field< ElemType, NSet, Dimension > > impl_t
the implementation class type
Definition: field.hpp:460
NiHu::field_traits::is_dof_vector_stored
indicate if the field stores its DOF vector or computes it on the fly
Definition: field.hpp:64
NiHu::dirac_field::type
dirac_field type
self-returning metafunction
Definition: field.hpp:203
NiHu::directional_derivative_field
field class that computes the directional derivative of a field
Definition: field.hpp:496
NiHu::field_view::type
field_view type
self-returning metafunction
Definition: field.hpp:348
NiHu::dirac_field::impl_t
field_impl< Field > impl_t
the implementation class type
Definition: field.hpp:206
NiHu::field_base::id
@ id
the field id
Definition: field.hpp:136
NiHu::field_traits::nset_type
assigns the N-set type to the field
Definition: field.hpp:56
NIHU_CRTP_HELPERS
#define NIHU_CRTP_HELPERS
define CRTP helper function
Definition: crtp_base.hpp:29
NiHu::field_option::isoparametric
tag to describe an isoparametric field
Definition: field.hpp:43
NiHu::field
field class that stores the dof vector and an element by value
Definition: field.hpp:367
NiHu::field_traits::id
assign a numeric ID to the field
Definition: field.hpp:72
NiHu::field_impl< field_view< ElemType, field_option::constant, Dimension > >::get_dofs
dofs_return_t get_dofs() const
return DOF vector
Definition: field.hpp:323
NiHu::field::field
field(element_base< elem_t > const &elem, dofs_t const &dofs)
constructor from element and dof vector
Definition: field.hpp:475
NiHu::directional_derivative
directional_derivative_field< Field > directional_derivative(field_base< Field > const &field, Eigen::MatrixBase< Direction > const &direction)
factory function to create a directional derivative field
Definition: field.hpp:604
NiHu::field::type
field type
self-returning metafunction
Definition: field.hpp:456
NiHu::isoparametric_view
const field_view< Elem, field_option::isoparametric, Dimension > & isoparametric_view(element_base< Elem > const &e, Dimension dim=Dimension())
isoparametric field view factory
Definition: field.hpp:621
NiHu::field_traits::quantity_dimension
assigns the dimensionality of the interpolated physical quantity
Definition: field.hpp:60
NiHu::directional_derivative_field::get_dofs
dofs_return_t get_dofs() const
return the dofs vector
Definition: field.hpp:586
NiHu::field_impl< field< ElemType, NSet, Dimension > >
the field class that stores the dof vector and the element by value
Definition: field.hpp:395
NiHu::field::elem_t
base_t::elem_t elem_t
the element type
Definition: field.hpp:463
NiHu::create_field_view
const field_view< Elem, Option, Dimension > & create_field_view(element_base< Elem > const &e, Option, Dimension dim=Dimension())
field view factory
Definition: field.hpp:484
NiHu::field_impl< field< ElemType, NSet, Dimension > >::dofs_t
field_traits::dof_vector_type< Derived >::type dofs_t
the dof vector type
Definition: field.hpp:405
NiHu::field_traits::elem_type
assigns the element type to the field
Definition: field.hpp:52
NiHu::constant_shape_set
Constant interpolation functions.
Definition: shapeset.hpp:290
NiHu::field_impl< field< ElemType, NSet, Dimension > >::elem_t
ElemType elem_t
the element type
Definition: field.hpp:401
NiHu::field_base::type
NIHU_CRTP_HELPERS typedef Derived type
self returning metafunction
Definition: field.hpp:117
NiHu::directional_derivative_field::eval_return_t
crtp_base_t::eval_return_t eval_return_t
the return type of the eval function
Definition: field.hpp:543
NiHu::field_impl< field< ElemType, NSet, Dimension > >::m_elem
elem_t m_elem
the element part by value
Definition: field.hpp:439
NiHu::field_base::get_dofs
dofs_return_t get_dofs() const
return DOF vector
Definition: field.hpp:155
NiHu::field_base::get_elem
const elem_t & get_elem() const
return underlying element
Definition: field.hpp:149
NiHu::field_base
CRTP base class of all fields.
Definition: field.hpp:111
NiHu::field_base::dofs_t
field_traits::dof_vector_type< Derived >::type dofs_t
the dofs vector type
Definition: field.hpp:128
NiHu::directional_derivative_field::crtp_base_t
field_base< directional_derivative_field< Field > > crtp_base_t
the crtp base type
Definition: field.hpp:530
NiHu::directional_derivative_field::directional_derivative_field
directional_derivative_field(Field const &field, Eigen::MatrixBase< Direction > const &direction)
contruct a directional derivative field instance
Definition: field.hpp:551
NiHu::field_impl< field< ElemType, NSet, Dimension > >::dofs_return_t
field_traits::dof_vector_return_type< Derived >::type dofs_return_t
the dof vector type
Definition: field.hpp:407
NiHu::field::base_t
field_base< field< ElemType, NSet, Dimension > > base_t
the CRTP base type
Definition: field.hpp:458
NiHu::field_base::x_t
elem_t::x_t x_t
the element location type
Definition: field.hpp:122
element.hpp
Declaration of element classes.
NiHu::directional_derivative_field::x_t
crtp_base_t::x_t x_t
the physical location type
Definition: field.hpp:539
NiHu::shape_set_traits::shape_return_type
Defines the return type of the shape function matrix.
Definition: shapeset.hpp:157
NiHu::field_view::elem_t
crtp_base_t::elem_t elem_t
the element type shorthand
Definition: field.hpp:351
NiHu::field_base::quantity_dimension
@ quantity_dimension
the quantity's dimensionality
Definition: field.hpp:138
NiHu::field_impl< field_view< ElemType, field_option::isoparametric, Dimension > >::get_dofs
dofs_return_t get_dofs() const
return DOF vector
Definition: field.hpp:280
NiHu::volume_element::xi_t
domain_t::xi_t xi_t
type of the shape functions' independent variable
Definition: element.hpp:210
NiHu::directional_derivative_field::type
directional_derivative_field type
self-returning metafunction
Definition: field.hpp:527
NiHu::dirac_field::elem_t
field_traits::elem_type< dirac_field< Field > >::type elem_t
shorthand for the element type
Definition: field.hpp:209
NiHu::field_view
Field automatically generated from an element using a field generation option.
Definition: field.hpp:222
NiHu::directional_derivative_field::xi_t
crtp_base_t::xi_t xi_t
the intrinsic location type
Definition: field.hpp:537
NiHu::field::dofs_t
base_t::dofs_t dofs_t
the dofs vector type
Definition: field.hpp:465
NiHu::shape_set_traits::shape_value_type
Defines the value type of the shape function matrix (and derivatives)
Definition: shapeset.hpp:138
NiHu::field_impl< field_view< ElemType, field_option::isoparametric, Dimension > >::get_elem
const ElemType & get_elem() const
return underlying element
Definition: field.hpp:274
NiHu::field_base::nset_t
field_traits::nset_type< Derived >::type nset_t
the nset type
Definition: field.hpp:126
NiHu::directional_derivative_field::get_elem
const elem_t & get_elem() const
return the element
Definition: field.hpp:580
NiHu::directional_derivative_field::eval
eval_return_t eval(xi_t const &xi) const
evaluate the directional derivative field
Definition: field.hpp:561
NiHu::dirac_field
dirac view of a field
Definition: field.hpp:175
NiHu::field_base::num_dofs
@ num_dofs
the number of dofs
Definition: field.hpp:140
NiHu::field_traits::eval_return_type
return type of the eval method
Definition: field.hpp:102
NiHu::element_base
The geometrical element representation.
Definition: element.hpp:194
NiHu::dirac
const dirac_field< Field > & dirac(field_base< Field > const &f)
dirac field view factory
Definition: field.hpp:629
NiHu::field_traits::is_dirac
indicate if the field is a Dirac field or not
Definition: field.hpp:68
NiHu::field_impl< field< ElemType, NSet, Dimension > >::m_dofs
dofs_t m_dofs
the dofs vector part by value
Definition: field.hpp:441
NiHu::field_base::xi_t
elem_t::xi_t xi_t
the intrinsic coordinate type
Definition: field.hpp:124
NiHu::field_base::dofs_return_t
field_traits::dof_vector_return_type< Derived >::type dofs_return_t
the dofs vector return type
Definition: field.hpp:130