[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
field.h
1 #ifndef __FIELD_H__
2 #define __FIELD_H__
3 
4 #include <ostream>
5 
6 #include <deal.II/base/tensor.h>
7 #include <deal.II/base/symmetric_tensor.h>
8 #include <deal.II/lac/vector.h>
9 #include <deal.II/base/geometry_info.h>
10 #include <deal.II/hp/dof_handler.h>
11 
12 namespace PHiLiP {
13 
14 namespace GridRefinement {
15 
17 
22 template <int dim, typename real>
23 class Element
24 {
25 public:
27  virtual ~Element() = default;
29 
32  virtual real& scale() = 0;
33 
35  virtual void set_scale(
36  const real val) = 0;
37 
39  virtual real get_scale() const = 0;
40 
42 
46  virtual void set_anisotropic_ratio(
47  const std::array<real,dim>& ratio) = 0;
48 
50 
52  virtual std::array<real,dim> get_anisotropic_ratio() = 0;
53 
55 
57  virtual real get_anisotropic_ratio(
58  const unsigned int j) = 0;
59 
61 
65  virtual void set_unit_axis(
66  const std::array<dealii::Tensor<1,dim,real>,dim>& unit_axis) = 0;
67 
69  virtual std::array<dealii::Tensor<1,dim,real>,dim> get_unit_axis() = 0;
70 
72  virtual dealii::Tensor<1,dim,real> get_unit_axis(
73  const unsigned int j) = 0;
74 
76 
79  virtual void set_axis(
80  const std::array<dealii::Tensor<1,dim,real>,dim>& axis) = 0;
81 
83  virtual std::array<dealii::Tensor<1,dim,real>,dim> get_axis() = 0;
84 
86  virtual dealii::Tensor<1,dim,real> get_axis(
87  const unsigned int j) = 0;
88 
90 
93  virtual dealii::Tensor<2,dim,real> get_metric() = 0;
94 
96 
98  virtual dealii::Tensor<2,dim,real> get_inverse_metric() = 0;
99 
101  using VertexList = std::array<dealii::Tensor<1,dim,real>, dealii::GeometryInfo<dim>::vertices_per_cell>;
103  using ChordList = std::array<dealii::Tensor<1,dim,real>, dim>;
104 
105 protected:
108  const VertexList& vertices);
109 
111 
114  virtual void set_cell_internal(
115  const VertexList& vertices) = 0;
116 
117 public:
118 
120 
122  template <typename DoFCellAccessorType>
123  void set_cell(
124  const DoFCellAccessorType& cell)
125  {
126  VertexList vertices;
127 
128  for(unsigned int vertex = 0; vertex < dealii::GeometryInfo<dim>::vertices_per_cell; ++vertex)
129  vertices[vertex] = cell->vertex(vertex);
130 
131  set_cell_internal(vertices);
132  }
133 
135 
138  virtual void set_anisotropy(
139  const std::array<real,dim>& derivative_value,
140  const std::array<dealii::Tensor<1,dim,real>,dim>& derivative_direction,
141  const unsigned int order) = 0;
142 
144 
148  virtual void apply_anisotropic_limit(
149  const real anisotropic_ratio_min,
150  const real anisotropic_ratio_max) = 0;
151 
152 };
153 
155 
160 template <int dim, typename real>
161 class ElementIsotropic : public Element<dim,real>
162 {
163 public:
165 
168  real& scale() override;
169 
171  void set_scale(
172  const real val) override;
173 
175  real get_scale() const override;
176 
178 
183  const std::array<real,dim>& ratio) override;
184 
186 
188  std::array<real,dim> get_anisotropic_ratio() override;
189 
191 
194  const unsigned int j) override;
195 
197 
201  void set_unit_axis(
202  const std::array<dealii::Tensor<1,dim,real>,dim>& unit_axis) override;
203 
205  std::array<dealii::Tensor<1,dim,real>,dim> get_unit_axis() override;
206 
208  dealii::Tensor<1,dim,real> get_unit_axis(
209  const unsigned int j) override;
210 
212 
215  void set_axis(
216  const std::array<dealii::Tensor<1,dim,real>,dim>& axis) override;
217 
219  std::array<dealii::Tensor<1,dim,real>,dim> get_axis() override;
220 
222  dealii::Tensor<1,dim,real> get_axis(
223  const unsigned int j) override;
224 
226 
229  dealii::Tensor<2,dim,real> get_metric() override;
230 
232 
234  dealii::Tensor<2,dim,real> get_inverse_metric() override;
235 
236 protected:
238 
241  void set_cell_internal(
242  const typename Element<dim,real>::VertexList& vertices) override;
243 
244 public:
246 
249  void set_anisotropy(
250  const std::array<real,dim>& derivative_value,
251  const std::array<dealii::Tensor<1,dim,real>,dim>& derivative_direction,
252  const unsigned int order) override;
253 
255 
260  const real anisotropic_ratio_min,
261  const real anisotropic_ratio_max);
262 
264 
266  friend std::ostream& operator<<(
267  std::ostream& os,
268  const ElementIsotropic<dim,real>& element)
269  {
270  os << "Isotropic element with properties:" << std::endl
271  << '\t' << "m_scale = " << element.m_scale << std::endl;
272 
273  return os;
274  }
275 
276 private:
278  real m_scale;
279 };
280 
282 
286 template <int dim, typename real>
287 class ElementAnisotropic : public Element<dim,real>
288 {
289 public:
291 
295 
297 
300  real& scale() override;
301 
303  void set_scale(
304  const real val) override;
305 
307  real get_scale() const override;
308 
310 
315  const std::array<real,dim>& ratio) override;
316 
318 
320  std::array<real,dim> get_anisotropic_ratio() override;
321 
323 
326  const unsigned int j) override;
327 
329  void set_unit_axis(
330  const std::array<dealii::Tensor<1,dim,real>,dim>& unit_axis) override;
331 
333  std::array<dealii::Tensor<1,dim,real>,dim> get_unit_axis() override;
334 
336  dealii::Tensor<1,dim,real> get_unit_axis(
337  const unsigned int j) override;
338 
340  void set_axis(
341  const std::array<dealii::Tensor<1,dim,real>,dim>& axis) override;
342 
344  std::array<dealii::Tensor<1,dim,real>,dim> get_axis() override;
345 
347  dealii::Tensor<1,dim,real> get_axis(
348  const unsigned int j) override;
349 
351  dealii::Tensor<2,dim,real> get_metric() override;
352 
354  dealii::Tensor<2,dim,real> get_inverse_metric() override;
355 
356 protected:
358 
361  void set_cell_internal(
362  const typename Element<dim,real>::VertexList& vertices) override;
363 
364 public:
366 
369  void set_anisotropy(
370  const std::array<real,dim>& derivative_value,
371  const std::array<dealii::Tensor<1,dim,real>,dim>& derivative_direction,
372  const unsigned int order) override;
373 
375 
380  const real anisotropic_ratio_min,
381  const real anisotropic_ratio_max);
382 
384 
386  friend std::ostream& operator<<(
387  std::ostream& os,
388  const ElementAnisotropic<dim,real>& element)
389  {
390  os << "Anisotropic element with properties:" << std::endl
391  << '\t' << "m_scale = " << element.m_scale << std::endl
392  << '\t' << "m_anisotropic_ratio = {" << element.m_anisotropic_ratio[0];
393 
394  for(unsigned int i = 1; i < dim; ++i)
395  os << ", " << element.m_anisotropic_ratio[i];
396 
397  os << "}" << std::endl
398  << '\t' << "m_unit_axis = {" << element.m_unit_axis[0];
399 
400  for(unsigned int i = 1; i < dim; ++i)
401  os << ", " << element.m_unit_axis[i];
402 
403  os << "}" << std::endl;
404 
405  return os;
406  }
407 
408 private:
409 
411  void clear();
412 
414 
417  void correct_element();
418 
420 
423  void correct_unit_axis();
424 
426 
428  void correct_anisotropic_ratio();
429 
431  void sort_anisotropic_ratio();
432 
434  real m_scale;
435 
437  std::array<real, dim> m_anisotropic_ratio;
438 
440  std::array<dealii::Tensor<1,dim,real>, dim> m_unit_axis;
441 };
442 
444 
451 template <int dim, typename real>
452 class Field
453 {
454 public:
456  virtual ~Field() = default;
457 
459  virtual void reinit(
460  const unsigned int size) = 0;
461 
463  virtual unsigned int size() const = 0;
464 
466  virtual real& scale(
467  const unsigned int index) = 0;
468 
470  virtual void set_scale(
471  const unsigned int index,
472  const real val) = 0;
473 
475  virtual real get_scale(
476  const unsigned int index) const = 0;
477 
479  void set_scale_vector_dealii(
480  const dealii::Vector<real>& vec);
481 
483  void set_scale_vector(
484  const std::vector<real>& vec);
485 
487  dealii::Vector<real> get_scale_vector_dealii() const;
488 
490  std::vector<real> get_scale_vector() const;
491 
493  virtual void set_anisotropic_ratio(
494  const unsigned int index,
495  const std::array<real,dim>& ratio) = 0;
496 
498  virtual std::array<real,dim> get_anisotropic_ratio(
499  const unsigned int index) = 0;
500 
502  virtual real get_anisotropic_ratio(
503  const unsigned int index,
504  const unsigned int j) = 0;
505 
507  dealii::Vector<real> get_max_anisotropic_ratio_vector_dealii();
508 
510  virtual void set_unit_axis(
511  const unsigned int index,
512  const std::array<dealii::Tensor<1,dim,real>,dim>& unit_axis) = 0;
513 
515  virtual std::array<dealii::Tensor<1,dim,real>,dim> get_unit_axis(
516  const unsigned int index) = 0;
517 
519  virtual dealii::Tensor<1,dim,real> get_unit_axis(
520  const unsigned int index,
521  const unsigned int j) = 0;
522 
524  virtual void set_axis(
525  const unsigned int index,
526  const std::array<dealii::Tensor<1,dim,real>,dim>& axis) = 0;
527 
529  virtual std::array<dealii::Tensor<1,dim,real>,dim> get_axis(
530  const unsigned int index) = 0;
531 
533  virtual dealii::Tensor<1,dim,real> get_axis(
534  const unsigned int index,
535  const unsigned int j) = 0;
536 
538  void set_axis_vector(
539  const std::vector<std::array<dealii::Tensor<1,dim,real>,dim>>& vec);
540 
542  std::vector<std::array<dealii::Tensor<1,dim,real>,dim>> get_axis_vector();
543 
545  std::vector<dealii::Tensor<1,dim,real>> get_axis_vector(
546  const unsigned int j);
547 
549  virtual dealii::Tensor<2,dim,real> get_metric(
550  const unsigned int index) = 0;
551 
553  std::vector<dealii::Tensor<2,dim,real>> get_metric_vector();
554 
556  virtual dealii::Tensor<2,dim,real> get_inverse_metric(
557  const unsigned int index) = 0;
558 
560  std::vector<dealii::Tensor<2,dim,real>> get_inverse_metric_vector();
561 
563  dealii::SymmetricTensor<2,dim,real> get_quadratic_metric(
564  const unsigned int index);
565 
567  std::vector<dealii::SymmetricTensor<2,dim,real>> get_quadratic_metric_vector();
568 
570  dealii::SymmetricTensor<2,dim,real> get_inverse_quadratic_metric(
571  const unsigned int index);
572 
574  std::vector<dealii::SymmetricTensor<2,dim,real>> get_inverse_quadratic_metric_vector();
575 
577  using DoFHandlerType = dealii::DoFHandler<dim>;
578 
580  virtual void set_cell(
581  const DoFHandlerType& dof_handler) = 0;
582 
584 
587  virtual void set_anisotropy(
588  const dealii::DoFHandler<dim>& dof_handler,
589  const std::vector<std::array<real,dim>>& derivative_value,
590  const std::vector<std::array<dealii::Tensor<1,dim,real>,dim>>& derivative_direction,
591  const int relative_order) = 0;
592 
594  virtual void apply_anisotropic_limit(
595  const real anisotropic_ratio_min,
596  const real anisotropic_ratio_max) = 0;
597 
599  virtual std::ostream& serialize(
600  std::ostream& os) const = 0;
601 
603  friend std::ostream& operator<<(
604  std::ostream& os,
605  const Field<dim,real>& field)
606  {
607  return field.serialize(os);
608  }
609 
610 };
611 
613 
618 template <int dim, typename real, typename ElementType>
619 class FieldInternal : public Field<dim,real>
620 {
621 public:
623 
624  void reinit(
625  const unsigned int size);
626 
628  unsigned int size() const;
629 
631  real& scale(
632  const unsigned int index) override;
633 
635  void set_scale(
636  const unsigned int index,
637  const real val) override;
638 
640  real get_scale(
641  const unsigned int index) const override;
642 
645  const unsigned int index,
646  const std::array<real,dim>& ratio) override;
647 
649  std::array<real,dim> get_anisotropic_ratio(
650  const unsigned int index) override;
651 
654  const unsigned int index,
655  const unsigned int j) override;
656 
658  void set_unit_axis(
659  const unsigned int index,
660  const std::array<dealii::Tensor<1,dim,real>,dim>& unit_axis) override;
661 
663  std::array<dealii::Tensor<1,dim,real>,dim> get_unit_axis(
664  const unsigned int index) override;
665 
667  dealii::Tensor<1,dim,real> get_unit_axis(
668  const unsigned int index,
669  const unsigned int j) override;
670 
672  void set_axis(
673  const unsigned int index,
674  const std::array<dealii::Tensor<1,dim,real>,dim>& axis) override;
675 
677  std::array<dealii::Tensor<1,dim,real>,dim> get_axis(
678  const unsigned int index) override;
679 
681  dealii::Tensor<1,dim,real> get_axis(
682  const unsigned int index,
683  const unsigned int j) override;
684 
685  // Gets the anisotropic metric tensor, \f$M\f$, for the specified element index
686  dealii::Tensor<2,dim,real> get_metric(
687  const unsigned int index) override;
688 
689  // Gets the inverse metric tensor, \f$M^{-1}\f$, for the specified element index
690  dealii::Tensor<2,dim,real> get_inverse_metric(
691  const unsigned int index) override;
692 
693  // Assigns the existing field based on an input DoFHandlerType
694  void set_cell(
695  const typename Field<dim,real>::DoFHandlerType& dof_handler) override
696  {
697  reinit(dof_handler.get_triangulation().n_active_cells());
698 
699  for(auto cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell)
700  if(cell->is_locally_owned())
701  field[cell->active_cell_index()].set_cell(cell);
702  }
703 
705 
708  void set_anisotropy(
709  const dealii::DoFHandler<dim>& dof_handler,
710  const std::vector<std::array<real,dim>>& derivative_value,
711  const std::vector<std::array<dealii::Tensor<1,dim,real>,dim>>& derivative_direction,
712  const int relative_order) override;
713 
716  const real anisotropic_ratio_min,
717  const real anisotropic_ratio_max) override;
718 
720  std::ostream& serialize(
721  std::ostream& os) const override;
722 
723 private:
725  std::vector<ElementType> field;
726 };
727 
729 
731 template <int dim, typename real>
733 
735 
738 template <int dim, typename real>
740 
741 } // namespace GridRefinement
742 
743 } // namespace PHiLiP
744 
745 #endif //__FIELD_H__
Isotropic element class.
Definition: field.h:161
virtual void set_cell_internal(const VertexList &vertices)=0
Set element to match geometry of input vertex set.
virtual void apply_anisotropic_limit(const real anisotropic_ratio_min, const real anisotropic_ratio_max)=0
Limits the anisotropic ratios to a given bandwidth.
std::array< real, dim > m_anisotropic_ratio
Anisotropic axis ratios (relative to element scale)
Definition: field.h:437
virtual std::array< dealii::Tensor< 1, dim, real >, dim > get_unit_axis()=0
Get unit axis directions as an array.
friend std::ostream & operator<<(std::ostream &os, const ElementIsotropic< dim, real > &element)
Write properties of element to ostream.
Definition: field.h:266
virtual void set_axis(const std::array< dealii::Tensor< 1, dim, real >, dim > &axis)=0
Set the scaled local frame axes based on vector set (length and direction)
virtual std::array< dealii::Tensor< 1, dim, real >, dim > get_axis()=0
Get the array of axes of the local frame field .
Files for the baseline physics.
Definition: ADTypes.hpp:10
Anisotropic element class.
Definition: field.h:287
std::array< dealii::Tensor< 1, dim, real >, dim > m_unit_axis
axis unit vector directions
Definition: field.h:440
virtual ~Element()=default
Destructor.
std::array< dealii::Tensor< 1, dim, real >, dim > ChordList
Type alias for array of chord veectors (face center to face center) in Deal.II ordering.
Definition: field.h:103
virtual void set_unit_axis(const std::array< dealii::Tensor< 1, dim, real >, dim > &unit_axis)=0
Set the unit axes of the element.
void set_cell(const DoFCellAccessorType &cell)
Set the Element based on the input cell (from current mesh)
Definition: field.h:123
virtual void set_scale(const real val)=0
Set the scale for the element.
virtual dealii::Tensor< 2, dim, real > get_metric()=0
Get metric matrix at point describing mapping from reference element.
Field element class.
Definition: field.h:452
dealii::DoFHandler< dim > DoFHandlerType
Associated DofHandler type.
Definition: field.h:577
ChordList get_chord_list(const VertexList &vertices)
Get the chord list from an input set of vertices.
Definition: field.cpp:16
std::array< dealii::Tensor< 1, dim, real >, dealii::GeometryInfo< dim >::vertices_per_cell > VertexList
Type alias for array of vertex coordinates for element.
Definition: field.h:101
std::vector< ElementType > field
Internal vector storage of element data for each index.
Definition: field.h:725
virtual real get_scale() const =0
Get the scale for the element.
virtual real & scale()=0
Reference for element size.
virtual dealii::Tensor< 2, dim, real > get_inverse_metric()=0
. Get inverse metric matrix for the reference element
Internal Field element class.
Definition: field.h:619
virtual void set_anisotropy(const std::array< real, dim > &derivative_value, const std::array< dealii::Tensor< 1, dim, real >, dim > &derivative_direction, const unsigned int order)=0
Set anisotropy from reconstructed directional derivatives.
virtual std::array< real, dim > get_anisotropic_ratio()=0
Get the anisotropic ratio of each reference axis as an array.
virtual std::ostream & serialize(std::ostream &os) const =0
Performs internal call for writing the field description to an ostream.
real m_scale
element size based on
Definition: field.h:434
friend std::ostream & operator<<(std::ostream &os, const ElementAnisotropic< dim, real > &element)
Write properties of element to ostream.
Definition: field.h:386
virtual void set_anisotropic_ratio(const std::array< real, dim > &ratio)=0
Set the anisotropic ratio for each reference axis.
friend std::ostream & operator<<(std::ostream &os, const Field< dim, real > &field)
Performs output to ostream using internal serialization.
Definition: field.h:603