3 #include <deal.II/base/tensor.h> 4 #include <deal.II/base/symmetric_tensor.h> 5 #include <deal.II/lac/vector.h> 6 #include <deal.II/base/geometry_info.h> 12 namespace GridRefinement {
15 template <
int dim,
typename real>
38 for(
unsigned int vertex = 0; vertex < dealii::GeometryInfo<dim>::vertices_per_cell; ++vertex){
41 for(
unsigned int i = 0; i < dim; ++i){
45 if(vertex>>i % 2 == 0){
48 chord_list[i] += vertices[vertex];
53 chord_list[i] -= vertices[vertex];
62 for(
unsigned int i = 0; i < dim; ++i)
63 chord_list[i] /= dealii::GeometryInfo<dim>::vertices_per_face;
72 template <
int dim,
typename real>
78 template <
int dim,
typename real>
85 template <
int dim,
typename real>
91 template <
int dim,
typename real>
93 const std::array<real,dim>& )
98 template <
int dim,
typename real>
101 std::array<real,dim> anisotropic_ratio;
103 for(
unsigned int j = 0; j < dim; ++j)
104 anisotropic_ratio[j] = get_anisotropic_ratio(j);
106 return anisotropic_ratio;
109 template <
int dim,
typename real>
116 template <
int dim,
typename real>
118 const std::array<dealii::Tensor<1,dim,real>,dim>& )
123 template <
int dim,
typename real>
126 std::array<dealii::Tensor<1,dim,real>,dim> unit_axis;
128 for(
unsigned int j = 0; j < dim; ++j)
129 unit_axis[j] = get_unit_axis(j);
134 template <
int dim,
typename real>
136 const unsigned int j)
139 dealii::Tensor<1,dim,real> u;
145 template <
int dim,
typename real>
147 const std::array<dealii::Tensor<1,dim,real>,dim>& )
152 template <
int dim,
typename real>
155 std::array<dealii::Tensor<1,dim,real>,dim> axis;
157 for(
unsigned int j = 0; j < dim; ++j)
158 axis[j] = get_axis(j);
163 template <
int dim,
typename real>
165 const unsigned int j)
167 return get_unit_axis(j) * get_scale();
170 template <
int dim,
typename real>
173 dealii::Tensor<2,dim,real> M;
174 for(
unsigned int i = 0; i < dim; ++i)
175 M[i] = m_scale * get_unit_axis(i);
180 template <
int dim,
typename real>
184 dealii::Tensor<2,dim,real> R;
185 for(
unsigned int i = 0; i < dim; ++i)
186 R[i] = get_unit_axis(i);
189 dealii::Tensor<2,dim,real> RT = transpose(R);
193 dealii::Tensor<2,dim,real> M;
194 for(
unsigned int i = 0; i < dim; ++i)
195 M[i] = (1.0/m_scale) * RT[i];
200 template <
int dim,
typename real>
210 for(
unsigned int i = 0; i < dim; ++i)
211 product *= chord_list[i].
norm();
214 m_scale = pow(product, -1.0/dim);
217 template <
int dim,
typename real>
219 const std::array<real,dim>& ,
220 const std::array<dealii::Tensor<1,dim,real>,dim>& ,
227 template <
int dim,
typename real>
238 template <
int dim,
typename real>
245 template <
int dim,
typename real>
251 template <
int dim,
typename real>
258 template <
int dim,
typename real>
264 template <
int dim,
typename real>
266 const std::array<real,dim>& ratio)
268 m_anisotropic_ratio = ratio;
273 template <
int dim,
typename real>
275 const unsigned int j)
277 return m_anisotropic_ratio[j];
280 template <
int dim,
typename real>
283 return m_anisotropic_ratio;
286 template <
int dim,
typename real>
288 const std::array<dealii::Tensor<1,dim,real>,dim>& unit_axis)
290 m_unit_axis = unit_axis;
295 template <
int dim,
typename real>
301 template <
int dim,
typename real>
305 return m_unit_axis[j];
308 template <
int dim,
typename real>
310 const std::array<dealii::Tensor<1,dim,real>,dim>& axis)
317 for(
unsigned int j = 0; j < dim; ++j)
318 m_anisotropic_ratio[j] = 1.0;
324 template <
int dim,
typename real>
328 return m_unit_axis[j] * m_anisotropic_ratio[j] * m_scale;
331 template <
int dim,
typename real>
334 std::array<dealii::Tensor<1,dim,real>,dim> axis;
336 for(
unsigned int j = 0; j < dim; ++j)
337 axis[j] = get_axis(j);
342 template <
int dim,
typename real>
345 dealii::Tensor<2,dim,real> M;
347 for(
unsigned int j = 0; j < dim; ++j)
348 M[j] = m_scale * m_anisotropic_ratio[j] * m_unit_axis[j];
353 template <
int dim,
typename real>
357 dealii::Tensor<2,dim,real> R;
358 for(
unsigned int i = 0; i < dim; ++i)
359 R[i] = get_unit_axis(i);
362 dealii::Tensor<2,dim,real> RT = transpose(R);
366 dealii::Tensor<2,dim,real> M;
367 for(
unsigned int i = 0; i < dim; ++i)
368 M[i] = (1.0)/(m_anisotropic_ratio[i]*m_scale) * RT[i];
373 template <
int dim,
typename real>
379 for(
unsigned int j = 0; j < dim; ++j){
381 m_anisotropic_ratio[j] = 1.0;
384 m_unit_axis[j] = dealii::Tensor<1,dim,real>();
385 m_unit_axis[j][j] = 1.0;
390 template <
int dim,
typename real>
394 correct_anisotropic_ratio();
397 template <
int dim,
typename real>
400 for(
unsigned int j = 0; j < dim; ++j){
402 real length = m_unit_axis[j].norm();
405 m_anisotropic_ratio[j] *= length;
406 m_unit_axis[j] /= length;
410 template <
int dim,
typename real>
415 for(
unsigned int j = 0; j < dim; ++j)
416 product *= m_anisotropic_ratio[j];
419 real alpha = pow(product, -1.0/dim);
422 for(
unsigned int j = 0; j < dim; ++j)
423 m_anisotropic_ratio[j] *= alpha;
429 sort_anisotropic_ratio();
432 template <
int dim,
typename real>
437 using anisopair = std::pair< real, dealii::Tensor<1,dim,real> >;
438 std::array<anisopair, dim > sort_array;
441 for(
unsigned int j = 0; j < dim; ++j)
442 sort_array[j] = std::make_pair(
443 m_anisotropic_ratio[j],
447 std::sort(sort_array.begin(), sort_array.end(), [](
451 return left.first > right.first;
455 for(
unsigned int j = 0; j < dim; ++j){
456 m_anisotropic_ratio[j] = sort_array[j].first;
457 m_unit_axis[j] = sort_array[j].second;
462 template <
int dim,
typename real>
474 m_unit_axis = chord_list;
480 template <
int dim,
typename real>
482 const std::array<real,dim>& derivative_value,
483 const std::array<dealii::Tensor<1,dim,real>,dim>& derivative_direction,
484 const unsigned int order)
497 for(
unsigned int i = 0; i < dim; ++i)
498 product *= derivative_value[i];
500 real denominator = pow(product, 1.0/dim);
503 std::array<real,dim> rho;
504 for(
unsigned int i = 0; i < dim; ++i)
505 rho[i] = derivative_value[i]/denominator;
514 std::array<real,dim> anisotropic_ratio;
515 for(
unsigned int i = 0; i < dim; ++i)
516 anisotropic_ratio[i] = pow(rho[i], -1.0/order);
524 m_anisotropic_ratio = anisotropic_ratio;
525 m_unit_axis = derivative_direction;
532 template <
int dim,
typename real>
534 const real anisotropic_ratio_min,
535 const real anisotropic_ratio_max)
538 bool changed =
false;
544 for(
unsigned int index = 0; index < dim; ++index){
548 if(m_anisotropic_ratio[j] > anisotropic_ratio_max){
550 assert(index != dim-1);
553 real factor = pow(m_anisotropic_ratio[j]/anisotropic_ratio_max, 1.0/(dim-1.0-index));
557 m_anisotropic_ratio[j] = anisotropic_ratio_max;
560 for(
unsigned int index_internal = index+1; index_internal < dim; ++index_internal){
563 int j_internal = index_internal;
566 m_anisotropic_ratio[j_internal] *= factor;
574 for(
unsigned int index = 0; index < dim; ++index){
579 if(m_anisotropic_ratio[j] < anisotropic_ratio_min){
581 assert(index != dim-1);
584 real factor = pow(m_anisotropic_ratio[j]/anisotropic_ratio_min, 1.0/(dim-1.0-index));
588 m_anisotropic_ratio[j] = anisotropic_ratio_min;
591 for(
unsigned int index_internal = index+1; index_internal < dim; ++index_internal){
594 int j_internal = dim-1-index_internal;
597 m_anisotropic_ratio[j_internal] *= factor;
606 correct_anisotropic_ratio();
612 template <
int dim,
typename real>
614 const dealii::Vector<real>& vec)
616 for(
unsigned int i = 0; i < this->size(); ++i)
617 this->set_scale(i, vec[i]);
620 template <
int dim,
typename real>
622 const std::vector<real>& vec)
624 for(
unsigned int i = 0; i < this->size(); ++i)
625 this->set_scale(i, vec[i]);
628 template <
int dim,
typename real>
631 dealii::Vector<real> vec(this->size());
633 for(
unsigned int i = 0; i < this->size(); ++i)
634 vec[i] = this->get_scale(i);
639 template <
int dim,
typename real>
642 std::vector<real> vec(this->size());
644 for(
unsigned int i = 0; i < this->size(); ++i)
645 vec[i] = this->get_scale(i);
650 template <
int dim,
typename real>
653 dealii::Vector<real> vec(this->size());
655 for(
unsigned int i = 0; i < this->size(); ++i){
657 std::array<real,dim> anisotropic_ratio = get_anisotropic_ratio(i);
660 vec[i] = *std::max_element(anisotropic_ratio.begin(), anisotropic_ratio.end());
666 template <
int dim,
typename real>
668 const std::vector<std::array<dealii::Tensor<1,dim,real>,dim>>& vec)
670 for(
unsigned int i = 0; i < this->size(); ++i)
671 this->set_axis(i, vec[i]);
674 template <
int dim,
typename real>
677 std::vector<std::array<dealii::Tensor<1,dim,real>,dim>> vec(this->size());
679 for(
unsigned int i = 0; i < this->size(); ++i)
680 vec[i] = this->get_axis(i);
685 template <
int dim,
typename real>
687 const unsigned int j)
689 std::vector<dealii::Tensor<1,dim,real>> vec(this->size());
691 for(
unsigned int i = 0; i < this->size(); ++i)
692 vec[i] = this->get_axis(i, j);
697 template <
int dim,
typename real>
700 std::vector<dealii::Tensor<2,dim,real>> vec(this->size());
702 for(
unsigned int i = 0; i < this->size(); ++i){
711 vec[i] = this->get_metric(i);
717 template <
int dim,
typename real>
720 std::vector<dealii::Tensor<2,dim,real>> vec(this->size());
722 for(
unsigned int i = 0; i < this->size(); ++i){
731 vec[i] = this->get_inverse_metric(i);
737 template <
int dim,
typename real>
739 const unsigned int index)
741 dealii::SymmetricTensor<2,dim,real> quadratic_metric;
742 dealii::Tensor<2,dim,real> metric = this->get_metric(index);
745 for(
unsigned int i = 0; i < dim; ++i){
746 for(
unsigned int j = i; j < dim; ++j){
748 quadratic_metric[i][j] = scalar_product(metric[i], metric[j]);
752 return quadratic_metric;
755 template <
int dim,
typename real>
758 std::vector<dealii::SymmetricTensor<2,dim,real>> vec(this->size());
760 for(
unsigned int i = 0; i < this->size(); ++i)
761 vec[i] = this->get_quadratic_metric(i);
766 template <
int dim,
typename real>
768 const unsigned int index)
770 dealii::SymmetricTensor<2,dim,real> inverse_quadratic_metric;
771 dealii::Tensor<2,dim,real> inverse_metric = this->get_inverse_metric(index);
786 inverse_metric = transpose(inverse_metric);
789 for(
unsigned int i = 0; i < dim; ++i){
790 for(
unsigned int j = i; j < dim; ++j){
792 inverse_quadratic_metric[i][j] = scalar_product(inverse_metric[i], inverse_metric[j]);
798 return inverse_quadratic_metric;
801 template <
int dim,
typename real>
804 std::vector<dealii::SymmetricTensor<2,dim,real>> vec(this->size());
806 for(
unsigned int i = 0; i < this->size(); ++i)
807 vec[i] = this->get_inverse_quadratic_metric(i);
814 template <
int dim,
typename real,
typename ElementType>
816 const unsigned int size)
821 template <
int dim,
typename real,
typename ElementType>
827 template <
int dim,
typename real,
typename ElementType>
829 const unsigned int index)
831 return field[index].scale();
834 template <
int dim,
typename real,
typename ElementType>
836 const unsigned int index,
839 field[index].set_scale(val);
842 template <
int dim,
typename real,
typename ElementType>
844 const unsigned int index)
const 846 return field[index].get_scale();
849 template <
int dim,
typename real,
typename ElementType>
851 const unsigned int index,
852 const std::array<real,dim>& ratio)
854 field[index].set_anisotropic_ratio(ratio);
857 template <
int dim,
typename real,
typename ElementType>
859 const unsigned int index)
861 return field[index].get_anisotropic_ratio();
864 template <
int dim,
typename real,
typename ElementType>
866 const unsigned int index,
867 const unsigned int j)
869 return field[index].get_anisotropic_ratio(j);
872 template <
int dim,
typename real,
typename ElementType>
874 const unsigned int index,
875 const std::array<dealii::Tensor<1,dim,real>,dim>& unit_axis)
877 field[index].set_unit_axis(unit_axis);
880 template <
int dim,
typename real,
typename ElementType>
882 const unsigned int index)
884 return field[index].get_unit_axis();
888 template <
int dim,
typename real,
typename ElementType>
890 const unsigned int index,
891 const unsigned int j)
893 return field[index].get_unit_axis(j);
896 template <
int dim,
typename real,
typename ElementType>
898 const unsigned int index,
899 const std::array<dealii::Tensor<1,dim,real>,dim>& axis)
901 field[index].set_axis(axis);
904 template <
int dim,
typename real,
typename ElementType>
906 const unsigned int index)
908 return field[index].get_axis();
911 template <
int dim,
typename real,
typename ElementType>
913 const unsigned int index,
914 const unsigned int j)
916 return field[index].get_axis(j);
919 template <
int dim,
typename real,
typename ElementType>
921 const unsigned int index)
923 return field[index].get_metric();
926 template <
int dim,
typename real,
typename ElementType>
928 const unsigned int index)
930 return field[index].get_inverse_metric();
933 template <
int dim,
typename real,
typename ElementType>
935 const dealii::DoFHandler<dim>& dof_handler,
936 const std::vector<std::array<real,dim>>& derivative_value,
937 const std::vector<std::array<dealii::Tensor<1,dim,real>,dim>>& derivative_direction,
938 const int relative_order)
941 assert(size() == dof_handler.get_triangulation().n_active_cells());
942 assert(size() == derivative_value.size());
943 assert(size() == derivative_direction.size());
946 for(
auto cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell){
947 if(!cell->is_locally_owned())
continue;
950 const unsigned int index = cell->active_cell_index();
953 const unsigned int order = cell->active_fe_index() + relative_order;
956 field[index].set_anisotropy(
957 derivative_value[index],
958 derivative_direction[index],
964 template <
int dim,
typename real,
typename ElementType>
966 const real anisotropic_ratio_min,
967 const real anisotropic_ratio_max)
970 for(
unsigned int index = 0; index < this->size(); ++index)
971 field[index].apply_anisotropic_limit(
972 anisotropic_ratio_min,
973 anisotropic_ratio_max);
977 template <
int dim,
typename real,
typename ElementType>
979 std::ostream& os)
const 981 for(
unsigned int index = 0; index < this->size(); ++index){
984 os << field[index] << std::endl;
dealii::Tensor< 2, dim, real > get_metric() override
get metric value at index
real get_scale(const unsigned int index) const override
Gets scale for the specified element index.
void set_anisotropic_ratio(const unsigned int index, const std::array< real, dim > &ratio) override
Sets anisotropic ratio for the specified element index (if anisotropic)
std::array< dealii::Tensor< 1, dim, real >, dim > get_axis(const unsigned int index) override
Gets the frame (dim scaled axis vectors) for the specified element index.
dealii::SymmetricTensor< 2, dim, real > get_inverse_quadratic_metric(const unsigned int index)
Gets the inverse quadratic Riemannian metric used with BAMG, , for a specified element index...
void set_unit_axis(const std::array< dealii::Tensor< 1, dim, real >, dim > &unit_axis) override
setting the (unit) axis direction
void set_scale(const real val) override
Set the scale for the element.
std::array< dealii::Tensor< 1, dim, real >, dim > get_axis() override
getting frame axis j (scaled) at index (array)
void set_unit_axis(const std::array< dealii::Tensor< 1, dim, real >, dim > &unit_axis) override
Set the unit axes of the element.
dealii::Tensor< 2, dim, real > get_inverse_metric() override
Get inverse metric matrix for the reference element.
std::vector< std::array< dealii::Tensor< 1, dim, real >, dim > > get_axis_vector()
Gets the frame (dim scaled axis vectors) for each element (std::vector)
void set_scale(const unsigned int index, const real val) override
Sets scale for the specified element index.
void correct_anisotropic_ratio()
Correct the anisotropic ratio values.
Files for the baseline physics.
std::vector< dealii::SymmetricTensor< 2, dim, real > > get_quadratic_metric_vector()
Gets the quadratic Riemannian metric, , for each element (std::vector)
dealii::Vector< real > get_scale_vector_dealii() const
Gets scale for all elements from a scale vector (dealii::Vector)
void set_axis_vector(const std::vector< std::array< dealii::Tensor< 1, dim, real >, dim >> &vec)
Sets the frame (dim scaled axis vectors) for each element (std::vector)
real get_scale() const override
Get the scale for the element.
std::array< real, dim > get_anisotropic_ratio() override
Get the anisotropic ratio of each reference axis as an array.
void set_axis(const std::array< dealii::Tensor< 1, dim, real >, dim > &axis) override
setting frame axis j (scaled) at index
void set_anisotropic_ratio(const std::array< real, dim > &ratio) override
Set the anisotropic ratio for each reference axis.
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.
dealii::Tensor< 2, dim, real > get_metric(const unsigned int index) override
Gets the anisotropic metric tensor, , for the specified element index.
void clear()
resets the element
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) override
Set anisotropy from reconstructed directional derivatives.
std::array< dealii::Tensor< 1, dim, real >, dim > get_axis() override
Get the array of axes of the local frame field .
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) override
Set anisotropy from reconstructed directional derivatives.
void set_scale_vector(const std::vector< real > &vec)
Sets scale for all elements from a scale vector(std::vector)
real & scale() override
Reference for element size.
unsigned int size() const
returns the internal vector size
void set_unit_axis(const unsigned int index, const std::array< dealii::Tensor< 1, dim, real >, dim > &unit_axis) override
Sets the group of dim (unit) axis directions for the specified element index.
void set_axis(const std::array< dealii::Tensor< 1, dim, real >, dim > &axis) override
Set the scaled local frame axes based on vector set (length and direction)
std::array< dealii::Tensor< 1, dim, real >, dim > get_unit_axis() override
getting the (unit) axis direction (array)
std::vector< dealii::Tensor< 2, dim, real > > get_metric_vector()
Gets the anisotropic metric tensor, , for each element (std::vector)
void set_anisotropy(const dealii::DoFHandler< dim > &dof_handler, const std::vector< std::array< real, dim >> &derivative_value, const std::vector< std::array< dealii::Tensor< 1, dim, real >, dim >> &derivative_direction, const int relative_order) override
Compute anisotropic ratio from directional derivatives.
void apply_anisotropic_limit(const real anisotropic_ratio_min, const real anisotropic_ratio_max)
Limits the anisotropic ratios to a given bandwidth.
void sort_anisotropic_ratio()
Sorts the anisotropic ratio values (and corresponding unit axis) in ascending order.
void apply_anisotropic_limit(const real anisotropic_ratio_min, const real anisotropic_ratio_max) override
Globally limit anisotropic ratio to a specified range.
void correct_element()
Corrects internal values to ensure consistent treatement.
void set_cell_internal(const typename Element< dim, real >::VertexList &vertices) override
Set element to match geometry of input vertex set.
void apply_anisotropic_limit(const real anisotropic_ratio_min, const real anisotropic_ratio_max)
Limits the anisotropic ratios to a given bandwidth.
ChordList get_chord_list(const VertexList &vertices)
Get the chord list from an input set of vertices.
std::array< real, dim > get_anisotropic_ratio(const unsigned int index) override
Gets the anisotropic ratio for the specified element index.
std::array< dealii::Tensor< 1, dim, real >, dealii::GeometryInfo< dim >::vertices_per_cell > VertexList
Type alias for array of vertex coordinates for element.
ElementAnisotropic()
Constructor, sets default element definition.
std::vector< dealii::SymmetricTensor< 2, dim, real > > get_inverse_quadratic_metric_vector()
Gets the inverse quadratic Riemannian metric used with BAMG, , for each element (std::vector) ...
real get_scale() const override
Get the scale for the element.
void set_anisotropic_ratio(const std::array< real, dim > &ratio) override
Set the anisotropic ratio for each reference axis.
dealii::Tensor< 2, dim, real > get_metric() override
Get metric matrix at point describing mapping from reference element.
real & scale() override
Reference for element size.
void set_cell_internal(const typename Element< dim, real >::VertexList &vertices) override
Set element to match geometry of input vertex set.
void set_axis(const unsigned int index, const std::array< dealii::Tensor< 1, dim, real >, dim > &axis) override
Sets the j^th (unit) axis direction for the specified element index.
Internal Field element class.
dealii::Vector< real > get_max_anisotropic_ratio_vector_dealii()
Gets the vector of largest anisotropic ratio for each element (dealii::Vector)
dealii::Tensor< 2, dim, real > get_inverse_metric(const unsigned int index) override
Gets the inverse metric tensor, , for the specified element index.
real1 norm(const dealii::Tensor< 1, dim, real1 > x)
Returns norm of dealii::Tensor<1,dim,real>
std::array< dealii::Tensor< 1, dim, real >, dim > get_unit_axis() override
Get unit axis directions as an array.
std::array< dealii::Tensor< 1, dim, real >, dim > get_unit_axis(const unsigned int index) override
Sets the group of dim (unit) axis directions for the specified element index.
std::vector< real > get_scale_vector() const
Gets scale fpr all elements from a scale vector (std::vector)
void set_scale(const real val) override
Set the scale for the element.
void reinit(const unsigned int size)
reinitialize the internal data structure
std::ostream & serialize(std::ostream &os) const override
Performs internal call for writing the field description to an ostream.
void set_scale_vector_dealii(const dealii::Vector< real > &vec)
Sets scale for all elements from a scale vector (dealii::Vector)
dealii::Tensor< 2, dim, real > get_inverse_metric() override
get inverse metric value
void correct_unit_axis()
renormalize the unit_axis
std::vector< dealii::Tensor< 2, dim, real > > get_inverse_metric_vector()
Gets the inverse metric tensor, , for each element (std::vector)
real & scale(const unsigned int index) override
reference for element size of specified element index
std::array< real, dim > get_anisotropic_ratio() override
Get the anisotropic ratio of each reference axis as an array.
dealii::SymmetricTensor< 2, dim, real > get_quadratic_metric(const unsigned int index)
Gets the quadratic Riemannian metric, , for the specified element index.