1#ifndef TATOOINE_UNSTRUCTURED_GRID_H
2#define TATOOINE_UNSTRUCTURED_GRID_H
7#include <boost/range.hpp>
8#include <boost/range/adaptor/transformed.hpp>
12template <
typename Real, std::
size_t NumDimensions>
22 static constexpr auto num_dimensions() -> std::size_t {
return NumDimensions; }
25 : boost::iterator_facade<cell_vertex_iterator, vertex_handle,
26 boost::bidirectional_traversal_tag,
36 std::vector<std::size_t>::const_iterator
m_it;
69 std::vector<std::size_t>::const_iterator cell_begin)
72 auto at(std::size_t
const i)
const {
83 for (std::size_t i = 0, j =
size() - 1; i <
size(); j = i++) {
86 if (((xi(1) > x(1)) != (xj(1) > x(1))) &&
87 (x(0) < (xj(0) - xi(0)) * (x(1) - xi(1)) / (xj(1) - xi(1)) + xi(0)))
100 requires(NumDimensions == 2) {
102 using namespace boost;
103 using namespace boost::adaptors;
104 using scalar_list = std::vector<real_type>;
105 using pos_list = std::vector<pos_type>;
112 auto accumulated_vertex_weights =
real_type(0);
115 auto distances_to_vertices = scalar_list(
num_vertices, 0);
116 auto direction_to_vertices = pos_list(
num_vertices, {0, 0});
119 auto previous_index = [
num_vertices](
auto const i) -> std::size_t {
123 auto next_index = [
num_vertices](
auto const i) -> std::size_t {
131 auto indexed_with_neighbors = [&](
auto&& f) ->
decltype(
auto) {
132 return [&f, i = std::size_t(0), &previous_index,
133 &next_index]()
mutable ->
decltype(
auto) {
134 decltype(
auto) ret_val = f(previous_index(i), i, next_index(i));
142 auto indexed = [&](
auto&& f) ->
decltype(
auto) {
143 return [&f, i = std::size_t(0)]()
mutable ->
decltype(
auto) {
144 decltype(
auto) return_value = f(i);
150 auto calculate_weight_of_vertex = [&distances_to_vertices,
152 &dot_products](
auto const prev_idx,
154 auto const next_idx) {
156 if (std::abs(triangle_areas[prev_idx]) > eps) {
157 weight += (distances_to_vertices[prev_idx] -
158 dot_products[prev_idx] / distances_to_vertices[cur_idx]) /
159 triangle_areas[prev_idx];
161 if (std::abs(triangle_areas[cur_idx]) > eps) {
162 weight += (distances_to_vertices[next_idx] -
163 dot_products[cur_idx] / distances_to_vertices[cur_idx]) /
164 triangle_areas[cur_idx];
169 auto calculate_and_accumulate_vertex_weight =
170 [&accumulated_vertex_weights, &calculate_weight_of_vertex](
171 auto const prev_idx,
auto const cur_idx,
auto const next_idx) {
173 calculate_weight_of_vertex(prev_idx, cur_idx, next_idx);
174 accumulated_vertex_weights += weight;
178 auto calculate_direction_to_vertex = [
this, &query_point](
auto const i) {
184 generate(direction_to_vertices, indexed(calculate_direction_to_vertex));
189 auto const next_idx = next_index(i);
190 distances_to_vertices[i] = length(direction_to_vertices[i]);
191 if (std::abs(distances_to_vertices[i]) <= eps) {
192 vertex_weights[i] = 1;
193 return vertex_weights;
196 (direction_to_vertices[i](0) * direction_to_vertices[next_idx](1) -
197 direction_to_vertices[i](1) * direction_to_vertices[next_idx](0)) /
200 dot(direction_to_vertices[i], direction_to_vertices[next_idx]);
202 if (std::abs(triangle_areas[i]) <= eps && dot_products[i] <= eps) {
203 distances_to_vertices[next_idx] =
204 length(direction_to_vertices[next_idx]);
206 1 / (distances_to_vertices[i] + distances_to_vertices[next_idx]);
207 vertex_weights[i] = distances_to_vertices[next_idx] *
norm;
208 vertex_weights[next_idx] = distances_to_vertices[i] *
norm;
209 return vertex_weights;
214 generate(vertex_weights,
215 indexed_with_neighbors(calculate_and_accumulate_vertex_weight));
218 auto normalize_w = [inverse_accumulated_weights =
219 1 / accumulated_vertex_weights](
auto& w) {
220 return w * inverse_accumulated_weights;
222 copy(vertex_weights | transformed(normalize_w), vertex_weights.begin());
223 return vertex_weights;
228 : boost::iterator_facade<cell_iterator, cell,
229 boost::forward_traversal_tag, cell const&> {
266 template <
typename T>
268 :
field<barycentric_coordinates_vertex_property_sampler_t<T>, Real,
269 parent_t::num_dimensions(), T> {
290 for (std::size_t i = 0; i < b.size(); ++i) {
296 return T{Real(0) / Real(0)};
300 using parent_t::vertex_data;
314 auto edges_per_vertex =
316 std::unordered_set<
typename edgeset<
317 Real, NumDimensions>::edge_handle>> {}
318 for (
auto e : edges.edges()) {
319 auto [v0, v1] = edges[e];
320 edges_per_vertex[v0].insert(e);
321 edges_per_vertex[v1].insert(e);
324 auto const& es = edges_per_vertex.
at(v);
325 if (es.size() >= 2) {
326 for (
auto e1_it =
begin(es), e1_it !=
end(es); ++e1_it) {
327 auto const e1 = *e1_it;
328 auto const [e1v0, e1v1] = edges[e1];
329 for (
auto e0_it =
next(e1_it), e0_it !=
end(es); ++e0_it) {
330 auto const e0 = *e0_it;
331 auto const [e0v0, e0v1] = edges[e0];
340 template <
typename... Handles>
342 (
sizeof...(Handles) > 2) &&
343 ((is_integral<Handles> || is_same<Handles, vertex_handle>)&&...)) {
346 [
this](
auto const h) {
347 using handle_t = std::decay_t<
decltype(h)>;
348 if constexpr (is_same<vertex_handle, handle_t>) {
350 }
else if constexpr (is_integral<handle_t>) {
365 using boost::adaptors::transformed;
367 copy(handles | transformed([](
auto const handle) {
return handle.
i; }),
377 auto write(filesystem::path
const& path)
const {
378 if (path.extension() ==
".vtk") {
382 throw std::runtime_error{
383 "[unstructured_grid::write()]\n unknown file extension: " +
384 path.extension().string()};
387 template <
typename T,
typename... Ts,
typename Prop,
typename Name,
390 Writer& writer)
const {
391 if (prop->type() ==
typeid(T)) {
392 auto const& casted_prop = *
dynamic_cast<
394 writer.write_scalars(name, casted_prop.data());
397 if constexpr (
sizeof...(Ts) > 0) {
404 using boost::make_iterator_range;
405 using boost::adaptors::transformed;
408 if (writer.is_open()) {
409 writer.set_title(
"");
410 writer.write_header();
412 auto three_dims = [
this](
auto const handle) {
416 auto v3s = std::vector<vec<Real, 3>>(
vertices().size());
418 writer.write_points(v3s);
421 writer.write_points(vertex_data());
424 std::vector<std::vector<std::size_t>> vertices_per_cell;
426 std::vector<vtk::cell_type> cell_types(
cells().
size(),
429 auto const num_vertices_of_cell =
cell.
size();
430 auto& polygon = vertices_per_cell.emplace_back();
431 polygon.reserve(num_vertices_of_cell);
433 std::back_inserter(polygon));
435 writer.write_cells(vertices_per_cell);
436 writer.write_cell_types(cell_types);
452 template <
typename T>
457 template <
typename T>
459 return sampler<T>(this->
template vertex_property<T>(name));
463template <std::
size_t NumDimensions>
465template <std::
size_t NumDimensions>
467template <std::
size_t NumDimensions>
Definition: grid_edge.h:16
Definition: vtk_legacy.h:448
Definition: algorithm.h:6
VecF< 3 > vec3f
Definition: vec_typedefs.h:40
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto advance(Iter &iter)
Definition: iterator_facade.h:360
auto end(Range &&range)
Definition: iterator_facade.h:322
VecD< 3 > vec3d
Definition: vec_typedefs.h:51
constexpr auto norm(base_tensor< Tensor, T, N > const &t, unsigned p=2) -> T
Definition: norm.h:23
VecD< 2 > vec2d
Definition: vec_typedefs.h:50
VecF< 4 > vec4f
Definition: vec_typedefs.h:41
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
constexpr auto dot(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: tensor_operations.h:120
auto next(Iter iter)
Definition: iterator_facade.h:325
auto prev(Iter iter)
Definition: iterator_facade.h:343
VecF< 2 > vec2f
Definition: vec_typedefs.h:39
vec_type pos_type
Definition: axis_aligned_bounding_box.h:109
Definition: vertex_handle.h:10
Int i
Definition: handle.h:21
auto vertex_properties() const -> auto const &
Definition: line.h:450
Definition: pointset.h:83
Definition: pointset.h:69
auto num_vertices() const
Definition: pointset.h:229
auto at(vertex_handle const v) -> auto &
Definition: pointset.h:198
auto vertices() const
Definition: pointset.h:226
auto vertex_properties() const -> auto const &
Definition: pointset.h:191
type_list_at< this_type, I > at
Definition: type_list.h:269
Definition: unstructured_grid.h:269
vertex_property_t< T > const & m_prop
Definition: unstructured_grid.h:275
auto grid() const -> auto const &
Definition: unstructured_grid.h:282
barycentric_coordinates_vertex_property_sampler_t(grid_t const &grid, vertex_property_t< T > const &prop)
Definition: unstructured_grid.h:278
auto evaluate(pos_type const &x, real_type const) const -> T
Definition: unstructured_grid.h:285
grid_t const & m_grid
Definition: unstructured_grid.h:274
auto property() const -> auto const &
Definition: unstructured_grid.h:283
Definition: unstructured_grid.h:248
auto end() const
Definition: unstructured_grid.h:259
auto begin() const
Definition: unstructured_grid.h:255
grid_t const * m_grid
Definition: unstructured_grid.h:253
auto size() const
Definition: unstructured_grid.h:263
Definition: unstructured_grid.h:229
auto equal(cell_iterator const &other) const
Definition: unstructured_grid.h:242
cell_iterator(cell_iterator const &other)
Definition: unstructured_grid.h:233
auto dereference() const -> auto const &
Definition: unstructured_grid.h:245
cell_iterator(cell c)
Definition: unstructured_grid.h:232
auto increment()
Definition: unstructured_grid.h:240
friend class boost::iterator_core_access
Definition: unstructured_grid.h:238
cell m_cell
Definition: unstructured_grid.h:236
Definition: unstructured_grid.h:27
auto equal(cell_vertex_iterator const &other) const
Definition: unstructured_grid.h:43
auto decrement()
Definition: unstructured_grid.h:41
auto dereference() const
Definition: unstructured_grid.h:46
cell_vertex_iterator(cell_vertex_iterator const &other)
Definition: unstructured_grid.h:32
std::vector< std::size_t >::const_iterator m_it
Definition: unstructured_grid.h:36
friend class boost::iterator_core_access
Definition: unstructured_grid.h:38
cell_vertex_iterator(std::vector< std::size_t >::const_iterator it)
Definition: unstructured_grid.h:30
auto increment()
Definition: unstructured_grid.h:40
Definition: unstructured_grid.h:49
cell(grid_t const *grid, std::vector< std::size_t >::const_iterator cell_begin)
Definition: unstructured_grid.h:68
auto end() const
Definition: unstructured_grid.h:77
auto size() const
Definition: unstructured_grid.h:71
auto begin() const
Definition: unstructured_grid.h:76
cell_vertex_iterator iterator
Definition: unstructured_grid.h:54
auto barycentric_coordinates(pos_type const &query_point) const
Computes generalized barycentric coordinates for arbitrary polygons.
Definition: unstructured_grid.h:99
std::vector< std::size_t >::const_iterator m_cell_begin
Definition: unstructured_grid.h:65
auto at(std::size_t const i) const
Definition: unstructured_grid.h:72
auto is_inside(pos_type const &x) const
Definition: unstructured_grid.h:81
grid_t const * m_grid
Definition: unstructured_grid.h:64
auto operator[](std::size_t const i) const
Definition: unstructured_grid.h:75
Definition: unstructured_grid.h:13
std::size_t m_num_cells
Definition: unstructured_grid.h:307
unstructured_grid()
Definition: unstructured_grid.h:310
auto sampler(vertex_property_t< T > const &prop) const
Definition: unstructured_grid.h:453
unstructured_grid(edgeset< Real, NumDimensions > &&edges)
Definition: unstructured_grid.h:311
auto write_vtk_vertex_property(Prop const &prop, Name const &name, Writer &writer) const
Definition: unstructured_grid.h:389
auto cells() const
Definition: unstructured_grid.h:338
Real real_type
Definition: unstructured_grid.h:17
std::vector< std::size_t > m_cell_indices
Definition: unstructured_grid.h:306
pointset< Real, NumDimensions > parent_t
Definition: unstructured_grid.h:16
auto insert_cell(std::vector< vertex_handle > const &handles)
Definition: unstructured_grid.h:363
auto insert_cell(Handles const ... handles)
Definition: unstructured_grid.h:341
static constexpr auto num_dimensions() -> std::size_t
Definition: unstructured_grid.h:22
typename parent_t::template vertex_property_t< T > vertex_property_t
Definition: unstructured_grid.h:21
auto vertex_property_sampler(std::string const &name) const
Definition: unstructured_grid.h:458
auto write(filesystem::path const &path) const
Definition: unstructured_grid.h:377
auto write_vtk(filesystem::path const &path) const
Definition: unstructured_grid.h:402
auto at(simplex_handle t) const -> auto
Definition: unstructured_simplicial_grid.h:300
std::map< std::string, data_array > vertices
Definition: piece.h:26