Tatooine
curve_to_streamline.h
Go to the documentation of this file.
1#ifndef TATOOINE_CURVE_TO_STREAMLINE_H
2#define TATOOINE_CURVE_TO_STREAMLINE_H
3
4#include <tatooine/field.h>
5
6//==============================================================================
7namespace tatooine {
8//==============================================================================
9
10template <typename Real>
12 //============================================================================
16
17 //============================================================================
18 std::vector<mat32> bases;
19 std::vector<vec2> grad_alpha;
20 std::vector<vec3> tangents;
21
22 //============================================================================
23 template <typename V, typename Line>
24 auto operator()(const field<V, Real, 3, 3>& v, Real t0, Line line,
25 Real initial_stepsize, Real delta, size_t num_its) {
26 bases.resize(line.size());
27 grad_alpha.resize(line.size());
28 tangents.resize(line.size());
29
30 Real cur_stepsize = initial_stepsize;
31 for (unsigned int i = 0; i < num_its; i++) {
36 step(line, cur_stepsize);
37 cur_stepsize *= delta;
38 }
39 return line;
40 }
41
42 //---------------------------------------------------------------------------
43 template <typename Line>
44 void step(Line& line, Real stepsize) {
45 for (size_t i = 0; i < line.size(); i++) {
46 auto refinement_dir = bases[i] * grad_alpha[i] * stepsize;
47 line.vertex_at(i) -= refinement_dir;
48 }
49 }
50
51 //----------------------------------------------------------------------------
52 template <typename Line>
53 void calc_tangents(const Line& line) {
54 for (unsigned int i = 0; i < line.size(); i++) {
55 tangents[i] = line.tangent(i);
56 }
57 }
58
59 //------------------------------------------------------------------------------
61 for (size_t i = 0; i < tangents.size(); i++) {
62 const auto& t = tangents[i];
63 vec3 aux_vec{1, 0, 0};
64 auto tn = normalize(t);
65 if (approx_equal(aux_vec, tn, 1e-10)) { aux_vec = {0, 1, 0}; }
66 if (approx_equal(aux_vec, tn, 1e-10)) { aux_vec = {0, 0, 1}; }
67 while (approx_equal(aux_vec, tn, 1e-10)) {
68 aux_vec = normalize(vec3::randu());
69 }
70 bases[i].col(0) = normalize(cross(aux_vec, t));
71 bases[i].col(1) = normalize(cross(t, bases[i].col(0)));
72 }
73 }
74
75 //------------------------------------------------------------------------------
76 template <typename Line>
78 auto redistributed_points = line.vertices();
79 const size_t start_idx = line.is_closed() ? 0 : 1;
80 const size_t end_idx = line.is_closed() ? line.size() : (line.size() - 1);
81
82 for (size_t i = start_idx; i < end_idx; ++i) {
83 const auto center =
84 ((i == line.size() - 1 ? line.front_vertex()
85 : line.vertex_at(i + 1)) +
86 (i == 0 ? line.back_vertex() : line.vertex_at(i - 1))) *
87 0.5;
88 const auto& t = tangents[i];
89 auto correction = t * (dot(center - line.vertex_at(i), t) / dot(t, t));
90 redistributed_points[i] += correction;
91 }
92 line.vertices() = std::move(redistributed_points);
93 }
94
95 //------------------------------------------------------------------------------
96 template <typename V, typename Line>
97 void calc_gradient_alpha(const V& v, Real t0, const Line& line) {
98 for (size_t i = 0; i < line.size(); ++i) {
99 const auto& x = line.vertex_at(i);
100
101 const Real offset = 1e-6;
102
103 const auto v_x_pos = normalize(v(x + bases[i].col(0) * offset, t0));
104 const auto v_x_neg = normalize(v(x - bases[i].col(0) * offset, t0));
105 const auto v_y_pos = normalize(v(x + bases[i].col(1) * offset, t0));
106 const auto v_y_neg = normalize(v(x - bases[i].col(1) * offset, t0));
107
108 const auto tn = normalize(tangents[i]);
109 auto alpha_x_pos = min_angle(tn, v_x_pos);
110 auto alpha_x_neg = min_angle(tn, v_x_neg);
111 auto alpha_y_pos = min_angle(tn, v_y_pos);
112 auto alpha_y_neg = min_angle(tn, v_y_neg);
113
114 if (std::isnan(alpha_x_pos)) { alpha_x_pos = 0; }
115 if (std::isnan(alpha_x_neg)) { alpha_x_neg = 0; }
116 if (std::isnan(alpha_y_pos)) { alpha_y_pos = 0; }
117 if (std::isnan(alpha_y_neg)) { alpha_y_neg = 0; }
118
119 grad_alpha[i] = {(alpha_x_pos - alpha_x_neg) / (offset * 2),
120 (alpha_y_pos - alpha_y_neg) / (offset * 2)};
121 }
122 }
123};
124
125curve_to_streamline()->curve_to_streamline<double>;
126
127//==============================================================================
128} // namespace tatooine
129//==============================================================================
130
131#endif
Definition: algorithm.h:6
constexpr auto min_angle(base_tensor< Tensor0, T0, N > const &v0, base_tensor< Tensor1, T1, N > const &v1)
Returns the angle of two normalized vectors.
Definition: tensor_operations.h:54
constexpr auto approx_equal(T0 const &lhs, T1 const &rhs, common_type< tatooine::value_type< T0 >, tatooine::value_type< T1 > > eps=1e-6)
for comparison
Definition: tensor_utility.h:11
constexpr auto normalize(base_tensor< Tensor, T, N > const &t_in) -> vec< T, N >
Definition: tensor_operations.h:100
constexpr auto dot(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: tensor_operations.h:120
constexpr auto cross(base_tensor< Tensor0, T0, 3 > const &lhs, base_tensor< Tensor1, T1, 3 > const &rhs)
Definition: cross.h:9
Definition: curve_to_streamline.h:11
void calc_tangents(const Line &line)
Definition: curve_to_streamline.h:53
std::vector< vec3 > tangents
Definition: curve_to_streamline.h:20
void calc_gradient_alpha(const V &v, Real t0, const Line &line)
Definition: curve_to_streamline.h:97
void step(Line &line, Real stepsize)
Definition: curve_to_streamline.h:44
void calc_plane_basis()
Definition: curve_to_streamline.h:60
void redistribute_points(Line &line) const
Definition: curve_to_streamline.h:77
std::vector< mat32 > bases
Definition: curve_to_streamline.h:18
auto operator()(const field< V, Real, 3, 3 > &v, Real t0, Line line, Real initial_stepsize, Real delta, size_t num_its)
Definition: curve_to_streamline.h:24
std::vector< vec2 > grad_alpha
Definition: curve_to_streamline.h:19
Definition: field.h:134
Definition: line.h:35
auto vertices() const
Definition: line.h:250
auto vertex_at(std::size_t const i) const -> auto const &
Definition: line.h:146
auto front_vertex() const -> auto const &
Definition: line.h:170
auto is_closed() const
Definition: line.h:305
auto back_vertex() const -> auto const &
Definition: line.h:173
Definition: mat.h:14
Definition: vec.h:12
static auto constexpr randu(ValueType min=0, ValueType max=1, RandEng &&eng=RandEng{std::random_device{}()})
Definition: vec.h:35