1#ifndef TATOOINE_RECTILINEAR_GRID_H
2#define TATOOINE_RECTILINEAR_GRID_H
17#if TATOOINE_HDF5_AVAILABLE
36template <floating_point_range... Dimensions>
37 requires(
sizeof...(Dimensions) > 1)
40 static constexpr bool is_uniform =
41 (is_linspace<std::decay_t<Dimensions>> && ...);
43 return sizeof...(Dimensions);
51 template <std::
size_t I>
65 template <
typename ValueType,
bool HasNonConstReference = false>
68 this_type, ValueType, HasNonConstReference>;
69 template <
typename Container>
75 std::invoke_result_t<F, decltype(((void)std::declval<Dimensions>(),
76 std::declval<std::size_t>()))...>;
82 mutable std::mutex m_finite_difference_coefficients_mutex = {};
90 m_finite_difference_coefficients = {};
91 std::size_t m_chunk_size_for_lazy_properties = 2;
99 : m_dimensions{other.m_dimensions},
100 m_finite_difference_coefficients{
101 other.m_finite_difference_coefficients} {
103 auto &emplaced_prop =
104 m_vertex_properties.emplace(name, prop->clone()).first->second;
105 emplaced_prop->set_grid(*
this);
111 : m_dimensions{std::move(other.m_dimensions)},
112 m_vertex_properties{std::move(other.m_vertex_properties)},
113 m_finite_difference_coefficients{
114 std::move(other.m_finite_difference_coefficients)} {
115 for (
auto const &[name, prop] : m_vertex_properties) {
116 prop->set_grid(*
this);
121 template <floating_point_range... Dimensions_>
123 requires(
sizeof...(Dimensions_) ==
sizeof...(Dimensions))
124 : m_dimensions{std::forward<Dimensions_>(dimensions)...} {}
127 template <
typename Real, integral... Res, std::size_t... Seq>
130 std::index_sequence<Seq...> , Res
const... res)
133 static_cast<std::size_t
>(res)}...} {}
139 template <
typename Real, integral... Res>
140 requires(
sizeof...(Res) == num_dimensions())
151 linspace{0.0, 1.0, static_cast<std::size_t>(
size)}...} {
152 assert(((
size >= 0) && ...));
161 template <std::size_t... Ds>
170 return copy_without_properties(
171 std::make_index_sequence<num_dimensions()>{});
178 m_dimensions = std::move(other.m_dimensions);
179 m_vertex_properties = std::move(other.m_vertex_properties);
180 m_finite_difference_coefficients =
181 std::move(other.m_finite_difference_coefficients);
182 for (
auto const &[name, prop] : m_vertex_properties) {
183 prop->set_grid(*
this);
185 for (
auto const &[name, prop] : other.m_vertex_properties) {
186 prop->set_grid(other);
192 template <std::
size_t I>
193 requires(I < num_dimensions())
195 return m_dimensions.template at<I>();
202 constexpr auto dimension(std::size_t
const i)
const ->
auto const &
203 requires(
is_same<Dimensions...>) && (num_dimensions() <= 11)
206 return dimension<0>();
208 if constexpr (num_dimensions() > 1) {
210 return dimension<1>();
213 if constexpr (num_dimensions() > 2) {
215 return dimension<2>();
218 if constexpr (num_dimensions() > 3) {
220 return dimension<3>();
223 if constexpr (num_dimensions() > 4) {
225 return dimension<4>();
228 if constexpr (num_dimensions() > 5) {
230 return dimension<5>();
233 if constexpr (num_dimensions() > 6) {
235 return dimension<6>();
238 if constexpr (num_dimensions() > 7) {
240 return dimension<7>();
243 if constexpr (num_dimensions() > 8) {
245 return dimension<8>();
248 if constexpr (num_dimensions() > 9) {
250 return dimension<9>();
253 if constexpr (num_dimensions() > 10) {
255 return dimension<10>();
258 return dimension<0>();
262 constexpr auto dimensions() const -> auto const & {
return m_dimensions; }
265 template <std::size_t... Seq>
266 constexpr auto min(std::index_sequence<Seq...> )
const {
268 static_cast<real_type>(dimension<Seq>().front())...};
276 template <std::size_t... Seq>
277 constexpr auto max(std::index_sequence<Seq...> )
const {
279 static_cast<real_type>(dimension<Seq>().back())...};
287 template <std::
size_t I>
constexpr auto extent()
const {
288 return dimension<I>().back() - dimension<I>().front();
293 template <std::size_t... Is>
294 constexpr auto extent(std::index_sequence<Is...> )
const {
295 return vec{extent<Is>()...};
301 return extent(std::make_index_sequence<num_dimensions()>{});
306 template <std::
size_t DimensionIndex>
307 constexpr auto extent(std::size_t
const cell_index)
const {
308 auto const &dim = dimension<DimensionIndex>();
309 return dim[cell_index + 1] - dim[cell_index];
312 template <std::
size_t I>
constexpr auto center()
const {
313 return (dimension<I>().
back() + dimension<I>().
front()) / 2;
317 template <std::size_t... Is>
318 constexpr auto center(std::index_sequence<Is...> )
const {
319 return vec{center<Is>()...};
324 return center(std::make_index_sequence<num_dimensions()>{});
329 template <std::size_t... Seq>
330 requires(
sizeof...(Seq) == num_dimensions())
334 static_cast<real_type>(dimension<Seq>().front())...},
336 static_cast<real_type>(dimension<Seq>().back())...}};
345 template <std::size_t... Seq>
346 requires(
sizeof...(Seq) == num_dimensions())
347 constexpr auto size(std::index_sequence<Seq...> )
const {
348 return std::array{size<Seq>()...};
357 template <std::
size_t I>
constexpr auto size()
const {
358 return dimension<I>().size();
364 constexpr auto size(std::size_t
const i)
const {
368 if constexpr (num_dimensions() > 1) {
373 if constexpr (num_dimensions() > 2) {
378 if constexpr (num_dimensions() > 3) {
383 if constexpr (num_dimensions() > 4) {
388 if constexpr (num_dimensions() > 5) {
393 if constexpr (num_dimensions() > 6) {
398 if constexpr (num_dimensions() > 7) {
403 if constexpr (num_dimensions() > 8) {
408 if constexpr (num_dimensions() > 9) {
413 if constexpr (num_dimensions() > 10) {
418 return std::numeric_limits<std::size_t>::max();
423 for (
auto &[name, prop] : vertex_properties()) {
424 prop->resize(
size());
431 template <std::
size_t I>
433 m_finite_difference_coefficients.clear();
434 m_dimensions.template at<I>() = std::forward<decltype(dim)>(dim);
435 resize_vertex_properties();
440 m_finite_difference_coefficients.clear();
441 auto &dim = m_dimensions.template at<I>();
442 if constexpr (
is_linspace<std::decay_t<
decltype(dim)>>) {
445 dim.push_back(dimension<I>().back() + extent<I>(size<I>() - 2));
447 resize_vertex_properties();
451 template <std::
size_t I>
452 requires requires(dimension_type<I> dim) { dim.pop_back(); }
454 m_finite_difference_coefficients.clear();
455 m_dimensions.template at<I>().pop_back();
456 resize_vertex_properties();
460 template <std::
size_t I>
461 requires requires(dimension_type<I> dim) { dim.pop_back(); }
463 m_finite_difference_coefficients.clear();
464 m_dimensions.template at<I>().pop_front();
465 resize_vertex_properties();
470 template <
arithmetic... Comps, std::size_t... Seq>
471 requires(num_dimensions() ==
sizeof...(Comps))
472 constexpr auto is_inside(std::index_sequence<Seq...> ,
473 Comps const... comps)
const {
474 return ((dimension<Seq>().front() <= comps &&
475 comps <= dimension<Seq>().back()) &&
482 requires(num_dimensions() ==
sizeof...(Comps))
483 constexpr auto is_inside(Comps const... comps)
const {
484 return is_inside(std::make_index_sequence<num_dimensions()>{}, comps...);
489 template <std::size_t... Seq>
491 std::index_sequence<Seq...> )
const {
492 return ((dimension<Seq>().
front() <= p(Seq) &&
493 p(Seq) <= dimension<Seq>().
back()) &&
500 return is_inside(p, std::make_index_sequence<num_dimensions()>{});
505 template <std::size_t... Seq>
507 std::index_sequence<Seq...> )
const {
508 return is_inside(p[Seq]...);
520 template <std::
size_t DimensionIndex>
522 -> std::pair<std::size_t, real_type> {
523 auto const &dim = dimension<DimensionIndex>();
524 using dim_value_type =
value_type<std::decay_t<
decltype(dim)>>;
525 if (std::abs(x - dim.front()) < 1e-10) {
528 if (std::abs(x - dim.back()) < 1e-10) {
531 if constexpr (
is_linspace<std::decay_t<
decltype(dim)>>) {
533 auto pos = (x - dim.front()) / (dim.back() - dim.front()) *
534 static_cast<dim_value_type
>((dim.size() - 1));
535 auto quantized_pos =
static_cast<std::size_t
>(std::floor(pos));
536 if (quantized_pos == dim.size() - 1) {
539 auto cell_position = pos -
static_cast<dim_value_type
>(quantized_pos);
540 if (quantized_pos == dim.size() - 1) {
544 return {quantized_pos, cell_position};
547 std::size_t left = 0;
548 std::size_t right = dim.size() - 1;
549 while (right - left > 1) {
550 auto const center = (right + left) / 2;
551 if (x < dim[center]) {
557 return {left, (x - dim[left]) / (dim[left + 1] - dim[left])};
563 template <std::size_t... DimensionIndex>
566 -> std::array<std::pair<std::size_t, double>, num_dimensions()> {
567 return std::array{cell_index<DimensionIndex>(
static_cast<double>(xs))...};
572 requires(
sizeof...(xs) == num_dimensions())
579 [
this](
auto const... xs) {
return cell_index(xs...); },
580 unpack(std::forward<
decltype(xs)>(xs)));
584 std::size_t
const dim_index,
585 std::size_t
const i)
const {
587 auto lock = std::lock_guard{m_finite_difference_coefficients_mutex};
588 if (stencil_size > m_finite_difference_coefficients.size()) {
589 create_finite_differences_coefficients(stencil_size);
593 begin(m_finite_difference_coefficients[stencil_size - 1][dim_index]);
594 return std::ranges::subrange{beg + stencil_size * i,
595 beg + stencil_size * (i + 1)};
605 using namespace std::ranges;
606 if (m_finite_difference_coefficients.size() < stencil_size) {
607 m_finite_difference_coefficients.resize(stencil_size);
609 auto &stencil_per_size = m_finite_difference_coefficients[stencil_size - 1];
611 auto const half_stencil_size = stencil_size / 2;
612 auto local_positions = std::vector<real_type>(stencil_size);
614 auto foreach_dim = [&, dim_idx = std::size_t{}](
auto const &dim)
mutable {
615 auto stencil_begin =
begin(dim);
616 auto stencil_end =
next(
begin(dim), stencil_size);
617 assert(stencil_size <= dim.size());
618 for (
auto it =
begin(dim); it !=
end(dim); ++it) {
619 auto &stencil_per_dim = stencil_per_size[dim_idx];
620 auto distance_to_center = [&it](
auto const &x) {
return x - *it; };
622 1, subrange{stencil_begin, stencil_end} |
623 views::transform(distance_to_center)),
624 std::back_inserter(stencil_per_dim));
626 static_cast<long>(half_stencil_size) &&
627 stencil_end !=
end(dim)) {
634 m_dimensions.iterate(foreach_dim);
639 template <std::size_t... DIs,
integral Int>
641 std::array<Int, num_dimensions()>
const &is)
const
646 template <std::size_t... DIs>
649 static_assert(
sizeof...(DIs) ==
sizeof...(is));
650 static_assert(
sizeof...(is) == num_dimensions());
655 static_assert(
sizeof...(is) == num_dimensions());
659 template <
integral Int>
660 auto vertex_at(std::array<Int, num_dimensions()>
const &is)
const {
673 requires(
sizeof...(is) == num_dimensions())
675 auto const arr_is = std::array{is...};
677 auto pi = std::size_t{};
679 for (std::size_t i = 0; i <
sizeof...(is); ++i) {
680 pi += arr_is[i] * multiplier;
681 multiplier *=
size[i];
689 template <std::size_t... Is>
691 std::index_sequence<Is...> )
const {
693 std::decay_t<
decltype(additional_dimension)>>{
695 std::forward<decltype(additional_dimension)>(additional_dimension)};
700 return add_dimension(
701 std::forward<
decltype(additional_dimension)>(additional_dimension),
706 return m_vertex_properties.find(name) !=
end(m_vertex_properties);
710 if (
auto it = m_vertex_properties.find(name);
711 it !=
end(m_vertex_properties)) {
712 m_vertex_properties.erase(it);
717 std::string
const &new_name) ->
void {
718 if (
auto it = m_vertex_properties.find(current_name);
719 it !=
end(m_vertex_properties)) {
720 auto handler = m_vertex_properties.extract(it);
721 handler.key() = new_name;
722 m_vertex_properties.insert(std::move(handler));
726 template <
typename Container,
typename... Args>
729 if (!has_vertex_property(name)) {
731 *
this, std::forward<Args>(args)...};
732 m_vertex_properties.emplace(
733 name, std::unique_ptr<vertex_property_type>{new_prop});
734 if constexpr (
sizeof...(Args) == 0) {
739 throw std::runtime_error{
"There is already a vertex property named \"" +
746 template <
typename T,
typename IndexOrder = x_fastest>
748 return insert_contiguous_vertex_property<T, IndexOrder>(name);
751 template <
typename IndexOrder = x_fastest>
753 return insert_vertex_property<tatooine::real_number, IndexOrder>(name);
756 template <
typename IndexOrder = x_fastest>
758 return insert_vertex_property<vec2, IndexOrder>(name);
761 template <
typename IndexOrder = x_fastest>
763 return insert_vertex_property<vec3, IndexOrder>(name);
766 template <
typename IndexOrder = x_fastest>
768 return insert_vertex_property<vec4, IndexOrder>(name);
771 template <
typename IndexOrder = x_fastest>
773 return insert_vertex_property<mat2, IndexOrder>(name);
776 template <
typename IndexOrder = x_fastest>
778 return insert_vertex_property<mat3, IndexOrder>(name);
781 template <
typename IndexOrder = x_fastest>
783 return insert_vertex_property<mat4, IndexOrder>(name);
788 template <
typename T,
typename IndexOrder = x_fastest>
790 return create_vertex_property<dynamic_multidim_array<T, IndexOrder>>(
794 template <
typename T,
typename IndexOrder = x_fastest>
797 std::vector<std::size_t>
const &chunk_size)
799 return create_vertex_property<chunked_multidim_array<T, IndexOrder>>(
800 name,
size(), chunk_size);
803 template <
typename T,
typename IndexOrder = x_fastest>
805 std::string
const &name,
806 std::array<std::size_t, num_dimensions()>
const &chunk_size) ->
auto & {
807 return create_vertex_property<chunked_multidim_array<T, IndexOrder>>(
808 name,
size(), chunk_size);
811 template <
typename T,
typename IndexOrder = x_fastest>
816 requires(
sizeof...(chunk_size) == num_dimensions())
818 return create_vertex_property<chunked_multidim_array<T, IndexOrder>>(
820 std::vector<std::size_t>{
static_cast<std::size_t
>(chunk_size)...});
823 template <
typename T,
typename IndexOrder = x_fastest>
825 return create_vertex_property<chunked_multidim_array<T, IndexOrder>>(
826 name,
size(), make_array<num_dimensions()>(std::size_t(10)));
830 template <
typename T,
bool HasNonConstReference = true>
833 if (
auto it = m_vertex_properties.find(name);
834 it ==
end(m_vertex_properties)) {
835 return insert_vertex_property<T>(name);
837 if (
typeid(T) != it->second->type()) {
838 throw std::runtime_error{
"type of property \"" + name +
"\"(" +
840 ") does not match specified type " +
841 type_name<T>() +
"."};
843 return *
dynamic_cast<
849 template <
typename T,
bool HasNonConstReference = true>
852 if (
auto it = m_vertex_properties.find(name);
853 it ==
end(m_vertex_properties)) {
854 throw std::runtime_error{
"property \"" + name +
"\" not found"};
856 if (
typeid(T) != it->second->type()) {
857 throw std::runtime_error{
"type of property \"" + name +
"\"(" +
859 ") does not match specified type " +
860 type_name<T>() +
"."};
863 T, HasNonConstReference
> const *>(it->second.get());
867 template <
bool HasNonConstReference = true>
869 return vertex_property<tatooine::real_number, HasNonConstReference>(name);
872 template <
bool HasNonConstReference = true>
874 return vertex_property<tatooine::real_number, HasNonConstReference>(name);
877 template <
bool HasNonConstReference = true>
879 return vertex_property<vec2, HasNonConstReference>(name);
882 template <
bool HasNonConstReference = true>
884 return vertex_property<vec2, HasNonConstReference>(name);
887 template <
bool HasNonConstReference = true>
889 return vertex_property<vec3, HasNonConstReference>(name);
892 template <
bool HasNonConstReference = true>
894 return vertex_property<vec3, HasNonConstReference>(name);
897 template <
bool HasNonConstReference = true>
899 return vertex_property<vec4, HasNonConstReference>(name);
902 template <
bool HasNonConstReference = true>
904 return vertex_property<vec4, HasNonConstReference>(name);
907 template <
bool HasNonConstReference = true>
909 return vertex_property<mat2, HasNonConstReference>(name);
912 template <
bool HasNonConstReference = true>
914 return vertex_property<mat2, HasNonConstReference>(name);
917 template <
bool HasNonConstReference = true>
919 return vertex_property<mat3, HasNonConstReference>(name);
922 template <
bool HasNonConstReference = true>
924 return vertex_property<mat3, HasNonConstReference>(name);
927 template <
bool HasNonConstReference = true>
929 return vertex_property<mat4, HasNonConstReference>(name);
932 template <
bool HasNonConstReference = true>
934 return vertex_property<mat4, HasNonConstReference>(name);
937 template <
typename T,
typename GlobalIndexOrder =
x_fastest,
938 typename LocalIndexOrder = GlobalIndexOrder>
940 std::string
const &dataset_name)
942 auto const ext = path.extension();
943#if TATOOINE_HDF5_AVAILABLE
945 return insert_hdf5_lazy_vertex_property<T, GlobalIndexOrder,
946 LocalIndexOrder>(path,
950#ifdef TATOOINE_NETCDF_AVAILABLE
952 return insert_netcdf_lazy_vertex_property<T, GlobalIndexOrder,
953 LocalIndexOrder>(path,
957 throw std::runtime_error{
958 "[rectilinear_grid::insert_lazy_vertex_property] - unknown file "
962#if TATOOINE_HDF5_AVAILABLE
963 template <
typename IndexOrder = x_fastest,
typename T>
965 return insert_vertex_property<IndexOrder>(dataset, dataset.name());
968 template <
typename IndexOrder = x_fastest,
typename T>
970 std::string
const &name) ->
auto & {
971 auto num_dims_dataset = dataset.num_dimensions();
972 if (num_dimensions() != num_dims_dataset) {
973 throw std::runtime_error{
"Number of dimensions(" +
974 std::to_string(num_dims_dataset) +
975 ") do not match for HDF5 dataset and "
976 "rectilinear_grid(" +
977 std::to_string(num_dimensions()) +
")."};
979 auto size_dataset = dataset.size();
980 for (std::size_t i = 0; i < num_dimensions(); ++i) {
981 if (size_dataset[i] !=
size(i)) {
982 std::stringstream ss;
983 ss <<
"Resolution of rectilinear_grid and HDF5 DataSet do not match. "
986 for (std::size_t i = 1; i < num_dimensions(); ++i) {
987 ss <<
", " <<
size(i);
989 ss <<
") and hdf5 dataset(" << size_dataset[i];
990 for (std::size_t i = 1; i < num_dimensions(); ++i) {
991 ss <<
", " << size_dataset[i];
994 throw std::runtime_error{ss.str()};
997 auto &prop = insert_vertex_property<T, IndexOrder>(name);
1002 template <
typename T,
typename GlobalIndexOrder =
x_fastest,
1003 typename LocalIndexOrder = GlobalIndexOrder>
1005 std::string
const &dataset_name)
1008 return insert_lazy_vertex_property<GlobalIndexOrder, LocalIndexOrder>(
1009 f.dataset<T>(dataset_name));
1012 template <
typename GlobalIndexOrder =
x_fastest,
1013 typename LocalIndexOrder = GlobalIndexOrder,
typename T>
1015 return insert_lazy_vertex_property<GlobalIndexOrder, LocalIndexOrder>(
1016 dataset, dataset.name());
1019 template <
typename GlobalIndexOrder =
x_fastest,
1020 typename LocalIndexOrder = GlobalIndexOrder,
typename T>
1022 std::string
const &name) ->
auto & {
1023 auto num_dims_dataset = dataset.num_dimensions();
1024 if (num_dimensions() != num_dims_dataset) {
1025 throw std::runtime_error{
1026 "Number of dimensions do not match for HDF5 dataset and "
1027 "rectilinear_grid."};
1029 auto size_dataset = dataset.size();
1030 for (std::size_t i = 0; i < num_dimensions(); ++i) {
1031 if (size_dataset[i] !=
size(i)) {
1032 std::stringstream ss;
1033 ss <<
"Resolution of rectilinear_grid and HDF5 DataSet (\"" << name
1034 <<
"\")do not match. rectilinear_grid(" <<
size(0);
1035 for (std::size_t i = 1; i < num_dimensions(); ++i) {
1036 ss <<
", " <<
size(i);
1038 ss <<
") and hdf5 dataset(" << size_dataset[i];
1039 for (std::size_t i = 1; i < num_dimensions(); ++i) {
1040 ss <<
", " << size_dataset[i];
1043 throw std::runtime_error{ss.str()};
1046 return create_vertex_property<
1049 std::vector<std::size_t>(num_dimensions(),
1050 m_chunk_size_for_lazy_properties));
1053#ifdef TATOOINE_NETCDF_AVAILABLE
1055 template <
typename T,
typename GlobalIndexOrder =
x_fastest,
1056 typename LocalIndexOrder = GlobalIndexOrder>
1058 std::string
const &dataset_name)
1061 return insert_lazy_vertex_property<GlobalIndexOrder, LocalIndexOrder, T>(
1062 f.variable<T>(dataset_name));
1065 template <
typename GlobalIndexOrder =
x_fastest,
1066 typename LocalIndexOrder = GlobalIndexOrder,
typename T>
1069 return create_vertex_property<
1071 dataset.name(), dataset,
1072 std::vector<std::size_t>(num_dimensions(),
1073 m_chunk_size_for_lazy_properties));
1077 template <
typename F>
1082 return sample_to_vertex_property(std::forward<F>(f), name,
1086 template <
typename F>
1093 return sample_to_vertex_property_pos(std::forward<F>(f), name, tag);
1095 return sample_to_vertex_property_indices(
1096 std::forward<F>(f), name, tag,
1097 std::make_index_sequence<num_dimensions()>{});
1102 template <invocable_with_n_
integrals<num_dimensions()> F, std::
size_t... Is>
1105 std::index_sequence<Is...> )
1107 using T = std::invoke_result_t<F,
decltype(Is)...>;
1108 auto &prop = vertex_property<T>(name);
1110 [&](
auto const... is) {
1112 prop(is...) = f(is...);
1113 }
catch (std::exception &) {
1114 if constexpr (tensor_num_components<T> == 1) {
1115 prop(is...) = nan<T>();
1125 template <invocable<pos_type> F>
1128 using invoke_result = std::decay_t<std::invoke_result_t<F, pos_type>>;
1129 auto &prop = vertex_property<invoke_result>(name);
1131 [&](
auto const... is) {
1133 prop(is...) = f(
vertices()(is...));
1134 }
catch (std::exception &) {
1135 if constexpr (tensor_num_components<invoke_result> == 1) {
1138 prop(is...) = invoke_result::fill(
1148 auto read(filesystem::path
const &path) {
1149#ifdef TATOOINE_NETCDF_AVAILABLE
1150 if constexpr (!is_uniform) {
1151 if (path.extension() ==
".nc") {
1157 if constexpr (num_dimensions() == 2 || num_dimensions() == 3) {
1158 if (path.extension() ==
".vtk") {
1162 if constexpr (is_uniform) {
1163 if (path.extension() ==
".am") {
1169 throw std::runtime_error{
1170 "[rectilinear_grid::read] Unknown file extension."};
1178 : gr{gr_}, is_structured_points{is_structured_points_}, spacing{
1182 if (t == vtk::dataset_type::structured_points && !is_uniform) {
1183 is_structured_points =
true;
1188 auto on_origin(
double x,
double y,
double z) ->
void override {
1191 if (num_dimensions() < 3 && z > 1) {
1192 throw std::runtime_error{
1193 "[rectilinear_grid::read_vtk] number of dimensions is < 3 but got "
1197 if constexpr (num_dimensions() > 3) {
1202 spacing = {x, y, z};
1208 if (num_dimensions() < 3 && z > 1) {
1209 throw std::runtime_error{
1210 "[rectilinear_grid::read_vtk] number of dimensions is < 3 but got "
1214 if constexpr (num_dimensions() > 2) {
1229 auto on_cells(std::vector<int>
const &) ->
void override {}
1232 auto on_lines(std::vector<int>
const &) ->
void override {}
1238 std::vector<std::array<float, 3>>
const & ,
1241 std::vector<std::array<double, 3>>
const & ,
1244 std::vector<std::array<float, 3>>
const & ,
1247 std::vector<std::array<double, 3>>
const & ,
1250 std::string
const & ,
1251 std::vector<std::array<float, 2>>
const & ,
1254 std::string
const & ,
1255 std::vector<std::array<double, 2>>
const & ,
1258 std::vector<std::array<float, 9>>
const & ,
1261 std::vector<std::array<double, 9>>
const & ,
1264 template <
typename T>
1265 auto insert_prop(std::string
const &prop_name, std::vector<T>
const &data,
1266 std::size_t
const num_components) {
1268 if (num_components == 1) {
1271 [&](
auto const... is) { prop(is...) = data[i++]; });
1273 if (num_components == 2) {
1275 gr.
vertices().iterate_indices([&](
auto const... is) {
1276 prop(is...) = {data[i], data[i + 1]};
1277 i += num_components;
1280 if (num_components == 3) {
1282 gr.
vertices().iterate_indices([&](
auto const... is) {
1283 prop(is...) = {data[i], data[i + 1], data[i + 2]};
1284 i += num_components;
1287 if (num_components == 4) {
1289 gr.
vertices().iterate_indices([&](
auto const... is) {
1290 prop(is...) = {data[i], data[i + 1], data[i + 2], data[i + 3]};
1291 i += num_components;
1296 std::string
const & ,
1297 std::size_t
const num_components,
1300 insert_prop<float>(data_name, data, num_components);
1303 std::string
const & ,
1304 std::size_t
const num_components,
1307 insert_prop<double>(data_name, data, num_components);
1312 std::string
const field_array_name,
1313 std::vector<int>
const &data,
1314 std::size_t num_components, std::size_t )
1316 insert_prop<int>(field_array_name, data, num_components);
1319 std::string
const field_array_name,
1320 std::vector<float>
const &data,
1321 std::size_t num_components, std::size_t )
1323 insert_prop<float>(field_array_name, data, num_components);
1326 std::string
const field_array_name,
1327 std::vector<double>
const &data,
1328 std::size_t num_components, std::size_t )
1330 insert_prop<double>(field_array_name, data, num_components);
1335 requires(num_dimensions() == 2) || (num_dimensions() == 3)
1337 bool is_structured_points =
false;
1339 vtk_listener listener{*
this, is_structured_points, spacing};
1344 if (is_structured_points) {
1345 if constexpr (is_same<std::decay_t<decltype(dimension<0>())>,
1347 dimension<0>().
back() =
1348 dimension<0>().front() + (size<0>() - 1) * spacing(0);
1351 for (
auto &d : dimension<0>()) {
1352 d = dimension<0>().front() + (i++) * spacing(0);
1355 if constexpr (is_same<std::decay_t<decltype(dimension<1>())>,
1357 dimension<1>().
back() =
1358 dimension<1>().front() + (size<1>() - 1) * spacing(1);
1361 for (
auto &d : dimension<1>()) {
1362 d = dimension<1>().front() + (i++) * spacing(1);
1365 if constexpr (num_dimensions() == 3) {
1366 if constexpr (is_same<std::decay_t<decltype(dimension<2>())>,
1368 dimension<2>().
back() =
1369 dimension<2>().front() + (size<2>() - 1) * spacing(2);
1372 for (
auto &d : dimension<2>()) {
1373 d = dimension<2>().front() + (i++) * spacing(2);
1380 auto read_amira(filesystem::path
const &path)
1381 requires is_uniform && ((num_dimensions() == 2) || (num_dimensions() == 3))
1383 auto const reader_data = amira::read<real_type>(path);
1384 auto const &[data, dims,
aabb, num_components] = reader_data;
1385 if (dims[2] == 1 && num_dimensions() == 3) {
1386 throw std::runtime_error{
1387 "[rectilinear_grid::read_amira] file contains 2-dimensional data. "
1388 "Cannot read into 3-dimensional rectilinear_grid"};
1390 if (dims[2] > 1 && num_dimensions() == 2) {
1391 throw std::runtime_error{
1392 "[rectilinear_grid::read_amira] file contains 3-dimensional data. "
1393 "Cannot read into 2-dimensional rectilinear_grid"};
1397 if constexpr (is_linspace<std::decay_t<decltype(dimension<0>())>>) {
1398 dimension<0>().front() =
aabb.min(0);
1399 dimension<0>().back() =
aabb.max(0);
1400 dimension<0>().resize(dims[0]);
1402 auto const uniform_dim =
1403 linspace<double>{
aabb.min(0),
aabb.max(0), dims[0]};
1404 dimension<0>().resize(dims[0]);
1405 std::ranges::copy(uniform_dim,
begin(dimension<0>()));
1407 if constexpr (is_linspace<std::decay_t<decltype(dimension<1>())>>) {
1408 dimension<1>().front() =
aabb.min(1);
1409 dimension<1>().back() =
aabb.max(1);
1410 dimension<1>().resize(dims[1]);
1412 auto const uniform_dim =
1413 linspace<double>{
aabb.min(1),
aabb.max(1), dims[1]};
1414 dimension<1>().resize(dims[1]);
1415 std::ranges::copy(uniform_dim,
begin(dimension<1>()));
1417 if constexpr (num_dimensions() == 3) {
1418 if constexpr (is_linspace<std::decay_t<decltype(dimension<2>())>>) {
1419 dimension<2>().front() =
aabb.min(2);
1420 dimension<2>().back() =
aabb.max(2);
1421 dimension<2>().resize(dims[2]);
1423 auto const uniform_dim =
1424 linspace<double>{
aabb.min(2),
aabb.max(2), dims[2]};
1425 dimension<2>().resize(dims[2]);
1426 std::ranges::copy(uniform_dim,
begin(dimension<2>()));
1430 auto i = std::size_t{};
1431 if (num_components == 1) {
1432 auto &prop = scalar_vertex_property(path.filename().string());
1433 vertices().iterate_indices([&](
auto const... is) {
1434 auto const &data = std::get<0>(reader_data);
1435 prop(is...) = data[i++];
1437 }
else if (num_components == 2) {
1438 auto &prop = vertex_property<vec<real_type, 2>>(path.filename().string());
1439 vertices().iterate_indices([&](
auto const... is) {
1441 prop(is...) = {data[i], data[i + 1]};
1442 i += num_components;
1444 }
else if (num_components == 3) {
1445 auto &prop = vertex_property<vec<real_type, 3>>(path.filename().string());
1446 vertices().iterate_indices([&](
auto const... is) {
1448 prop(is...) = {data[i], data[i + 1], data[i + 2]};
1449 i += num_components;
1454#ifdef TATOOINE_NETCDF_AVAILABLE
1455 auto read_netcdf(filesystem::path
const &path)
1456 requires(!is_uniform)
1458 read_netcdf(path, std::make_index_sequence<num_dimensions()>{});
1461 template <
typename T, std::size_t... Seq>
1462 auto insert_variables_of_type(netcdf::file &f,
bool &first,
1463 std::index_sequence<Seq...> )
1464 requires(!is_uniform)
1466 for (
auto v : f.variables<T>()) {
1467 if (v.name() ==
"x" || v.name() ==
"y" || v.name() ==
"z" ||
1468 v.name() ==
"t" || v.name() ==
"X" || v.name() ==
"Y" ||
1469 v.name() ==
"Z" || v.name() ==
"T" || v.name() ==
"xdim" ||
1470 v.name() ==
"ydim" || v.name() ==
"zdim" || v.name() ==
"tdim" ||
1471 v.name() ==
"Xdim" || v.name() ==
"Ydim" || v.name() ==
"Zdim" ||
1472 v.name() ==
"Tdim" || v.name() ==
"XDim" || v.name() ==
"YDim" ||
1473 v.name() ==
"ZDim" || v.name() ==
"TDim") {
1476 if (v.num_dimensions() != num_dimensions() &&
1477 v.size()[0] !=
vertices().size()) {
1478 throw std::runtime_error{
1479 "[rectilinear_grid::read_netcdf] variable's number of dimensions "
1482 "match rectilinear_grid's number of dimensions:\nnumber of "
1485 std::to_string(num_dimensions()) +
"\nnumber of data dimensions: " +
1486 std::to_string(v.num_dimensions()) +
1487 "\nvariable name: " + v.name()};
1490 auto check = [
this, &v](std::size_t i) {
1491 if (v.size(i) !=
size(i)) {
1492 throw std::runtime_error{
1493 "[rectilinear_grid::read_netcdf] variable's size(" +
1496 "match rectilinear_grid's size(" +
1497 std::to_string(i) +
")"};
1503 typename std::decay_t<decltype(dimension<Seq>())>
::value_type>(
1504 v.dimension_name(Seq))
1505 .
read(dimension<Seq>())),
1509 create_vertex_property<lazy_reader<netcdf::variable<T>>>(
1511 std::vector<std::size_t>(num_dimensions(),
1512 m_chunk_size_for_lazy_properties));
1516 template <std::size_t... Seq>
1517 auto read_netcdf(filesystem::path
const &path,
1518 std::index_sequence<Seq...> seq)
1519 requires(!is_uniform)
1521 netcdf::file f{path, netCDF::NcFile::read};
1523 insert_variables_of_type<double>(f, first, seq);
1524 insert_variables_of_type<float>(f, first, seq);
1525 insert_variables_of_type<int>(f, first, seq);
1529 template <
typename T>
1530 void write_amira(std::string
const &path,
1531 std::string
const &vertex_property_name)
const
1532 requires(num_dimensions() == 3)
1534 write_amira(path, vertex_property<T>(vertex_property_name));
1537 template <
typename T,
bool HasNonConstReference>
1539 std::string
const &path,
1540 typed_vertex_property_interface_type<T, HasNonConstReference>
const &prop)
1542 requires is_uniform && (num_dimensions() == 3)
1544 std::ofstream outfile{path, std::ofstream::binary};
1545 std::stringstream header;
1547 header <<
"# AmiraMesh BINARY-LITTLE-ENDIAN 2.1\n\n";
1548 header <<
"define Lattice " << size<0>() <<
" " << size<1>() <<
" "
1549 << size<2>() <<
"\n\n";
1550 header <<
"Parameters {\n";
1551 header <<
" BoundingBox " << dimension<0>().front() <<
" "
1552 << dimension<0>().back() <<
" " << dimension<1>().front() <<
" "
1553 << dimension<1>().back() <<
" " << dimension<2>().front() <<
" "
1554 << dimension<2>().back() <<
",\n";
1555 header <<
" CoordType \"uniform\"\n";
1557 if constexpr (tensor_num_components < T >> 1) {
1558 header <<
"Lattice { " << type_name<internal_data_type_t<T>>() <<
"["
1559 << tensor_num_components<T> <<
"] Data } @1\n\n";
1561 header <<
"Lattice { " << type_name<internal_data_type_t<T>>()
1562 <<
" Data } @1\n\n";
1564 header <<
"# Data section follows\n@1\n";
1565 auto const header_string = header.str();
1567 std::vector<T> data;
1568 data.reserve(size<0>() * size<1>() * size<2>());
1569 auto back_inserter = [&](
auto const... is) { data.push_back(prop(is...)); };
1570 for_loop(back_inserter, size<0>(), size<1>(), size<2>());
1572 (
char *)header_string.c_str(),
1573 static_cast<std::streamsize
>(header_string.size() *
sizeof(
char)));
1574 outfile.write((
char *)data.data(),
1575 static_cast<std::streamsize
>(data.size() *
sizeof(T)));
1580 auto write(filesystem::path
const &path)
const {
1581 auto const ext = path.extension();
1583 if constexpr (num_dimensions() == 2 || num_dimensions() == 3) {
1584 if (ext ==
".vtk") {
1589 if constexpr (num_dimensions() == 2 || num_dimensions() == 3) {
1590 if (ext ==
".vtr") {
1595#if TATOOINE_HDF5_AVAILABLE
1596 if constexpr (num_dimensions() == 2 || num_dimensions() == 3) {
1598 write_visitvs(path);
1603 throw std::runtime_error{
"Unsupported file extension: \"" + ext.string() +
1609 std::string
const &description =
"tatooine rectilinear_grid") const
1610 requires is_uniform && ((num_dimensions() == 2) || (num_dimensions() == 3))
1614 writer.set_title(description);
1615 writer.write_header();
1616 if constexpr (num_dimensions() == 1) {
1617 writer.write_dimensions(size<0>(), 1, 1);
1618 writer.write_origin(dimension<0>().front(), 0, 0);
1619 writer.write_spacing(dimension<0>().spacing(), 0, 0);
1620 }
else if constexpr (num_dimensions() == 2) {
1621 writer.write_dimensions(size<0>(), size<1>(), 1);
1622 writer.write_origin(dimension<0>().front(), dimension<1>().front(), 0);
1623 writer.write_spacing(dimension<0>().spacing(), dimension<1>().spacing(),
1625 }
else if constexpr (num_dimensions() == 3) {
1626 writer.write_dimensions(size<0>(), size<1>(), size<2>());
1627 writer.write_origin(dimension<0>().front(), dimension<1>().front(),
1628 dimension<2>().front());
1629 writer.write_spacing(dimension<0>().spacing(), dimension<1>().spacing(),
1630 dimension<2>().spacing());
1633 writer.write_point_data(
vertices().size());
1640 std::string
const &description =
"tatooine rectilinear_grid") const
1641 requires(!is_uniform) && ((num_dimensions() == 2) || (num_dimensions() == 3))
1645 writer.set_title(description);
1646 writer.write_header();
1647 if constexpr (num_dimensions() == 1) {
1648 writer.write_dimensions(size<0>(), 1, 1);
1649 writer.write_x_coordinates(
1650 std::vector<double>(
begin(dimension<0>()),
end(dimension<0>())));
1651 writer.write_y_coordinates(std::vector<double>{0});
1652 writer.write_z_coordinates(std::vector<double>{0});
1653 }
else if constexpr (num_dimensions() == 2) {
1654 writer.write_dimensions(size<0>(), size<1>(), 1);
1655 writer.write_x_coordinates(
1656 std::vector<double>(
begin(dimension<0>()),
end(dimension<0>())));
1657 writer.write_y_coordinates(
1658 std::vector<double>(
begin(dimension<1>()),
end(dimension<1>())));
1659 writer.write_z_coordinates(std::vector<double>{0});
1660 }
else if constexpr (num_dimensions() == 3) {
1661 writer.write_dimensions(size<0>(), size<1>(), size<2>());
1662 writer.write_x_coordinates(
1663 std::vector<double>(
begin(dimension<0>()),
end(dimension<0>())));
1664 writer.write_y_coordinates(
1665 std::vector<double>(
begin(dimension<1>()),
end(dimension<1>())));
1666 writer.write_z_coordinates(
1667 std::vector<double>(
begin(dimension<2>()),
end(dimension<2>())));
1670 writer.write_point_data(
vertices().size());
1676 template <
typename T,
bool HasNonConstReference>
1677 auto write_vtk_prop(
1678 vtk::legacy_file_writer &writer, std::string
const &name,
1679 typed_vertex_property_interface_type<T, HasNonConstReference>
const &prop)
1681 auto data = std::vector<T>{};
1683 [&](
auto const... is) { data.push_back(prop(is...)); });
1684 writer.write_scalars(name, data);
1687 template <
typename... Ts>
1688 auto write_vtk_prop(vtk::legacy_file_writer &writer)
const ->
void {
1689 for (
auto const &key_value : this->m_vertex_properties) {
1691 auto const &[
name, prop] = key_value;
1692 if (prop->type() ==
typeid(Ts)) {
1693 write_vtk_prop(writer, name, prop->template cast_to_typed<Ts>());
1700 template <
typename HeaderType = std::u
int64_t>
1701 auto write_vtr(filesystem::path
const &path)
const
1702 requires(num_dimensions() == 2) || (num_dimensions() == 3)
1704 detail::rectilinear_grid::vtr_writer<this_type, HeaderType>{*
this}.write(
1709 auto write_visitvs(filesystem::path
const &path)
const ->
void {
1710 write_visitvs(path, std::make_index_sequence<num_dimensions()>{});
1715#if TATOOINE_HDF5_AVAILABLE
1717 template <
typename T,
bool HasNonConstReference, std::size_t... Is>
1718 void write_prop_hdf5(
1719 hdf5::file &f, std::string
const &name,
1720 typed_vertex_property_interface_type<T, HasNonConstReference>
const &prop,
1721 std::index_sequence<Is...> )
const {
1722 if constexpr (is_arithmetic<T>) {
1723 auto dataset = f.create_dataset<T>(
name, size<Is>()...);
1724 dataset.attribute(
"vsMesh") =
"/rectilinear_grid";
1725 dataset.attribute(
"vsCentering") =
"nodal";
1726 dataset.attribute(
"vsType") =
"variable";
1727 dataset.attribute(
"vsIndexOrder") =
"compMinorF";
1728 auto data = std::vector<T>{};
1731 [&](
auto const... is) { data.push_back(prop(is...)); });
1732 dataset.write(H5S_ALL, H5S_ALL, H5P_DEFAULT, data.data());
1733 }
else if constexpr (static_vec<T>) {
1735 auto g = f.group(name);
1736 auto gg = g.sub_group(name);
1737 std::stringstream ss;
1739 ss <<
"<" +
name +
"/" <<
name <<
"_0>";
1740 for (std::size_t i = 1; i < vec_type::dimension(0); ++i) {
1741 ss <<
",<" +
name +
"/" <<
name <<
"_" << i <<
">";
1744 gg.attribute(name) = ss.str();
1745 gg.attribute(
"vsType") =
"vsVars";
1747 for (std::size_t i = 0; i < vec_type::dimension(0); ++i) {
1748 auto dataset = g.create_dataset<
typename vec_type::value_type>(
1749 name +
"_" + std::to_string(i), size<Is>()...);
1750 dataset.attribute(
"vsMesh") =
"/rectilinear_grid";
1751 dataset.attribute(
"vsCentering") =
"nodal";
1752 dataset.attribute(
"vsType") =
"variable";
1753 dataset.attribute(
"vsIndexOrder") =
"compMinorF";
1754 auto data = std::vector<typename vec_type::value_type>{};
1757 [&](
auto const... is) { data.push_back(prop(is...)(i)); });
1758 dataset.write(H5S_ALL, H5S_ALL, H5P_DEFAULT, data.data());
1763 template <
typename... Ts, std::size_t... Is>
1764 auto write_prop_hdf5_wrapper(hdf5::file &f, std::string
const &name,
1765 vertex_property_type
const &prop,
1766 std::index_sequence<Is...> seq)
const ->
void {
1768 if (prop.type() ==
typeid(Ts)) {
1772 typed_vertex_property_interface_type<Ts, true> const *>(&prop),
1780 template <std::size_t... Is>
1781 auto write_visitvs(filesystem::path
const &path,
1782 std::index_sequence<Is...> seq)
const ->
void {
1783 if (filesystem::exists(path)) {
1784 filesystem::remove(path);
1786 auto f = hdf5::file{path};
1787 auto group = f.group(
"rectilinear_grid");
1789 auto axis_labels_stream = std::stringstream{};
1791 for (std::size_t i = 1; i < num_dimensions(); ++i) {
1795 group.attribute(
"vsAxisLabels") = axis_labels_stream.str();
1796 group.attribute(
"vsKind") =
"rectilinear";
1797 group.attribute(
"vsType") =
"mesh";
1798 group.attribute(
"vsIndexOrder") =
"compMinorF";
1800 m_dimensions.iterate([&, i = std::size_t{}](
auto const &dim)
mutable {
1801 using dim_type =
typename std::decay_t<
decltype(dim)>
::value_type;
1802 group.attribute(
"vsAxis" + std::to_string(i)) =
1803 "axis" + std::to_string(i);
1804 auto dim_as_vec = std::vector<dim_type>{};
1805 dim_as_vec.reserve(dim.size());
1806 std::ranges::copy(dim, std::back_inserter(dim_as_vec));
1808 auto dim_dataset = f.create_dataset<dim_type>(
1809 "rectilinear_grid/axis" + std::to_string(i), dim.size());
1810 dim_dataset.write(dim_as_vec);
1814 for (
const auto &[name, prop] : this->m_vertex_properties) {
1815 write_prop_hdf5_wrapper<std::uint16_t, std::uint32_t, std::int16_t,
1824 template <std::
size_t I>
auto print_dim(std::ostream &out)
const {
1825 auto const &dim = dimension<I>();
1826 if constexpr (
is_linspace<std::decay_t<
decltype(dim)>>) {
1829 out << dim.front() <<
", " << dim[1] <<
", ..., " << dim.back();
1831 out <<
" [" << dim.size() <<
"]\n";
1833 template <std::size_t... Seq>
1834 auto print(std::ostream &out, std::index_sequence<Seq...> )
const
1836 (print_dim<Seq>(out), ...);
1841 auto print(std::ostream &out = std::cout)
const ->
auto & {
1842 return print(out, std::make_index_sequence<num_dimensions()>{});
1845 auto chunk_size_for_lazy_properties() {
1846 return m_chunk_size_for_lazy_properties;
1849 auto set_chunk_size_for_lazy_properties(std::size_t
const val) ->
void {
1850 m_chunk_size_for_lazy_properties = val;
1856template <
typename... Dimensions>
1859 return g.print(out);
1861template <floating_point_range... Dimensions>
1868template <floating_point_range... Dimensions>
1872template <
typename Real, std::
size_t N>
1876 linspace<std::conditional_t<
true, Real,
decltype(res)>>...>;
1887 AdditionalDimension &&additional_dimension) {
1889 std::forward<AdditionalDimension>(additional_dimension));
1892template <floating_point_range... Dimensions,
1893 floating_point_range AdditionalDimension>
1894auto operator+(AdditionalDimension &&additional_dimension,
1897 std::forward<AdditionalDimension>(additional_dimension));
1902template <
floating_po
int Real, std::
size_t N>
1905template <std::
size_t N>
1911template <
floating_po
int Real>
1913template <
floating_po
int Real>
1915template <
floating_po
int Real>
1917template <
floating_po
int Real>
1920template <arithmetic Real, std::
size_t N>
1923template <std::
size_t N>
1933template <std::
size_t N>
Definition: rectilinear_grid.h:38
constexpr rectilinear_grid()=default
Default CTOR.
auto scalar_vertex_property(std::string const &name) const -> auto const &
Definition: rectilinear_grid.h:868
auto vec4_vertex_property(std::string const &name) const -> auto const &
Definition: rectilinear_grid.h:898
auto sample_to_vertex_property(F &&f, std::string const &name) -> auto &
Definition: rectilinear_grid.h:1080
constexpr auto copy_without_properties() const
Creates a copy of with any of the give properties.
Definition: rectilinear_grid.h:169
auto insert_hdf5_lazy_vertex_property(filesystem::path const &path, std::string const &dataset_name) -> auto &
Definition: rectilinear_grid.h:1004
auto cells() const
Definition: rectilinear_grid.h:686
auto create_vertex_property(std::string const &name, Args &&...args) -> auto &
Definition: rectilinear_grid.h:727
auto insert_lazy_vertex_property(hdf5::dataset< T > const &dataset, std::string const &name) -> auto &
Definition: rectilinear_grid.h:1021
constexpr auto dimension(std::size_t const i) const -> auto const &requires(is_same< Dimensions... >) &&(num_dimensions()<=11)
Definition: rectilinear_grid.h:202
auto insert_vec2_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:757
auto insert_netcdf_lazy_vertex_property(filesystem::path const &path, std::string const &dataset_name) -> auto &
Definition: rectilinear_grid.h:1057
constexpr auto min() const
Definition: rectilinear_grid.h:273
auto insert_mat2_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:772
constexpr rectilinear_grid(axis_aligned_bounding_box< Real, num_dimensions()> const &bb, Res const ... res)
Definition: rectilinear_grid.h:141
auto vec3_vertex_property(std::string const &name) const -> auto const &
Definition: rectilinear_grid.h:888
auto insert_lazy_vertex_property(netcdf::variable< T > const &dataset) -> auto &
Definition: rectilinear_grid.h:1067
static constexpr auto num_dimensions() -> std::size_t
Definition: rectilinear_grid.h:42
auto insert_contiguous_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:789
auto cell_index(arithmetic auto x) const -> std::pair< std::size_t, real_type >
Definition: rectilinear_grid.h:521
auto vertex_property(std::string const &name) const -> typed_vertex_property_interface_type< T, HasNonConstReference > const &
Definition: rectilinear_grid.h:850
constexpr auto bounding_box() const
Definition: rectilinear_grid.h:341
auto read(filesystem::path const &path)
Definition: rectilinear_grid.h:1148
constexpr auto is_inside(pos_type const &p, std::index_sequence< Seq... >) const
Checks if point p is inside of grid.
Definition: rectilinear_grid.h:490
auto mat2_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:913
auto vec2_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:883
auto insert_chunked_vertex_property(std::string const &name, std::array< std::size_t, num_dimensions()> const &chunk_size) -> auto &
Definition: rectilinear_grid.h:804
constexpr rectilinear_grid(integral auto const ... size)
Definition: rectilinear_grid.h:149
constexpr auto copy_without_properties(std::index_sequence< Ds... >) const
Definition: rectilinear_grid.h:163
auto vertices() const
Definition: rectilinear_grid.h:637
auto cell_index(arithmetic auto const ... xs) const
Definition: rectilinear_grid.h:571
constexpr auto extent(std::size_t const cell_index) const
Definition: rectilinear_grid.h:307
auto insert_lazy_vertex_property(filesystem::path const &path, std::string const &dataset_name) -> typed_vertex_property_interface_type< T, false > &
Definition: rectilinear_grid.h:939
auto sample_to_vertex_property(F &&f, std::string const &name, execution_policy_tag auto tag) -> auto &
Definition: rectilinear_grid.h:1089
auto add_dimension(floating_point_range auto &&additional_dimension, std::index_sequence< Is... >) const
Definition: rectilinear_grid.h:690
constexpr auto size(std::index_sequence< Seq... >) const
Definition: rectilinear_grid.h:347
auto insert_chunked_vertex_property(std::string const &name, std::vector< std::size_t > const &chunk_size) -> auto &
Definition: rectilinear_grid.h:796
constexpr auto pop_front()
Removes first discrete point in dimension I.
Definition: rectilinear_grid.h:462
auto mat2_vertex_property(std::string const &name) const -> auto const &
Definition: rectilinear_grid.h:908
auto vertex_at(std::index_sequence< DIs... >, std::array< Int, num_dimensions()> const &is) const -> vec< real_type, num_dimensions()>
Definition: rectilinear_grid.h:640
auto insert_vec4_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:767
auto vec4_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:903
~rectilinear_grid()=default
auto insert_vertex_property(hdf5::dataset< T > const &dataset, std::string const &name) -> auto &
Definition: rectilinear_grid.h:969
auto insert_lazy_vertex_property(hdf5::dataset< T > const &dataset) -> auto &
Definition: rectilinear_grid.h:1014
constexpr auto size() const
Definition: rectilinear_grid.h:357
constexpr auto center(std::index_sequence< Is... >) const
Definition: rectilinear_grid.h:318
constexpr auto extent(std::index_sequence< Is... >) const
Definition: rectilinear_grid.h:294
constexpr auto dimensions() const -> auto const &
Definition: rectilinear_grid.h:262
constexpr auto pop_back()
Removes last discrete point in dimension I.
Definition: rectilinear_grid.h:453
auto scalar_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:873
constexpr auto min(std::index_sequence< Seq... >) const
Definition: rectilinear_grid.h:266
auto vertex_at(vertex_handle const &h) const
Definition: rectilinear_grid.h:664
auto has_vertex_property(std::string const &name)
Definition: rectilinear_grid.h:705
std::map< std::string, property_ptr_type > property_container_type
Definition: rectilinear_grid.h:79
constexpr auto plain_index(integral auto const ... is)
Definition: rectilinear_grid.h:672
auto insert_mat3_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:777
common_type< typename Dimensions::value_type... > real_type
Definition: rectilinear_grid.h:46
auto insert_vec3_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:762
auto finite_differences_coefficients(std::size_t const stencil_size, std::size_t const dim_index, std::size_t const i) const
Definition: rectilinear_grid.h:583
auto resize_vertex_properties()
Definition: rectilinear_grid.h:422
constexpr auto push_back()
Inserts new discrete point in dimension I with extent of last cell.
Definition: rectilinear_grid.h:439
constexpr rectilinear_grid(rectilinear_grid const &other)
Copy CTOR.
Definition: rectilinear_grid.h:98
variadic::ith_type< I, Dimensions... > dimension_type
Definition: rectilinear_grid.h:52
auto cell_index(std::index_sequence< DimensionIndex... >, arithmetic auto const ... xs) const -> std::array< std::pair< std::size_t, double >, num_dimensions()>
returns cell indices and factors for each dimension for interpolaton
Definition: rectilinear_grid.h:564
constexpr auto extent() const
Definition: rectilinear_grid.h:287
auto vertex_properties() const -> auto const &
Definition: rectilinear_grid.h:743
auto vec2_vertex_property(std::string const &name) const -> auto const &
Definition: rectilinear_grid.h:878
constexpr auto is_inside(std::array< real_type, num_dimensions()> const &p) const
Checks if point p is inside of grid.
Definition: rectilinear_grid.h:514
constexpr auto dimension() const -> auto const &
Definition: rectilinear_grid.h:194
auto insert_vertex_property(hdf5::dataset< T > const &dataset) -> auto &
Definition: rectilinear_grid.h:964
constexpr auto operator=(rectilinear_grid &&other) noexcept -> rectilinear_grid &
Definition: rectilinear_grid.h:176
constexpr auto extent() const
Definition: rectilinear_grid.h:300
auto rename_vertex_property(std::string const ¤t_name, std::string const &new_name) -> void
Definition: rectilinear_grid.h:716
constexpr auto size(std::size_t const i) const
Definition: rectilinear_grid.h:364
auto remove_vertex_property(std::string const &name) -> void
Definition: rectilinear_grid.h:709
rectilinear_grid(filesystem::path const &path)
Constructs a rectilinear grid by reading a file.
Definition: rectilinear_grid.h:156
constexpr auto max(std::index_sequence< Seq... >) const
Definition: rectilinear_grid.h:277
constexpr rectilinear_grid(axis_aligned_bounding_box< Real, num_dimensions()> const &bb, std::index_sequence< Seq... >, Res const ... res)
Definition: rectilinear_grid.h:128
auto read_vtk(filesystem::path const &path)
Definition: rectilinear_grid.h:1334
constexpr auto operator=(rectilinear_grid const &other) -> rectilinear_grid &=default
auto insert_chunked_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:824
auto mat3_vertex_property(std::string const &name) const -> auto const &
Definition: rectilinear_grid.h:918
std::make_index_sequence< num_dimensions()> sequence_type
Definition: rectilinear_grid.h:49
auto create_finite_differences_coefficients(std::size_t const stencil_size) const
Computes finite difference coefficients for given stencil size.
Definition: rectilinear_grid.h:604
constexpr auto max() const
Definition: rectilinear_grid.h:284
constexpr auto size() const
Definition: rectilinear_grid.h:353
auto insert_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:747
auto vec3_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:893
auto vertex_at(std::array< Int, num_dimensions()> const &is) const
Definition: rectilinear_grid.h:660
std::unique_ptr< vertex_property_type > property_ptr_type
Definition: rectilinear_grid.h:78
constexpr rectilinear_grid(Dimensions_ &&...dimensions)
Definition: rectilinear_grid.h:122
constexpr auto bounding_box(std::index_sequence< Seq... >) const
Definition: rectilinear_grid.h:331
auto mat4_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:933
auto vertex_at(integral auto const ... is) const
Definition: rectilinear_grid.h:654
auto add_dimension(floating_point_range auto &&additional_dimension) const
Definition: rectilinear_grid.h:699
auto mat4_vertex_property(std::string const &name) const -> auto const &
Definition: rectilinear_grid.h:928
constexpr auto center() const
Definition: rectilinear_grid.h:323
auto insert_mat4_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:782
constexpr auto is_inside(std::array< real_type, num_dimensions()> const &p, std::index_sequence< Seq... >) const
Checks if point p is inside of grid.
Definition: rectilinear_grid.h:506
dimensions_type m_dimensions
Definition: rectilinear_grid.h:83
auto mat3_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:923
constexpr auto set_dimension(convertible_to< dimension_type< I > > auto &&dim)
Definition: rectilinear_grid.h:432
property_container_type m_vertex_properties
Definition: rectilinear_grid.h:84
auto sample_to_vertex_property_indices(F &&f, std::string const &name, execution_policy_tag auto tag, std::index_sequence< Is... >) -> auto &
Definition: rectilinear_grid.h:1103
auto operator[](vertex_handle const &h) const
Definition: rectilinear_grid.h:668
constexpr auto center() const
Definition: rectilinear_grid.h:312
auto insert_chunked_vertex_property(std::string const &name, integral auto const ... chunk_size) -> auto &requires(sizeof...(chunk_size)==num_dimensions())
Definition: rectilinear_grid.h:813
auto insert_scalar_vertex_property(std::string const &name) -> auto &
Definition: rectilinear_grid.h:752
constexpr auto is_inside(pos_type const &p) const
Checks if point p is inside of grid.
Definition: rectilinear_grid.h:499
auto vertex_properties() -> auto &
Definition: rectilinear_grid.h:744
auto vertex_property(std::string const &name) -> typed_vertex_property_interface_type< T, HasNonConstReference > &
Definition: rectilinear_grid.h:831
auto vertex_at(std::index_sequence< DIs... >, integral auto const ... is) const -> vec< real_type, num_dimensions()>
Definition: rectilinear_grid.h:647
std::vector< real_type > finite_difference_coefficents_list_type
Definition: rectilinear_grid.h:86
auto cell_index(fixed_size_vec< num_dimensions()> auto &&xs) const
Definition: rectilinear_grid.h:577
constexpr rectilinear_grid(rectilinear_grid &&other) noexcept
Move CTOR.
Definition: rectilinear_grid.h:110
std::invoke_result_t< F, decltype(((void) std::declval< Dimensions >(), std::declval< std::size_t >()))... > invoke_result_with_indices
Definition: rectilinear_grid.h:76
auto sample_to_vertex_property_pos(F &&f, std::string const &name, execution_policy_tag auto tag) -> auto &
Definition: rectilinear_grid.h:1126
Definition: vtk_legacy.h:184
auto add_listener(legacy_file_listener &listener) -> void
Definition: concepts.h:33
Definition: concepts.h:39
Definition: tensor_concepts.h:33
Definition: concepts.h:94
Definition: concepts.h:21
Definition: invocable_with_n_types.h:37
Definition: concepts.h:121
auto finite_differences_coefficients(std::size_t const derivative_order, floating_point auto const ... xs)
See What is this? for an explanation.
Definition: finite_differences_coefficients.h:13
auto read(std::ifstream &file)
Definition: read.h:104
typename detail::rectilinear_grid::creator< IndexableSpace, N >::type creator_t
Definition: creator.h:37
static constexpr sequential_t sequential
Definition: tags.h:63
constexpr auto name()
Definition: reflection.h:61
typename ith_type_impl< I, Types... >::type ith_type
Definition: ith_type.h:15
reader_data
Definition: vtk_legacy.h:42
dataset_type
Definition: vtk_legacy.h:44
Definition: algorithm.h:6
auto operator<<(std::ostream &out, linspace< Real > const &l) -> auto &
Definition: linspace.h:165
constexpr auto distance(Iter const &it0, Iter const &it1)
Definition: iterator_facade.h:372
typename common_type_impl< Ts... >::type common_type
Definition: common_type.h:23
VecF< 3 > vec3f
Definition: vec_typedefs.h:40
auto write_vtk(Lines const &lines, filesystem::path const &path, std::string const &title="tatooine lines") -> void
Definition: write.h:163
NonuniformRectilinearGrid< 3 > static_nonuniform_rectilinear_grid3
Definition: rectilinear_grid.h:1936
auto begin(Range &&range)
Definition: iterator_facade.h:318
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto end(Range &&range)
Definition: iterator_facade.h:322
auto write(Lines const &lines, filesystem::path const &path) -> void
Definition: write.h:218
UniformRectilinearGrid< 4 > uniform_rectilinear_grid4
Definition: rectilinear_grid.h:1909
std::invoke_result_t< F, Args... > invoke_result
Definition: concepts.h:127
VecD< 3 > vec3d
Definition: vec_typedefs.h:51
uniform_rectilinear_grid< Real, 5 > UniformRectilinearGrid5
Definition: rectilinear_grid.h:1918
auto type_name() -> std::string
returns demangled typename
Definition: demangling.h:21
auto vertices(pointset< Real, NumDimensions > const &ps)
Definition: vertex_container.h:278
uniform_rectilinear_grid< Real, 2 > UniformRectilinearGrid2
Definition: rectilinear_grid.h:1912
axis_aligned_bounding_box< Real, NumDimensions > aabb
Definition: axis_aligned_bounding_box.h:553
nonuniform_rectilinear_grid< real_number, N > NonuniformRectilinearGrid
Definition: rectilinear_grid.h:1924
uniform_rectilinear_grid< Real, 4 > UniformRectilinearGrid4
Definition: rectilinear_grid.h:1916
constexpr auto invoke(invocable auto &&...funcs)
Definition: functional.h:8
detail::rectilinear_grid::creator_t< std::vector< Real >, N > nonuniform_rectilinear_grid
Definition: rectilinear_grid.h:1922
static constexpr auto is_linspace
Definition: linspace.h:160
UniformRectilinearGrid< 2 > uniform_rectilinear_grid2
Definition: rectilinear_grid.h:1907
UniformRectilinearGrid< 3 > uniform_rectilinear_grid3
Definition: rectilinear_grid.h:1908
VecD< 2 > vec2d
Definition: vec_typedefs.h:50
VecF< 4 > vec4f
Definition: vec_typedefs.h:41
detail::rectilinear_grid::creator_t< linspace< Real >, N > uniform_rectilinear_grid
Definition: rectilinear_grid.h:1904
uniform_rectilinear_grid< real_number, N > UniformRectilinearGrid
Definition: rectilinear_grid.h:1906
static constexpr auto is_same
Definition: type_traits.h:42
NonuniformRectilinearGrid< 2 > nonuniform_rectilinear_grid2
Definition: rectilinear_grid.h:1925
VecD< 4 > vec4d
Definition: vec_typedefs.h:52
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto next(Iter iter)
Definition: iterator_facade.h:325
auto nan(const char *arg="")
Definition: nan.h:26
NonuniformRectilinearGrid< 3 > nonuniform_rectilinear_grid3
Definition: rectilinear_grid.h:1926
static auto constexpr cartesian_axis_label()
Definition: cartesian_axis_labels.h:27
NonuniformRectilinearGrid< 5 > static_nonuniform_rectilinear_grid5
Definition: rectilinear_grid.h:1938
VecF< 5 > vec5f
Definition: vec_typedefs.h:42
NonuniformRectilinearGrid< 5 > nonuniform_rectilinear_grid5
Definition: rectilinear_grid.h:1928
auto back(linspace< Real > const &l)
Definition: linspace.h:136
auto front(linspace< Real > const &l)
Definition: linspace.h:126
constexpr decltype(auto) invoke_unpacked(F &&f)
All arguments are bound -> just call f.
Definition: invoke_unpacked.h:15
constexpr auto for_loop(Iteration &&iteration, execution_policy::sequential_t, Ranges(&&... ranges)[2]) -> void
Use this function for creating a sequential nested loop.
Definition: for_loop.h:336
UniformRectilinearGrid< 5 > uniform_rectilinear_grid5
Definition: rectilinear_grid.h:1910
NonuniformRectilinearGrid< 4 > nonuniform_rectilinear_grid4
Definition: rectilinear_grid.h:1927
uniform_rectilinear_grid< Real, 3 > UniformRectilinearGrid3
Definition: rectilinear_grid.h:1914
NonuniformRectilinearGrid< 2 > static_nonuniform_rectilinear_grid2
Definition: rectilinear_grid.h:1935
NonuniformRectilinearGrid< 4 > static_nonuniform_rectilinear_grid4
Definition: rectilinear_grid.h:1937
VecF< 2 > vec2f
Definition: vec_typedefs.h:39
VecD< 5 > vec5d
Definition: vec_typedefs.h:53
Definition: axis_aligned_bounding_box.h:103
Definition: cell_container.h:18
Definition: vertex_property.h:96
Definition: vertex_property.h:368
auto resize(std::array< std::size_t, num_dimensions()> const &size) -> void override
Definition: vertex_property.h:458
Definition: vertex_container.h:20
Definition: vertex_handle.h:10
constexpr auto indices() const -> auto const &
Definition: vertex_handle.h:31
Definition: vertex_property.h:45
Definition: lazy_reader.h:14
Definition: linspace.h:26
constexpr auto back() const
Definition: linspace.h:95
Definition: rectilinear_grid.h:1173
auto on_field_array(std::string const, std::string const field_array_name, std::vector< double > const &data, std::size_t num_components, std::size_t) -> void override
Definition: rectilinear_grid.h:1325
auto on_field_array(std::string const, std::string const field_array_name, std::vector< int > const &data, std::size_t num_components, std::size_t) -> void override
Definition: rectilinear_grid.h:1311
auto on_lines(std::vector< int > const &) -> void override
Definition: rectilinear_grid.h:1232
auto on_field_array(std::string const, std::string const field_array_name, std::vector< float > const &data, std::size_t num_components, std::size_t) -> void override
Definition: rectilinear_grid.h:1318
auto on_cell_types(std::vector< vtk::cell_type > const &) -> void override
Definition: rectilinear_grid.h:1230
auto on_vectors(std::string const &, std::vector< std::array< float, 3 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1237
auto on_z_coordinates(std::vector< float > const &) -> void override
Definition: rectilinear_grid.h:1224
auto on_y_coordinates(std::vector< double > const &) -> void override
Definition: rectilinear_grid.h:1222
auto on_polygons(std::vector< int > const &) -> void override
Definition: rectilinear_grid.h:1233
auto on_cell_data(std::size_t) -> void override
Definition: rectilinear_grid.h:1310
auto insert_prop(std::string const &prop_name, std::vector< T > const &data, std::size_t const num_components)
Definition: rectilinear_grid.h:1265
auto on_origin(double x, double y, double z) -> void override
Definition: rectilinear_grid.h:1188
auto on_x_coordinates(std::vector< double > const &) -> void override
Definition: rectilinear_grid.h:1219
bool & is_structured_points
Definition: rectilinear_grid.h:1175
auto on_triangle_strips(std::vector< int > const &) -> void override
Definition: rectilinear_grid.h:1234
auto on_point_data(std::size_t) -> void override
Definition: rectilinear_grid.h:1309
vtk_listener(this_type &gr_, bool &is_structured_points_, vec3 &spacing_)
Definition: rectilinear_grid.h:1177
auto on_texture_coordinates(std::string const &, std::vector< std::array< double, 2 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1253
vec3 & spacing
Definition: rectilinear_grid.h:1176
auto on_z_coordinates(std::vector< double > const &) -> void override
Definition: rectilinear_grid.h:1225
auto on_dimensions(std::size_t x, std::size_t y, std::size_t z) -> void override
Definition: rectilinear_grid.h:1204
auto on_dataset_type(vtk::dataset_type t) -> void override
Definition: rectilinear_grid.h:1181
auto on_y_coordinates(std::vector< float > const &) -> void override
Definition: rectilinear_grid.h:1221
auto on_scalars(std::string const &data_name, std::string const &, std::size_t const num_components, std::vector< double > const &data, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1302
auto on_x_coordinates(std::vector< float > const &) -> void override
Definition: rectilinear_grid.h:1218
auto on_cells(std::vector< int > const &) -> void override
Definition: rectilinear_grid.h:1229
auto on_texture_coordinates(std::string const &, std::vector< std::array< float, 2 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1249
auto on_normals(std::string const &, std::vector< std::array< float, 3 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1243
auto on_tensors(std::string const &, std::vector< std::array< double, 9 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1260
this_type & gr
Definition: rectilinear_grid.h:1174
auto on_spacing(double x, double y, double z) -> void override
Definition: rectilinear_grid.h:1201
auto on_tensors(std::string const &, std::vector< std::array< float, 9 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1257
auto on_scalars(std::string const &data_name, std::string const &, std::size_t const num_components, std::vector< float > const &data, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1295
auto on_normals(std::string const &, std::vector< std::array< double, 3 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1246
auto on_vertices(std::vector< int > const &) -> void override
Definition: rectilinear_grid.h:1231
auto on_vectors(std::string const &, std::vector< std::array< double, 3 > > const &, vtk::reader_data) -> void override
Definition: rectilinear_grid.h:1240
Definition: invoke_unpacked.h:11
Definition: vtk_legacy.h:92
Definition: index_order.h:17