Tatooine
sampler.h
Go to the documentation of this file.
1#ifndef TATOOINE_DETAIL_AUTONOMOUS_PARTICLE_SAMPLER_H
2#define TATOOINE_DETAIL_AUTONOMOUS_PARTICLE_SAMPLER_H
3//==============================================================================
4#include <tatooine/concepts.h>
6#include <tatooine/mat.h>
7#include <tatooine/vec.h>
8
9#include <tatooine/linspace.h>
10//==============================================================================
12//==============================================================================
13template <floating_point Real, std::size_t NumDimensions>
14struct sampler {
15 //============================================================================
16 // TYPEDEFS
17 //============================================================================
22
23 private:
24 //============================================================================
25 // MEMBERS
26 //============================================================================
29
30 public:
31 //============================================================================
32 // CTORS
33 //============================================================================
34 sampler(sampler const&) = default;
35 sampler(sampler&&) noexcept = default;
36 //============================================================================
37 auto operator=(sampler const&) -> sampler& = default;
38 auto operator=(sampler&&) noexcept -> sampler& = default;
39 //============================================================================
40 sampler() = default;
41 ~sampler() = default;
42 //----------------------------------------------------------------------------
43 sampler(ellipse_type const& e0, ellipse_type const& e1,
44 mat_type const& nabla_phi)
45 : m_ellipse0{e0},
46 m_ellipse1{e1},
49 //============================================================================
51 auto ellipse(forward_tag const /*tag*/) const -> auto const& {
52 return m_ellipse0;
53 }
54 //----------------------------------------------------------------------------
55 auto ellipse(backward_tag const /*tag*/) const -> auto const& {
56 return m_ellipse1;
57 }
59 //----------------------------------------------------------------------------
61 auto nabla_phi(forward_tag const /*tag*/) const -> auto const& {
62 return m_nabla_phi0;
63 }
64 //----------------------------------------------------------------------------
65 auto nabla_phi(backward_tag const /*tag*/) const -> auto const& {
66 return m_nabla_phi1;
67 }
69 //============================================================================
70 auto local_pos(pos_type const& q,
71 forward_or_backward_tag auto const tag) const {
72 return transposed(nabla_phi(tag)) * (q - x0(tag));
73 }
74 //----------------------------------------------------------------------------
75 auto sample(pos_type const& q, forward_or_backward_tag auto const tag) const {
76 return phi(tag) + local_pos(q, tag);
77 }
78 //----------------------------------------------------------------------------
79 auto operator()(pos_type const& q,
80 forward_or_backward_tag auto const tag) const {
81 return sample(q, tag);
82 }
83 //----------------------------------------------------------------------------
84 auto is_inside(pos_type const& q,
85 forward_or_backward_tag auto const tag) const {
86 return ellipse(tag).is_inside(q);
87 }
88 //----------------------------------------------------------------------------
89 auto x0(forward_or_backward_tag auto const tag) const -> auto const& {
90 return ellipse(tag).center();
91 }
92 //----------------------------------------------------------------------------
93 auto phi(forward_or_backward_tag auto const tag) const -> auto const& {
94 return ellipse(opposite(tag)).center();
95 }
96 //----------------------------------------------------------------------------
97 auto distance_sqr(pos_type const& q,
98 forward_or_backward_tag auto const tag) const {
100 }
101 //----------------------------------------------------------------------------
102 auto distance(pos_type const& q, auto const tag) const {
103 return gcem::sqrt(distance_sqr(q, tag));
104 }
105 //----------------------------------------------------------------------------
106 auto S(forward_or_backward_tag auto const tag) const -> auto const& {
107 return ellipse(tag).S();
108 }
109 //----------------------------------------------------------------------------
110 auto discretize(std::size_t const n,
111 forward_or_backward_tag auto const tag) const {
112 return ellipse(tag).discretize(n);
113 }
114};
115//------------------------------------------------------------------------------
116template <floating_point Real>
117auto write_vtp(std::vector<sampler<Real, 2>> const& samplers,
118 std::size_t const n, filesystem::path const& path,
119 forward_or_backward_tag auto const tag) {
120 auto file = std::ofstream{path, std::ios::binary};
121 if (!file.is_open()) {
122 throw std::runtime_error{"Could not write " + path.string()};
123 }
124 auto offset = std::size_t{};
125 using header_type = std::uint64_t;
126 using lines_connectivity_int_t = std::int32_t;
127 using lines_offset_int_t = lines_connectivity_int_t;
128 file << "<VTKFile"
129 << " type=\"PolyData\""
130 << " version=\"1.0\" "
131 "byte_order=\"LittleEndian\""
132 << " header_type=\""
133 << vtk::xml::to_data_type<header_type>()
134 << "\">";
135 file << "<PolyData>\n";
136 for (std::size_t i = 0 ;i < size(samplers); ++i) {
137 file << "<Piece"
138 << " NumberOfPoints=\"" << n << "\""
139 << " NumberOfPolys=\"0\""
140 << " NumberOfVerts=\"0\""
141 << " NumberOfLines=\"" << n - 1 << "\""
142 << " NumberOfStrips=\"0\""
143 << ">\n";
144
145 // Points
146 file << "<Points>";
147 file << "<DataArray"
148 << " format=\"appended\""
149 << " offset=\"" << offset << "\""
150 << " type=\""
151 << vtk::xml::to_data_type<Real>()
152 << "\" NumberOfComponents=\"" << 3 << "\"/>";
153 auto const num_bytes_points =
154 header_type(sizeof(Real) * 3 * n);
155 offset += num_bytes_points + sizeof(header_type);
156 file << "</Points>\n";
157
158 // Lines
159 file << "<Lines>\n";
160 // Lines - connectivity
161 file << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
162 << vtk::xml::to_data_type<lines_connectivity_int_t>()
163 << "\" Name=\"connectivity\"/>\n";
164 auto const num_bytes_lines_connectivity =
165 (n - 1) * 2 *
166 sizeof(lines_connectivity_int_t);
167 offset += num_bytes_lines_connectivity + sizeof(header_type);
168 // Lines - offsets
169 file << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
170 << vtk::xml::to_data_type<lines_offset_int_t>()
171 << "\" Name=\"offsets\"/>\n";
172 auto const num_bytes_lines_offsets =
173 sizeof(lines_offset_int_t) * (n - 1) * 2;
174 offset += num_bytes_lines_offsets + sizeof(header_type);
175 file << "</Lines>\n";
176 file << "</Piece>\n";
177 }
178 file << "</PolyData>\n";
179 file << "<AppendedData encoding=\"raw\">_";
180 // Writing vertex data to appended data section
181 for (auto const& sampler : samplers) {
182 auto const num_bytes_points =
183 header_type(sizeof(Real) * 3 * n);
184 using namespace std::ranges;
185 auto radial = tatooine::linspace<Real>{0, M_PI * 2, n + 1};
186 radial.pop_back();
187
188 auto discretization = tatooine::line<Real, 3>{};
189 auto radian_to_cartesian = [](auto const t) {
190 return tatooine::vec{gcem::cos(t), gcem::sin(t), 0};
191 };
192 auto out_it = std::back_inserter(discretization);
193 copy(radial | views::transform(radian_to_cartesian), out_it);
194 discretization.set_closed(true);
195 for (auto const v : discretization.vertices()) {
196 auto v2 = sampler.S(tag) * discretization[v].xy() + sampler.x0(tag);;
197 discretization[v].x() = v2.x();
198 discretization[v].y() = v2.y();
199 }
200
201 // Writing points
202 file.write(reinterpret_cast<char const*>(&num_bytes_points), sizeof(header_type));
203 for (auto const v : discretization.vertices()) {
204 file.write(reinterpret_cast<char const*>(discretization.at(v).data()),
205 sizeof(Real) * 3);
206 }
207
208 // Writing lines connectivity data to appended data section
209 {
210 auto connectivity_data = std::vector<lines_connectivity_int_t>{};
211 connectivity_data.reserve((n - 1) * 2);
212 for (std::size_t i = 0; i < n - 1; ++i) {
213 connectivity_data.push_back(static_cast<lines_connectivity_int_t>(i));
214 connectivity_data.push_back(static_cast<lines_connectivity_int_t>(i + 1));
215 }
216
217 auto const num_bytes_lines_connectivity =
218 header_type((n - 1) * 2 * sizeof(lines_connectivity_int_t));
219 file.write(reinterpret_cast<char const*>(&num_bytes_lines_connectivity),
220 sizeof(header_type));
221 file.write(reinterpret_cast<char const*>(connectivity_data.data()),
222 static_cast<std::streamsize>(num_bytes_lines_connectivity));
223 }
224
225 // Writing lines offsets to appended data section
226 {
227 auto offsets = std::vector<lines_offset_int_t>(n, 2);
228 for (std::size_t i = 1; i < size(offsets); ++i) {
229 offsets[i] += offsets[i - 1];
230 }
231 auto const num_bytes_lines_offsets =
232 header_type(sizeof(lines_offset_int_t) * (n - 1) * 2);
233 file.write(reinterpret_cast<char const*>(&num_bytes_lines_offsets),
234 sizeof(header_type));
235 file.write(reinterpret_cast<char const*>(offsets.data()),
236 static_cast<std::streamsize>(num_bytes_lines_offsets));
237 }
238 }
239
240 file << "</AppendedData>";
241 file << "</VTKFile>";
242}
243//==============================================================================
244} // namespace tatooine::detail::autonomous_particle
245//==============================================================================
246#endif
Definition: post_triangulation.h:10
auto write_vtp(std::vector< sampler< Real, 2 > > const &samplers, std::size_t const n, filesystem::path const &path, forward_or_backward_tag auto const tag)
Definition: sampler.h:117
constexpr auto inv(diag_static_tensor< Tensor, N, N > const &A) -> std::optional< diag_static_tensor< vec< tatooine::value_type< Tensor >, N >, N, N > >
Definition: diag_tensor.h:109
constexpr auto euclidean_length(base_tensor< Tensor, T, N > const &t_in) -> T
Definition: length.h:12
constexpr auto opposite(forward_tag const)
Definition: tags.h:15
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto transposed(dynamic_tensor auto &&t)
Definition: transposed_tensor.h:170
Definition: tags.h:10
auto ellipse(backward_tag const) const -> auto const &
Definition: sampler.h:55
auto distance_sqr(pos_type const &q, forward_or_backward_tag auto const tag) const
Definition: sampler.h:97
auto nabla_phi(forward_tag const) const -> auto const &
Definition: sampler.h:61
auto x0(forward_or_backward_tag auto const tag) const -> auto const &
Definition: sampler.h:89
auto ellipse(forward_tag const) const -> auto const &
Definition: sampler.h:51
mat_type m_nabla_phi1
Definition: sampler.h:28
auto distance(pos_type const &q, auto const tag) const
Definition: sampler.h:102
auto S(forward_or_backward_tag auto const tag) const -> auto const &
Definition: sampler.h:106
auto operator()(pos_type const &q, forward_or_backward_tag auto const tag) const
Definition: sampler.h:79
auto nabla_phi(backward_tag const) const -> auto const &
Definition: sampler.h:65
auto sample(pos_type const &q, forward_or_backward_tag auto const tag) const
Definition: sampler.h:75
vec< Real, NumDimensions > vec_type
Definition: sampler.h:18
ellipse_type m_ellipse1
Definition: sampler.h:27
ellipse_type m_ellipse0
Definition: sampler.h:27
auto local_pos(pos_type const &q, forward_or_backward_tag auto const tag) const
Definition: sampler.h:70
mat_type m_nabla_phi0
Definition: sampler.h:28
auto phi(forward_or_backward_tag auto const tag) const -> auto const &
Definition: sampler.h:93
auto discretize(std::size_t const n, forward_or_backward_tag auto const tag) const
Definition: sampler.h:110
auto is_inside(pos_type const &q, forward_or_backward_tag auto const tag) const
Definition: sampler.h:84
Definition: tags.h:8
Definition: hyper_ellipse.h:12
Definition: line.h:35
Definition: linspace.h:26
constexpr auto pop_back()
Definition: linspace.h:107