Tatooine
streamsurface.h
Go to the documentation of this file.
1#ifndef TATOOINE_STREAMSURFACE_H
2#define TATOOINE_STREAMSURFACE_H
3//==============================================================================
6#include <tatooine/for_loop.h>
8#include <tatooine/line.h>
9#include <tatooine/linspace.h>
11#include <tatooine/ode/solver.h>
12#include <tatooine/tensor.h>
14
15#include <algorithm>
16#include <boost/functional.hpp>
17#include <boost/range/algorithm.hpp>
18#include <boost/range/numeric.hpp>
19#include <limits>
20#include <list>
21#include <map>
22#include <memory>
23//==============================================================================
24namespace tatooine {
25//==============================================================================
26template <typename Streamsurface>
27struct hultquist_discretization;
28//==============================================================================
29template <typename Flowmap,
30 template <typename> typename SeedcurveInterpolationKernel>
32 using flowmap_type = std::decay_t<Flowmap>;
33 static constexpr auto num_dimensions() -> std::size_t {
34 return flowmap_type::num_dimensions();
35 }
36 using real_type = typename flowmap_type::real_type;
40 typename seedcurve_type::template vertex_property_sampler_type<
41 seedcurve_type, SeedcurveInterpolationKernel>;
45
46 private:
47 Flowmap m_flowmap;
52
53 //----------------------------------------------------------------------------
54 public:
56 arithmetic auto t0u1, seedcurve_type const& seedcurve)
57 : m_flowmap{std::forward<decltype(flowmap)>(flowmap)},
58 m_t0_u0{static_cast<real_type>(t0u0)},
59 m_t0_u1{static_cast<real_type>(t0u1)},
62 seedcurve.template sampler<SeedcurveInterpolationKernel>()},
63 m_min_u{std::min(m_seedcurve.parameterization().front(),
64 m_seedcurve.parameterization().back())},
65 m_max_u{std::max(m_seedcurve.parameterization().front(),
66 m_seedcurve.parameterization().back())} {}
67 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
70 : m_flowmap{std::forward<decltype(flowmap)>(flowmap)},
71 m_t0_u0{static_cast<real_type>(t0)},
72 m_t0_u1{static_cast<real_type>(t0)},
75 seedcurve.template sampler<SeedcurveInterpolationKernel>()},
76 m_min_u{std::min(m_seedcurve.parameterization().front(),
77 m_seedcurve.parameterization().back())},
78 m_max_u{std::max(m_seedcurve.parameterization().front(),
79 m_seedcurve.parameterization().back())} {}
80 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
83 : m_flowmap{std::forward<decltype(flowmap)>(flowmap)},
84 m_t0_u0{static_cast<real_type>(0)},
85 m_t0_u1{static_cast<real_type>(0)},
88 seedcurve.template sampler<SeedcurveInterpolationKernel>()},
89 m_min_u{std::min(m_seedcurve.parameterization().front(),
90 m_seedcurve.parameterization().back())},
91 m_max_u{std::max(m_seedcurve.parameterization().front(),
92 m_seedcurve.parameterization().back())} {}
93 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94 // streamsurface(streamsurface const& other) = default;
95 // streamsurface(streamsurface&& other) = default;
96 // streamsurface& operator=(streamsurface const& other) = default;
97 // streamsurface& operator=(streamsurface&& other) = default;
98 //============================================================================
99 auto t0(real_type const u) const {
100 return (u - m_seedcurve.parameterization().front()) /
101 (m_seedcurve.parameterization().back() -
102 m_seedcurve.parameterization().front()) *
103 (m_t0_u1 - m_t0_u0) +
104 m_t0_u0;
105 }
106 //----------------------------------------------------------------------------
107 auto flowmap() -> auto& { return m_flowmap; }
108 auto flowmap() const -> auto const& { return m_flowmap; }
109 //----------------------------------------------------------------------------
110 auto seedcurve() const -> auto const& { return m_seedcurve; }
111 //----------------------------------------------------------------------------
113 auto sample(real_type const u, real_type const v) const -> vec_type {
114 if (u < m_min_u || u > m_max_u) {
115 throw out_of_domain_error{};
116 }
117 if (v == t0(u)) {
118 return m_seedcurve_interpolator(u);
119 }
120 try {
121 return m_flowmap(m_seedcurve_interpolator(u), t0(u), v);
122 } catch (std::exception&) {
123 throw out_of_domain_error{};
124 }
125 }
126 //----------------------------------------------------------------------------
128 auto sample(vec2 const& uv) const -> vec_type { return sample(uv(0), uv(1)); }
129 //----------------------------------------------------------------------------
130 auto distance(vec2 const& uv0, vec2 const& uv1,
131 std::size_t num_samples) const {
132 auto step = (uv1 - uv0) / (num_samples - 1);
133 real_type d = 0;
134 for (std::size_t i = 0; i < num_samples - 1; ++i) {
135 d += tatooine::euclidean_distance(sample(uv0 + step * i),
136 sample(uv0 + step * (i + 1)));
137 }
138 return d;
139 }
140 //----------------------------------------------------------------------------
141 auto operator()(real_type u, real_type v) const { return sample(u, v); }
142 auto operator()(vec2 const& uv) const { return sample(uv); }
143 //----------------------------------------------------------------------------
144 template <template <typename>
145 typename Discretization = hultquist_discretization,
146 typename... Args>
147 auto discretize(Args&&... args) {
148 return Discretization<this_type>(this, std::forward<Args>(args)...);
149 }
150 //----------------------------------------------------------------------------
151 constexpr auto min_u() const { return m_min_u; }
152 constexpr auto max_u() const { return m_max_u; }
153};
154//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
155template <typename Flowmap>
156streamsurface(Flowmap const&, arithmetic auto u0t0, arithmetic auto u1t0,
157 line<typename Flowmap::real_type,
158 Flowmap::num_dimensions()> const& seedcurve)
160// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161template <typename Flowmap>
162streamsurface(Flowmap const&, arithmetic auto t0,
163 line<typename Flowmap::real_type,
164 Flowmap::num_dimensions()> const& seedcurve)
166// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
167template <typename Flowmap>
169 Flowmap const&,
170 line<typename Flowmap::real_type, Flowmap::num_dimensions()> const&)
172// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
173template <typename Flowmap>
174streamsurface(Flowmap&&, arithmetic auto u0t0, arithmetic auto u1t0,
175 line<typename Flowmap::real_type,
176 Flowmap::num_dimensions()> const& seedcurve)
178// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
179template <typename Flowmap>
180streamsurface(Flowmap&&, arithmetic auto t0,
181 line<typename Flowmap::real_type,
182 Flowmap::num_dimensions()> const& seedcurve)
184// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
185template <typename Flowmap>
187 Flowmap&&,
188 line<typename Flowmap::real_type, Flowmap::num_dimensions()> const&)
190//==============================================================================
191template <typename Streamsurface>
193 : public unstructured_triangular_grid<typename Streamsurface::real_type,
194 Streamsurface::num_dimensions()> {
195 //============================================================================
196 // typedefs
197 //============================================================================
198 static constexpr auto num_dimensions() -> std::size_t {
199 return Streamsurface::num_dimensions();
200 }
201 using real_type = typename Streamsurface::real_type;
204 using parent_type::at;
205 using typename parent_type::pos_type;
206 using parent_type::operator[];
207 using typename parent_type::triangle_handle;
208 using typename parent_type::vertex_handle;
209
211 using uv_type = vec2;
213 typename parent_type::template typed_vertex_property_type<uv_type>;
214
215 using vertex_vec_type = std::vector<vertex_handle>;
216 using vertex_list_type = std::list<vertex_handle>;
217 using vertex_list_iterator_type = typename vertex_list_type::const_iterator;
219 std::pair<vertex_list_iterator_type, vertex_list_iterator_type>;
220 using streamsurface_type = Streamsurface;
221
222 // a front is a list of lists, containing vertices and a range specifing
223 // which vertices have to be triangulated from previous front
225
226 //============================================================================
227 // members
228 //============================================================================
229 private:
232
233 public:
234 auto streamsurface() const -> auto const& { return *m_streamsurface; }
235
236 //============================================================================
237 // ctors
238 //============================================================================
242 //----------------------------------------------------------------------------
244 : parent_type{other},
247 //----------------------------------------------------------------------------
249 : parent_type{std::move(other)},
250 m_streamsurface{other.m_streamsurface},
252 //----------------------------------------------------------------------------
253 auto& operator=(this_type const& other) {
257 return *this;
258 }
259 //----------------------------------------------------------------------------
260 auto& operator=(this_type&& other) noexcept {
261 parent_type::operator=(std::move(other));
262 m_streamsurface = other.m_streamsurface;
264 return *this;
265 }
266 //============================================================================
267 // methods
268 //============================================================================
269 private:
271 return this->template vertex_property<uv_type>("uv");
272 }
273 auto& find_uv_prop() { return this->template vertex_property<uv_type>("uv"); }
274 //----------------------------------------------------------------------------
275 public:
276 auto uv(vertex_handle v) -> auto& { return m_uv_property->at(v); }
277 auto uv(vertex_handle v) const -> auto const& { return m_uv_property->at(v); }
278 //----------------------------------------------------------------------------
279 auto t0(real_type u) const { return streamsurface().t0(u); }
280 //----------------------------------------------------------------------------
281 auto insert_vertex(pos_type const& p, uv_type const& p_uv) {
282 auto v = parent_type::insert_vertex(p);
283 uv(v) = p_uv;
284 return v;
285 }
286 //----------------------------------------------------------------------------
288 front_type const& front1) {
289 auto new_face_indices = std::vector<triangle_handle>{};
290 auto left0 = begin(front0);
291 auto const end0 = end(front0);
292 auto left1 = begin(front1);
293 auto const end1 = end(front1);
294
295 // while both lines are not fully traversed
296 while (next(left0) != end0 || next(left1) != end1) {
297 assert(left0 != end0);
298 assert(left1 != end1);
299 auto lower_edge_len = std::numeric_limits<real_type>::max();
300 auto upper_edge_len = std::numeric_limits<real_type>::max();
301 auto const right0 = next(left0);
302 auto const right1 = next(left1);
303
304 if (next(left0) != end0) {
305 lower_edge_len = std::abs(uv(*left1)(0) - uv(*right0)(0));
306 }
307
308 if (next(left1) != end1) {
309 upper_edge_len = std::abs(uv(*right1)(0) - uv(*left0)(0));
310 }
311
312 if (lower_edge_len < upper_edge_len) {
313 new_face_indices.push_back(
314 this->insert_triangle(*left0, *right0, *left1));
315 if (next(left0) != end0) {
316 ++left0;
317 }
318
319 } else {
320 new_face_indices.push_back(
321 this->insert_triangle(*left0, *right1, *left1));
322
323 if (next(left1) != end1) {
324 ++left1;
325 }
326 }
327 }
328 }
329 //----------------------------------------------------------------------------
331 auto dist_acc = real_type{};
332 for (auto v = begin(vertices); v != prev(end(vertices)); ++v) {
333 dist_acc += euclidean_distance(at(*v), at(*next(v)));
334 }
335 return dist_acc / static_cast<real_type>(size(vertices) - 1);
336 }
337 //--------------------------------------------------------------------------
338 auto seedcurve_to_front(std::size_t const seedline_resolution) {
339 auto front = front_type{};
340 for (auto u : linspace{streamsurface().min_u(), streamsurface().max_u(),
341 seedline_resolution}) {
342 auto const t0u = t0(u);
343 auto const new_pos = streamsurface()(u, t0u);
344 auto const v = insert_vertex(new_pos, uv_type{u, t0u});
345 front.push_back(v);
346 }
347 return front;
348 }
349 //--------------------------------------------------------------------------
350 auto subdivide(front_type& front, real_type desired_spatial_dist) -> void {
351 for (auto v = begin(front); v != prev(end(front)); ++v) {
352 auto d = real_type{};
353 try {
354 d = streamsurface().distance(uv(*v), uv(*next(v)), 5);
355 } catch (std::exception&) {
356 d = euclidean_distance(at(*v), at(*next(v)));
357 }
358
359 auto stop = false;
360 while (d > desired_spatial_dist * 1.5) {
361 // split front if u distance to small
362 auto new_uv = (uv(*v) + uv(*next(v))) * 0.5;
363 try {
364 auto new_pnt = streamsurface()(new_uv);
365 auto new_v = insert_vertex(new_pnt, uv_type{new_uv(0), new_uv(1)});
366 front.insert(next(v), new_v);
367 try {
368 d = streamsurface().distance(uv(*v), uv(*next(v)), 5);
369 } catch (std::exception&) {
370 d = euclidean_distance(at(*v), at(*next(v)));
371 }
372 } catch (std::exception&) {
373 stop = true;
374 break;
375 }
376 }
377 if (stop) {
378 break;
379 }
380 }
381 }
382 //---------------------------------------------------------------------------
383 void reduce(front_type& front, real_type desired_spatial_dist) {
384 if (front.size() >= 3) {
385 for (auto v = begin(front); v != prev(end(front), 2); ++v) {
386 auto d = [&] {
387 try {
388 return streamsurface().distance(uv(*v), uv(*next(v, 2)), 7);
389 } catch (std::exception&) {
390 return euclidean_distance(at(*v), at(*next(v))) +
391 euclidean_distance(at(*next(v)), at(*next(v, 2)));
392 }
393 };
394 while (next(v) != prev(end(front), 2) &&
395 d() < desired_spatial_dist * 1.25) {
396 front.erase(next(v));
397 }
398 }
399 }
400 if (front.size() > 2 &&
401 norm(at(*prev(end(front), 1)) - at(*prev(end(front), 2))) <
402 desired_spatial_dist * 0.5) {
403 front.erase(prev(end(front), 2));
404 }
405 }
406};
407//==============================================================================
408template <typename Streamsurface>
410 : public unstructured_triangular_grid<typename Streamsurface::real_type,
411 Streamsurface::num_dimensions()> {
412 //============================================================================
413 // typedefs
414 //============================================================================
415 static constexpr auto num_dimensions() -> std::size_t {
416 return Streamsurface::num_dimensions();
417 }
418 using real_type = typename Streamsurface::real_type;
421 using parent_type::at;
422 using typename parent_type::pos_type;
423 using parent_type::operator[];
424 using typename parent_type::triangle_handle;
425 using typename parent_type::vertex_handle;
426
428 using uv_type = vec2;
430 typename parent_type::template typed_vertex_property_type<uv_type>;
431
432 using vertex_vec_type = std::vector<vertex_handle>;
433 using vertex_list_type = std::list<vertex_handle>;
434 using vertex_list_iterator_type = typename vertex_list_type::const_iterator;
436 std::pair<vertex_list_iterator_type, vertex_list_iterator_type>;
437 using subfront_type = std::pair<vertex_list_type, vertex_range_type>;
438 using streamsurface_type = Streamsurface;
439
440 // a front is a list of lists, containing vertices and a range specifing
441 // which vertices have to be triangulated from previous front
442 using front_type = std::list<subfront_type>;
443
444 //============================================================================
445 // members
446 //============================================================================
447 private:
449 std::set<vertex_handle> m_on_border;
451
452 public:
453 auto streamsurface() const -> auto const& { return *m_streamsurface; }
454
455 //============================================================================
456 // ctors
457 //============================================================================
460 : m_streamsurface{streamsurface}, m_uv_property{&insert_uv_prop()} {}
461 //----------------------------------------------------------------------------
463 : parent_type{other},
464 m_streamsurface{other.m_streamsurface},
465 m_uv_property{&find_uv_prop()} {}
466 //----------------------------------------------------------------------------
468 : parent_type{std::move(other)},
469 m_streamsurface{other.m_streamsurface},
470 m_uv_property{&find_uv_prop()} {}
471 //----------------------------------------------------------------------------
472 auto& operator=(this_type const& other) {
473 parent_type::operator=(other);
474 m_streamsurface = other.m_streamsurface;
475 m_uv_property = &find_uv_prop();
476 return *this;
477 }
478 //----------------------------------------------------------------------------
479 auto& operator=(this_type&& other) noexcept {
480 parent_type::operator=(std::move(other));
481 m_streamsurface = other.m_streamsurface;
482 m_uv_property = &find_uv_prop();
483 return *this;
484 }
485 //============================================================================
486 // methods
487 //============================================================================
488 private:
490 return this->template vertex_property<uv_type>("uv");
491 }
492 auto& find_uv_prop() { return this->template vertex_property<uv_type>("uv"); }
493 //----------------------------------------------------------------------------
494 public:
495 auto& uv(vertex_handle v) { return m_uv_property->at(v); }
496 auto uv(vertex_handle v) const -> auto const& { return m_uv_property->at(v); }
497 //----------------------------------------------------------------------------
498 auto t0(real_type u) const { return streamsurface().t0(u); }
499 //----------------------------------------------------------------------------
500 auto insert_vertex(pos_type const& p, uv_type const& p_uv) {
501 auto v = parent_type::insert_vertex(p);
502 uv(v) = p_uv;
503 return v;
504 }
505 //----------------------------------------------------------------------------
506 auto insert_vertex(pos_type&& p, uv_type const& p_uv) {
507 auto v = parent_type::insert_vertex(std::move(p));
508 uv(v) = p_uv;
509 return v;
510 }
511 //----------------------------------------------------------------------------
512 auto insert_vertex(pos_type const& p, uv_type&& p_uv) {
513 auto v = parent_type::insert_vertex(p);
514 uv(v) = std::move(p_uv);
515 return v;
516 }
517 //----------------------------------------------------------------------------
518 auto insert_vertex(pos_type&& p, uv_type&& p_uv) {
519 auto v = parent_type::insert_vertex(std::move(p));
520 uv(v) = std::move(p_uv);
521 return v;
522 }
523 //----------------------------------------------------------------------------
525 for (auto const& subfront : front) {
526 auto new_face_indices = std::vector<triangle_handle>{};
527 auto const& vs = subfront.first;
528 auto [left0, end0] = subfront.second;
529 auto left1 = begin(vs);
530 auto end1 = end(vs);
531
532 if (left0 == end0) {
533 continue;
534 }
535
536 // while both lines are not fully traversed
537 while (next(left0) != end0 || next(left1) != end1) {
538 assert(left0 != end0);
539 assert(left1 != end1);
540 real_type lower_edge_len = std::numeric_limits<real_type>::max();
541 real_type upper_edge_len = std::numeric_limits<real_type>::max();
542 auto const right0 = next(left0);
543 auto const right1 = next(left1);
544
545 if (next(left0) != end0) {
546 lower_edge_len = std::abs(uv(*left1)(0) - uv(*right0)(0));
547 }
548
549 if (next(left1) != end1) {
550 upper_edge_len = std::abs(uv(*right1)(0) - uv(*left0)(0));
551 }
552
553 if (lower_edge_len < upper_edge_len) {
554 new_face_indices.push_back(
555 this->insert_triangle(*left0, *right0, *left1));
556 if (next(left0) != end0) {
557 ++left0;
558 }
559
560 } else {
561 new_face_indices.push_back(
562 this->insert_triangle(*left0, *right1, *left1));
563
564 if (next(left1) != end1) {
565 ++left1;
566 }
567 }
568 }
569 }
570 }
571 //--------------------------------------------------------------------------
572 auto seedcurve_to_front(std::size_t seedline_resolution) {
573 auto vs = std::vector<vertex_list_type>{};
574 vs.emplace_back();
575 for (auto u : linspace{streamsurface().min_u(), streamsurface().max_u(),
576 seedline_resolution}) {
577 auto const t0u = t0(u);
578 // if
579 // (this->streamsurface().vectorfield().in_domain(this->streamsurface().seedcurve().sample(u),
580 // t0u)) {
581 auto const new_pos = streamsurface().sample(u, t0u);
582 auto const v = insert_vertex(std::move(new_pos), uv_type{u, t0u});
583 vs.back().push_back(v);
584 //} else if (vs.back().size() > 1) {
585 // vs.emplace_back();
586 //} else {
587 // vs.back().clear();
588 //}
589 }
590 if (vs.back().size() <= 1) {
591 vs.pop_back();
592 }
593 auto front = front_type{};
594 for (auto&& vs : vs) {
595 front.emplace_back(std::move(vs), std::pair{begin(vs), end(vs)});
596 }
597 return front;
598 }
599 //----------------------------------------------------------------------------
601 return average_segment_length(subfront.first);
602 }
603 //----------------------------------------------------------------------------
605 real_type dist_acc = 0;
606 for (auto v = begin(vs); v != prev(end(vs)); ++v) {
607 dist_acc += norm(at(*v) - at(*next(v)));
608 }
609
610 return dist_acc / (vs.size() - 1);
611 }
612 //--------------------------------------------------------------------------
613 void subdivide(front_type& front, real_type desired_spatial_dist) {
614 auto find_best_predecessor = [this](auto const v, auto const& pred_range) {
615 real_type min_u_dist = std::numeric_limits<real_type>::max();
616 auto best_it = pred_range.second;
617 for (auto it = pred_range.first; it != pred_range.second; ++it) {
618 if (real_type u_dist = std::abs(uv(*v)(0) - uv(*it)(0));
619 u_dist < min_u_dist) {
620 min_u_dist = u_dist;
621 best_it = it;
622 if (min_u_dist == 0) {
623 break;
624 }
625 }
626 }
627 return best_it;
628 };
629
630 for (auto subfront = begin(front); subfront != end(front); ++subfront) {
631 if (subfront->first.size() > 1) {
632 auto& vs = subfront->first;
633 auto& pred_range = subfront->second;
634
635 for (auto v = begin(vs); v != prev(end(vs)); ++v) {
636 real_type d;
637 try {
638 d = streamsurface().distance(uv(*v), uv(*next(v)), 5);
639 } catch (std::exception&) {
640 d = euclidean_distance(at(*v), at(*next(v)));
641 }
642
643 bool stop = false;
644 while (d > desired_spatial_dist * 1.5) {
645 // split front if u distance to small
646 real_type u_dist = std::abs(uv(*v)(0) - uv(*next(v))(0));
647 if (u_dist < 1e-5) {
648 auto const best_predecessor = find_best_predecessor(v, pred_range);
649 front.emplace(
650 next(subfront), vertex_list_type{next(v), end(vs)},
651 vertex_range_type{next(best_predecessor), pred_range.second});
652 pred_range.second = next(best_predecessor);
653 vs.erase(next(v), end(vs));
654 stop = true;
655 break;
656 }
657
658 auto new_uv = (uv(*v) + uv(*next(v))) * 0.5;
659 try {
660 auto new_pnt = streamsurface()(new_uv);
661 auto new_v =
662 insert_vertex(new_pnt, uv_type{new_uv(0), new_uv(1)});
663 vs.insert(next(v), new_v);
664 try {
665 d = streamsurface().distance(uv(*v), uv(*next(v)), 5);
666 } catch (std::exception&) {
667 d = euclidean_distance(at(*v), at(*next(v)));
668 }
669 } catch (std::exception&) {
670 if (next(v, 2) != end(vs)) {
671 auto const best_predecessor = find_best_predecessor(v, pred_range);
672 // front.emplace(next(subfront), vertex_list_type{next(v),
673 // end(vs)},
674 // vertex_range_type{next(best_predecessor),
675 // pred_range.second});
676 pred_range.second = next(best_predecessor);
677 vs.erase(next(v), end(vs));
678 }
679 stop = true;
680 break;
681 }
682 }
683 if (stop) {
684 break;
685 }
686 }
687 }
688 }
689 }
690 //---------------------------------------------------------------------------
691 void reduce(front_type& front, real_type desired_spatial_dist) {
692 for (auto& subfront : front) {
693 auto& vs = subfront.first;
694 if (vs.size() >= 3) {
695 for (auto v = begin(vs); v != prev(end(vs), 2); ++v) {
696 // if (m_on_border.find(*v) != end(m_on_border)) {
697 // continue;
698 // }
699 auto d = [&] {
700 try {
701 return streamsurface().distance(uv(*v), uv(*next(v, 2)), 7);
702 } catch (std::exception&) {
703 return euclidean_distance(at(*v), at(*next(v))) +
704 euclidean_distance(at(*next(v)), at(*next(v, 2)));
705 }
706 };
707 while (next(v) != prev(end(vs), 2) &&
708 d() < desired_spatial_dist * 1.25) {
709 vs.erase(next(v));
710 }
711 }
712 }
713 if (vs.size() > 2 && norm(at(*prev(end(vs), 1)) - at(*prev(end(vs), 2))) <
714 desired_spatial_dist * 0.5) {
715 vs.erase(prev(end(vs), 2));
716 }
717 }
718 }
719};
720//==============================================================================
721template <typename Streamsurface>
724 using real_type = typename Streamsurface::real_type;
725 static constexpr auto num_dimensions() -> std::size_t {
726 return Streamsurface::num_dimensions();
727 }
740 using parent_type::at;
742 using parent_type::t0;
743 using parent_type::uv;
745 //============================================================================
747 naive_discretization(naive_discretization&& other) noexcept = default;
750 default;
752 //============================================================================
754 std::size_t seedline_resolution, real_type stepsize,
755 real_type backward_tau, real_type forward_tau)
757 assert(forward_tau >= 0);
758 assert(backward_tau <= 0);
759
760 auto const seed_front = this->seedcurve_to_front(seedline_resolution);
761 if (seed_front.empty()) {
762 return;
763 }
764
765 if (backward_tau < 0) {
766 auto cur_stepsize = stepsize;
767 auto cur_front = seed_front;
768 real_type advected_time = 0;
769 while (advected_time > backward_tau) {
770 if (advected_time - cur_stepsize < backward_tau) {
771 cur_stepsize = std::abs(backward_tau - advected_time);
772 }
773 cur_front = evolve(cur_front, -cur_stepsize);
774 advected_time -= cur_stepsize;
775 }
776 }
777
778 if (forward_tau > 0) {
779 auto cur_stepsize = stepsize;
780 auto cur_front = seed_front;
781 real_type advected_time = 0;
782 while (advected_time < forward_tau) {
783 if (advected_time + cur_stepsize > forward_tau) {
784 cur_stepsize = forward_tau - advected_time;
785 }
786 cur_front = evolve(cur_front, cur_stepsize);
787 advected_time += cur_stepsize;
788 }
789 }
790 }
791
792 //============================================================================
793 auto evolve(front_type const& front, real_type const step) {
794 auto advected_front = front;
795 auto& [vertices, range] = advected_front.front();
796 range.first = begin(front.front().first);
797 range.second = end(front.front().first);
798
799 for (auto& v : vertices) {
800 auto const& uv = parent_type::uv(v);
801 vec const new_uv{uv(0), uv(1) + step};
802 auto new_pos = streamsurface()(new_uv);
803
804 v = insert_vertex(new_pos, {uv(0), uv(1) + step});
805 }
806
807 this->triangulate_timeline(front, advected_front);
808 return advected_front;
809 }
810};
811//==============================================================================
812template <typename Streamsurface>
815 using real_type = typename Streamsurface::real_type;
819 using parent_type::at;
821 using parent_type::t0;
822 using parent_type::uv;
824 using typename parent_type::front_type;
825 using typename parent_type::streamsurface_type;
826 using typename parent_type::triangle_handle;
827 using typename parent_type::uv_type;
828 using typename parent_type::vertex_handle;
830 using typename parent_type::vertex_list_type;
831 using typename parent_type::vertex_range_type;
832 using typename parent_type::vertex_vec_type;
833 //----------------------------------------------------------------------------
835 std::size_t seedline_resolution, real_type stepsize,
836 real_type backward_tau, real_type forward_tau)
838 assert(forward_tau >= 0);
839 assert(backward_tau <= 0);
840
841 auto const seed_front = this->seedcurve_to_front(seedline_resolution);
842 if (seed_front.size() <= 1) {
843 return;
844 }
845 auto const desired_spatial_dist = this->average_segment_length(seed_front);
846
847 if (backward_tau < 0) {
848 auto cur_stepsize = stepsize;
849 auto cur_front = seed_front;
850 auto advected_time = real_type{};
851 while (advected_time > backward_tau) {
852 if (advected_time - cur_stepsize < backward_tau) {
853 cur_stepsize = std::abs(backward_tau - advected_time);
854 }
855 cur_front = evolve(cur_front, -cur_stepsize, desired_spatial_dist);
856 advected_time -= cur_stepsize;
857 }
858 }
859
860 if (forward_tau > 0) {
861 auto cur_stepsize = stepsize;
862 auto cur_front = seed_front;
863 auto advected_time = real_type{};
864 while (advected_time < forward_tau) {
865 if (advected_time + cur_stepsize > forward_tau) {
866 cur_stepsize = forward_tau - advected_time;
867 }
868 cur_front = evolve(cur_front, cur_stepsize, desired_spatial_dist);
869 advected_time += cur_stepsize;
870 }
871 }
872 }
873 //----------------------------------------------------------------------------
874 hultquist_discretization(this_type const& other) = default;
875 hultquist_discretization(this_type&& other) noexcept = default;
876 auto operator=(this_type const& other) -> hultquist_discretization& = default;
877 auto operator=(this_type&& other) noexcept
878 -> hultquist_discretization& = default;
880 //============================================================================
882 assert(step != 0);
883 for (auto& v :front) {
884 auto const& uv = parent_type::uv(v);
885 auto const new_uv = vec{uv(0), uv(1) + step};
886 auto new_pos = streamsurface()(new_uv);
887 v = insert_vertex(new_pos, uv_type{new_uv(0), new_uv(1)});
888 }
889 return front;
890 }
891
892 //--------------------------------------------------------------------------
893 auto evolve(front_type const& front, real_type step,
894 real_type /*desired_spatial_dist*/) {
895 auto advected_front = advect(front, step);
896
897 //this->subdivide(advected_front, desired_spatial_dist);
898 //this->reduce(advected_front, desired_spatial_dist);
899 if (step > 0) {
900 this->triangulate_timeline(front, advected_front);
901 } else {
902 this->triangulate_timeline(advected_front, front);
903 }
904 return advected_front;
905 }
906};
907
908//==============================================================================
909// template <typename Flowmap,
910// template <typename> typename SeedcurveInterpolationKernel>
911// struct schulze_discretization : multi_front_evolving_streamsurface_discretization<
912// Flowmap, SeedcurveInterpolationKernel> {
913// using real_type = typename Flowmap::real_type;
914// static constexpr auto num_dimensions() -> std::size_t { return Flowmap::num_dimensions(); }
915// using parent_type =
916// multi_front_evolving_streamsurface_discretization<Flowmap,
917// SeedcurveInterpolationKernel>;
918// using typename parent_type::triangle_handle;
919// using typename parent_type::front_type;
920// using typename parent_type::streamsurface_type;
921// using typename parent_type::subfront_type;
922// using typename parent_type::vertex_handle;
923// using typename parent_type::vertex_list_iterator_type;
924// using typename parent_type::vertex_list_type;
925// template <typename T>
926// using vertex_property_t = typename parent_type::template
927// vertex_property_t<T>; using parent_type::at; using
928// parent_type::insert_vertex; using parent_type::uv;
929// using parent_type::streamsurface;
930//
931// vertex_property_t<real_type>& alpha_prop;
932// vertex_property_t<real_type>& second_derivate_alpha_prop;
933//
934// //----------------------------------------------------------------------------
935// schulze_discretization(streamsurface_type* streamsurface, std::size_t
936// seedline_resolution,
937// std::size_t num_iterations)
938// : parent_type(streamsurface),
939// alpha_prop(this->template add_vertex_property<real_type>("alpha")),
940// second_derivate_alpha_prop(
941// this->template add_vertex_property<real_type>(
942// "second_derivative_alpha")) {
943// auto const initial_front = this->seedcurve_to_front(seedline_resolution);
944// real_type desired_spatial_dist =
945// this->average_segment_length(initial_front.front());
946//
947// // evolve front
948// front_type cur_front = initial_front;
949// for (std::size_t i = 0; i < num_iterations; ++i) {
950// cur_front = evolve(cur_front, desired_spatial_dist);
951// }
952// }
953//
954// //--------------------------------------------------------------------------
955// auto advect(subfront_type const& front) {
956// std::vector<subfront_type> new_subfronts{
957// {{}, {begin(front.first), end(front.first)}}};
958// auto const& [vs, pred_range] = front;
959// // advect each subfront
960// auto alpha = optimal_stepsizes(vs);
961// for (auto [v, i] = std::pair{begin(vs), std::size_t(0)}; v != end(vs);
962// ++v, ++i) {
963// alpha_prop[*v] = alpha[i];
964// }
965// auto splitted_front_ranges = detect_peaks(alpha, vs);
966// // no rip needed
967// if (size(splitted_front_ranges) == 1 &&
968// splitted_front_ranges[0].first == begin(vs) &&
969// splitted_front_ranges[0].second == end(vs)) {
970// auto& vertices1 = new_subfronts
971// .emplace_back(std::list<vertex_handle>{},
972// std::pair{begin(vs), end(vs)})
973// .first;
974//
975// std::size_t i = 0;
976// for (auto const v : vs) {
977// auto const& uv = parent_type::uv(v);
978// vec2 new_uv{uv(0), uv(1) + alpha[i++]};
979// auto new_pos = streamsurface()(new_uv);
980// vertices1.push_back(insert_vertex(new_pos, new_uv));
981// alpha_prop[v] = alpha[i - 1];
982// }
983//
984// } else {
985// // rip needed
986// for (auto const& range : splitted_front_ranges) {
987// auto& [vertices1, pred_range] =
988// new_subfronts.emplace_back(std::list<vertex_handle>{}, range);
989//
990// std::size_t i = 0;
991// std::list<vertex_handle> sub_front;
992// std::copy(pred_range.first, pred_range.second,
993// std::back_inserter(sub_front));
994// auto sub_alpha = optimal_stepsizes(sub_front);
995// for (auto v = pred_range.first; v != pred_range.second; ++v) {
996// auto const& uv = parent_type::uv(*v);
997// vec2 new_uv{uv(0), uv(1) + sub_alpha[i++]};
998// auto new_pos = streamsurface()(new_uv);
999// vertices1.push_back(insert_vertex(new_pos, new_uv));
1000// alpha_prop[vertices1.back()] = sub_alpha[i - 1];
1001// }
1002// }
1003// }
1004// return new_subfronts;
1005// }
1006// //--------------------------------------------------------------------------
1007// auto advect(front_type const& front) {
1008// front_type advected_front;
1009// for (auto const& subfront : front) {
1010// if (subfront.first.size() > 1) {
1011// boost::copy(advect(subfront),
1012// std::back_inserter(advected_front));
1013// }
1014// }
1015// return advected_front;
1016// }
1017// //----------------------------------------------------------------------------
1018// auto evolve(front_type const& front, real_type desired_spatial_dist) {
1019// auto advected_front = advect(front);
1020// // triangulate
1021// std::vector<std::vector<triangle_handle>> faces;
1022// this->subdivide(advected_front, desired_spatial_dist);
1023// this->reduce(advected_front, desired_spatial_dist);
1024// this->triangulate_timeline(advected_front);
1025// return advected_front;
1026// }
1027// //----------------------------------------------------------------------------
1028// std::vector<real_type> optimal_stepsizes(vertex_list_type const& vs) {
1029// auto const& v = streamsurface().flowmap().vectorfield();
1030// auto jacobian = diff(v, 1e-7);
1031//
1032// auto num_pnts = size(vs);
1033// std::vector<real_type> p(num_pnts - 1), q(num_pnts - 1), null(num_pnts),
1034// r(num_pnts);
1035// std::vector<vec<real_type, num_dimensions()>> ps(num_pnts);
1036//
1037// // TODO: get t0 at u, not at 0
1038// std::size_t i = 0;
1039// for (auto const vertex_handle : vs)
1040// ps[i++] = v(at(vertex_handle), this->t0(0) + uv(vertex_handle)(1));
1041//
1042// i = 0;
1043// real_type avg_len = 0;
1044// for (auto vertex_handle = begin(vs); vertex_handle != prev(end(vs));
1045// ++vertex_handle, ++i) {
1046// auto tm = this->t0(0) +
1047// (uv(*vertex_handle)(1) + uv(*next(vertex_handle))(1)) * 0.5;
1048// auto xm = (at(*next(vertex_handle)) + at(*vertex_handle)) * 0.5;
1049// auto dir = at(*next(vertex_handle)) - at(*vertex_handle);
1050// auto vm = v(xm, tm);
1051// auto Jm = jacobian(xm, tm);
1052//
1053// p[i] = dot(dir * 0.5, Jm * ps[i]) - dot(ps[i], vm);
1054// q[i] = dot(dir * 0.5, Jm * ps[i + 1]) + dot(ps[i + 1], vm);
1055// r[i] = -dot(dir, vm);
1056//
1057// avg_len += norm(dir);
1058// }
1059// avg_len /= num_pnts - 1;
1060// solve_qr(num_pnts - 1, &p[0], &q[0], &r[0], &null[0]);
1061//
1062// // real_type nrm{0};
1063// // for (auto x : null) nrm += x * x;
1064// // nrm = sqrt(nrm);
1065// // for (std::size_t i = 0; i < null.size(); ++i) null[i] /= nrm;
1066//
1067// // count positive entries in nullspace
1068// std::size_t num_pos_null = 0;
1069// for (auto c : null)
1070// if (c > 0) ++num_pos_null;
1071// int k_plus_factor = (num_pos_null < null.size() / 2) ? -1 : 1;
1072//
1073// for (std::size_t i = 0; i < r.size(); ++i)
1074// r[i] += k_plus_factor * null[i];
1075// // r[i] += (num_pnts / 10.0) * k_plus_factor * null[i];
1076//
1077// // apply step width
1078// real_type h = std::numeric_limits<real_type>::max();
1079// for (std::size_t i = 0; i < num_pnts; ++i)
1080// h = std::min(h, avg_len / (std::abs(r[i]) * norm(ps[i])));
1081// for (std::size_t i = 0; i < r.size(); ++i)
1082// r[i] *= h;
1083// // for (std::size_t i = 0; i < r.size(); ++i) r[i] = std::max(r[i],1e-3);
1084// return r;
1085// }
1086//
1087// //----------------------------------------------------------------------------
1088// auto detect_peaks(std::vector<real_type> const& alpha,
1089// vertex_list_type const& vs, real_type threshold = 100) {
1090// // calculate second derivative
1091// std::vector<real_type> snd_der(alpha.size(), 0);
1092// auto v = next(begin(vs));
1093// for (std::size_t i = 1; i < alpha.size() - 1; ++i, ++v) {
1094// mat<real_type, 3, 3> A{
1095// {real_type(1), uv(*prev(v))(0), uv(*prev(v))(0) * uv(*prev(v))(0)},
1096// {real_type(1), uv(*v)(0), uv(*v)(0) * uv(*v)(0)},
1097// {real_type(1), uv(*next(v))(0), uv(*next(v))(0) * uv(*next(v))(0)}};
1098// vec<real_type, 3> b{alpha[i - 1], alpha[i], alpha[i + 1]};
1099// snd_der[i] = 2 * solve(A, b)(2);
1100// second_derivate_alpha_prop[*v] = std::abs(snd_der[i]);
1101// }
1102//
1103// std::vector<std::pair<vertex_list_iterator_type,
1104// vertex_list_iterator_type>>
1105// splitted_front_ranges;
1106// splitted_front_ranges.emplace_back(begin(vs), end(vs));
1107//
1108// auto v_it = next(begin(vs));
1109// for (std::size_t i = 1; i < snd_der.size() - 1; ++i, ++v_it)
1110// if (std::abs(snd_der[i]) > threshold) {
1111// if (splitted_front_ranges.back().first == v_it)
1112// // shift left border of split to the right
1113// ++splitted_front_ranges.back().first;
1114// else {
1115// // insert new subfront
1116// splitted_front_ranges.back().second = next(v_it);
1117// if (splitted_front_ranges.back().first ==
1118// splitted_front_ranges.back().second)
1119// splitted_front_ranges.pop_back();
1120//
1121// splitted_front_ranges.emplace_back(next(v_it), end(vs));
1122// }
1123// }
1124// if (splitted_front_ranges.back().first ==
1125// splitted_front_ranges.back().second) {
1126// splitted_front_ranges.pop_back();
1127// }
1128// return splitted_front_ranges;
1129// }
1130//};
1131//==============================================================================
1132} // namespace tatooine
1133//==============================================================================
1134#endif
auto & operator=(const cache &other)
Definition: cache.h:48
Definition: concepts.h:33
Definition: concepts.h:39
Definition: concepts.h:84
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
Vec< 2 > vec2
Definition: vec_typedefs.h:28
constexpr auto norm(base_tensor< Tensor, T, N > const &t, unsigned p=2) -> T
Definition: norm.h:23
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto next(Iter iter)
Definition: iterator_facade.h:325
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
auto back(linspace< Real > const &l)
Definition: linspace.h:136
auto front(linspace< Real > const &l)
Definition: linspace.h:126
static constexpr forward_tag forward
Definition: tags.h:9
constexpr auto euclidean_distance(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: distance.h:19
auto prev(Iter iter)
Definition: iterator_facade.h:343
vec_type pos_type
Definition: axis_aligned_bounding_box.h:109
typename vertex_list_type::const_iterator vertex_list_iterator_type
Definition: streamsurface.h:217
streamsurface_type const * m_streamsurface
Definition: streamsurface.h:230
uv_property_type * m_uv_property
Definition: streamsurface.h:231
auto subdivide(front_type &front, real_type desired_spatial_dist) -> void
Definition: streamsurface.h:350
vec< real_type, 2 > vec2
Definition: streamsurface.h:210
auto seedcurve_to_front(std::size_t const seedline_resolution)
Definition: streamsurface.h:338
front_evolving_streamsurface_discretization(this_type &&other) noexcept
Definition: streamsurface.h:248
typename Streamsurface::real_type real_type
Definition: streamsurface.h:201
auto streamsurface() const -> auto const &
Definition: streamsurface.h:234
typename parent_type::template typed_vertex_property_type< uv_type > uv_property_type
Definition: streamsurface.h:213
Streamsurface streamsurface_type
Definition: streamsurface.h:220
auto uv(vertex_handle v) const -> auto const &
Definition: streamsurface.h:277
auto average_segment_length(vertex_list_type const &vertices) const
Definition: streamsurface.h:330
auto & insert_uv_prop()
Definition: streamsurface.h:270
auto & find_uv_prop()
Definition: streamsurface.h:273
typename parent_type::simplex_handle triangle_handle
Definition: unstructured_triangular_grid.h:15
front_evolving_streamsurface_discretization(this_type const &other)
Definition: streamsurface.h:243
auto t0(real_type u) const
Definition: streamsurface.h:279
void reduce(front_type &front, real_type desired_spatial_dist)
Definition: streamsurface.h:383
std::pair< vertex_list_iterator_type, vertex_list_iterator_type > vertex_range_type
Definition: streamsurface.h:219
auto & operator=(this_type &&other) noexcept
Definition: streamsurface.h:260
auto & operator=(this_type const &other)
Definition: streamsurface.h:253
std::list< vertex_handle > vertex_list_type
Definition: streamsurface.h:216
static constexpr auto num_dimensions() -> std::size_t
Definition: streamsurface.h:198
vec2 uv_type
Definition: streamsurface.h:211
std::vector< vertex_handle > vertex_vec_type
Definition: streamsurface.h:215
front_evolving_streamsurface_discretization(streamsurface_type const *streamsurface)
Definition: streamsurface.h:239
auto uv(vertex_handle v) -> auto &
Definition: streamsurface.h:276
auto triangulate_timeline(front_type const &front0, front_type const &front1)
Definition: streamsurface.h:287
auto insert_vertex(pos_type const &p, uv_type const &p_uv)
Definition: streamsurface.h:281
vertex_list_type front_type
Definition: streamsurface.h:224
Definition: streamsurface.h:814
auto operator=(this_type &&other) noexcept -> hultquist_discretization &=default
hultquist_discretization(streamsurface_type *streamsurface, std::size_t seedline_resolution, real_type stepsize, real_type backward_tau, real_type forward_tau)
Definition: streamsurface.h:834
typename Streamsurface::real_type real_type
Definition: streamsurface.h:815
hultquist_discretization(this_type &&other) noexcept=default
auto streamsurface() const -> auto const &
Definition: streamsurface.h:234
auto operator=(this_type const &other) -> hultquist_discretization &=default
Streamsurface streamsurface_type
Definition: streamsurface.h:220
hultquist_discretization(this_type const &other)=default
auto evolve(front_type const &front, real_type step, real_type)
Definition: streamsurface.h:893
auto uv(vertex_handle v) -> auto &
Definition: streamsurface.h:276
auto insert_vertex(pos_type const &p, uv_type const &p_uv)
Definition: streamsurface.h:281
vertex_list_type front_type
Definition: streamsurface.h:224
auto advect(front_type front, real_type step)
Definition: streamsurface.h:881
Definition: interpolation.h:16
auto parameterization() -> auto &
Definition: line.h:502
Definition: linspace.h:26
auto & operator=(this_type &&other) noexcept
Definition: streamsurface.h:479
typename Streamsurface::real_type real_type
Definition: streamsurface.h:418
std::list< vertex_handle > vertex_list_type
Definition: streamsurface.h:433
void triangulate_timeline(front_type const &front)
Definition: streamsurface.h:524
auto t0(real_type u) const
Definition: streamsurface.h:498
std::pair< vertex_list_type, vertex_range_type > subfront_type
Definition: streamsurface.h:437
std::list< subfront_type > front_type
Definition: streamsurface.h:442
auto seedcurve_to_front(std::size_t seedline_resolution)
Definition: streamsurface.h:572
auto uv(vertex_handle v) const -> auto const &
Definition: streamsurface.h:496
typename parent_type::template typed_vertex_property_type< uv_type > uv_property_type
Definition: streamsurface.h:430
auto insert_vertex(pos_type const &p, uv_type &&p_uv)
Definition: streamsurface.h:512
void reduce(front_type &front, real_type desired_spatial_dist)
Definition: streamsurface.h:691
typename vertex_list_type::const_iterator vertex_list_iterator_type
Definition: streamsurface.h:434
auto & operator=(this_type const &other)
Definition: streamsurface.h:472
Streamsurface streamsurface_type
Definition: streamsurface.h:438
multi_front_evolving_streamsurface_discretization(this_type &&other) noexcept
Definition: streamsurface.h:467
real_type average_segment_length(vertex_list_type const &vs) const
Definition: streamsurface.h:604
void subdivide(front_type &front, real_type desired_spatial_dist)
Definition: streamsurface.h:613
auto insert_vertex(pos_type &&p, uv_type const &p_uv)
Definition: streamsurface.h:506
multi_front_evolving_streamsurface_discretization(streamsurface_type const *streamsurface)
Definition: streamsurface.h:458
auto & find_uv_prop()
Definition: streamsurface.h:492
auto insert_vertex(pos_type &&p, uv_type &&p_uv)
Definition: streamsurface.h:518
uv_property_type * m_uv_property
Definition: streamsurface.h:450
auto & uv(vertex_handle v)
Definition: streamsurface.h:495
auto insert_vertex(pos_type const &p, uv_type const &p_uv)
Definition: streamsurface.h:500
std::vector< vertex_handle > vertex_vec_type
Definition: streamsurface.h:432
multi_front_evolving_streamsurface_discretization(this_type const &other)
Definition: streamsurface.h:462
std::pair< vertex_list_iterator_type, vertex_list_iterator_type > vertex_range_type
Definition: streamsurface.h:436
auto & insert_uv_prop()
Definition: streamsurface.h:489
real_type average_segment_length(subfront_type const &subfront) const
Definition: streamsurface.h:600
streamsurface_type const * m_streamsurface
Definition: streamsurface.h:448
auto streamsurface() const -> auto const &
Definition: streamsurface.h:453
static constexpr auto num_dimensions() -> std::size_t
Definition: streamsurface.h:415
std::set< vertex_handle > m_on_border
Definition: streamsurface.h:449
Definition: streamsurface.h:723
typename parent_type::streamsurface_type streamsurface_type
Definition: streamsurface.h:732
typename Streamsurface::real_type real_type
Definition: streamsurface.h:724
typename parent_type::vertex_list_iterator_type vertex_list_iterator_type
Definition: streamsurface.h:738
naive_discretization(naive_discretization const &other)=default
static constexpr auto num_dimensions() -> std::size_t
Definition: streamsurface.h:725
typename parent_type::vertex_vec_type vertex_vec_type
Definition: streamsurface.h:733
auto streamsurface() const -> auto const &
Definition: streamsurface.h:234
typename parent_type::vertex_range_type vertex_range_type
Definition: streamsurface.h:739
naive_discretization(streamsurface_type *streamsurface, std::size_t seedline_resolution, real_type stepsize, real_type backward_tau, real_type forward_tau)
Definition: streamsurface.h:753
naive_discretization & operator=(naive_discretization &&other) noexcept=default
typename parent_type::vertex_list_type vertex_list_type
Definition: streamsurface.h:734
typename parent_type::subfront_type subfront_type
Definition: streamsurface.h:731
naive_discretization(naive_discretization &&other) noexcept=default
auto evolve(front_type const &front, real_type const step)
Definition: streamsurface.h:793
typename parent_type::vertex_handle vertex_handle
Definition: streamsurface.h:735
naive_discretization & operator=(naive_discretization const &other)=default
typename parent_type::triangle_handle triangle_handle
Definition: streamsurface.h:736
auto uv(vertex_handle v) -> auto &
Definition: streamsurface.h:276
typename parent_type::front_type front_type
Definition: streamsurface.h:730
auto insert_vertex(pos_type const &p, uv_type const &p_uv)
Definition: streamsurface.h:281
Definition: exceptions.h:8
Definition: pointset.h:83
auto insert_vertex(arithmetic auto const ... ts)
Definition: pointset.h:243
auto vertices() const
Definition: pointset.h:226
Definition: streamsurface.h:31
constexpr auto min_u() const
Definition: streamsurface.h:151
streamsurface(convertible_to< Flowmap > auto &&flowmap, seedcurve_type const &seedcurve)
Definition: streamsurface.h:81
real_type m_t0_u0
Definition: streamsurface.h:48
typename seedcurve_type::template vertex_property_sampler_type< seedcurve_type, SeedcurveInterpolationKernel > seedcurve_interpolator_type
Definition: streamsurface.h:41
streamsurface(convertible_to< Flowmap > auto &&flowmap, arithmetic auto t0u0, arithmetic auto t0u1, seedcurve_type const &seedcurve)
Definition: streamsurface.h:55
auto operator()(real_type u, real_type v) const
Definition: streamsurface.h:141
streamsurface(convertible_to< Flowmap > auto &&flowmap, arithmetic auto t0, seedcurve_type const &seedcurve)
Definition: streamsurface.h:68
auto sample(real_type const u, real_type const v) const -> vec_type
calculates position of streamsurface
Definition: streamsurface.h:113
Flowmap m_flowmap
Definition: streamsurface.h:47
auto operator()(vec2 const &uv) const
Definition: streamsurface.h:142
auto flowmap() const -> auto const &
Definition: streamsurface.h:108
real_type m_t0_u1
Definition: streamsurface.h:48
auto seedcurve() const -> auto const &
Definition: streamsurface.h:110
real_type m_max_u
Definition: streamsurface.h:51
auto t0(real_type const u) const
Definition: streamsurface.h:99
std::decay_t< Flowmap > flowmap_type
Definition: streamsurface.h:32
seedcurve_type m_seedcurve
Definition: streamsurface.h:49
constexpr auto max_u() const
Definition: streamsurface.h:152
seedcurve_interpolator_type m_seedcurve_interpolator
Definition: streamsurface.h:50
real_type m_min_u
Definition: streamsurface.h:51
auto flowmap() -> auto &
Definition: streamsurface.h:107
line< real_type, num_dimensions()> seedcurve_type
Definition: streamsurface.h:38
auto discretize(Args &&... args)
Definition: streamsurface.h:147
auto distance(vec2 const &uv0, vec2 const &uv1, std::size_t num_samples) const
Definition: streamsurface.h:130
auto sample(vec2 const &uv) const -> vec_type
calculates position of streamsurface
Definition: streamsurface.h:128
typename flowmap_type::real_type real_type
Definition: streamsurface.h:36
static constexpr auto num_dimensions() -> std::size_t
Definition: streamsurface.h:33
type_list_at< this_type, I > at
Definition: type_list.h:269
typename parent_type::template typed_vertex_property_type< T > typed_vertex_property_type
Definition: unstructured_simplicial_grid.h:82
auto at(simplex_handle t) const -> auto
Definition: unstructured_simplicial_grid.h:300
Definition: unstructured_triangular_grid.h:10
auto insert_triangle(Handles const ... handles)
Definition: unstructured_triangular_grid.h:18
typename parent_type::simplex_handle triangle_handle
Definition: unstructured_triangular_grid.h:15