1#ifndef TATOOINE_PARALLEL_VECTORS_H
2#define TATOOINE_PARALLEL_VECTORS_H
4#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
16#include <boost/range/adaptor/transformed.hpp>
17#include <boost/range/numeric.hpp>
102template <
typename Real, invocable<Vec3<Real>>... Preds>
108 -> std::optional<Vec3<Real>> {
117 if (std::abs(
det(V)) > 0) {
119 }
else if (std::abs(
det(W)) > 0) {
126 auto const ieig =
imag(eigvecs);
127 auto const reig =
real(eigvecs);
129 auto barycentric_coords = std::vector<Vec3<Real>>{};
130 for (std::size_t i = 0; i < 3; ++i) {
131 if ((ieig(0, i) == 0 && ieig(1, i) == 0 && ieig(2, i) == 0) &&
132 ((reig(0, i) <= 0 && reig(1, i) <= 0 && reig(2, i) <= 0) ||
133 (reig(0, i) >= 0 && reig(1, i) >= 0 && reig(2, i) >= 0))) {
135 barycentric_coords.push_back(bc);
139 if (barycentric_coords.empty()) {
143 if (barycentric_coords.size() == 1) {
144 auto pos = barycentric_coords.front()(0) * p0 +
145 barycentric_coords.front()(1) * p1 +
146 barycentric_coords.front()(2) * p2;
147 if constexpr (
sizeof...(Preds) > 0) {
148 if ((preds(pos) && ...)) {
157 Real
const eps = 1e-5;
158 for (
unsigned int i = 1; i < barycentric_coords.size(); i++) {
159 for (
unsigned int j = 0; j < i; j++) {
160 if (!
approx_equal(barycentric_coords[i], barycentric_coords[j], eps)) {
165 auto const pos = barycentric_coords.front()(0) * p0 +
166 barycentric_coords.front()(1) * p1 +
167 barycentric_coords.front()(2) * p2;
172template <
typename Real>
178 auto tris = std::vector<std::optional<Vec3<Real>>
const*>{};
180 tris.push_back(&tri0);
183 tris.push_back(&tri1);
186 tris.push_back(&tri2);
189 tris.push_back(&tri3);
192 if (tris.size() == 1) {
194 }
else if (tris.size() == 2) {
197 }
else if (tris.size() == 3) {
199 }
else if (tris.size() == 4) {
206template <
signed_
integral Int =
int>
207auto constexpr sign(
bool pred) -> Int {
208 return pred ? 1 : -1;
216 auto const& z_faces,
auto const& inner_faces,
auto& ls,
217 auto const ix,
auto const iy) {
220 y_faces(ix, iy + 1)[0],
221 z_faces(0, ix, iy)[1],
222 inner_faces(ix, iy)[1],
227 z_faces(0, ix, iy)[0],
228 inner_faces(ix, iy)[0],
232 y_faces(ix, iy + 1)[1],
233 z_faces(1, ix, iy)[1],
234 inner_faces(ix, iy)[2],
239 z_faces(1, ix, iy)[0],
240 inner_faces(ix, iy)[3],
244 inner_faces(ix, iy)[1],
245 inner_faces(ix, iy)[2],
246 inner_faces(ix, iy)[3],
251 auto const& z_faces,
auto const& inner_faces,
auto& ls,
252 auto const ix,
auto const iy) {
256 z_faces(0, ix, iy)[0],
257 inner_faces(ix, iy)[0],
262 z_faces(1, ix, iy)[0],
263 inner_faces(ix, iy)[2],
267 y_faces(ix, iy + 1)[1],
268 z_faces(1, ix, iy)[1],
269 inner_faces(ix, iy)[3],
273 y_faces(ix, iy + 1)[0],
274 z_faces(0, ix, iy)[1],
275 inner_faces(ix, iy)[1],
279 inner_faces(ix, iy)[1],
280 inner_faces(ix, iy)[2],
281 inner_faces(ix, iy)[3],
285auto check_cube(
auto const& x_faces,
auto const& y_faces,
auto const& z_faces,
286 auto const& inner_faces,
auto& ls,
auto const ix,
auto const iy,
295#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
305template <
typename Real,
typename GetV,
typename GetW,
typename XDomain,
308 GetV&& getv, GetW&& getw,
311 -> std::vector<Line3<Real>> {
315 using maybe_vec3 = std::optional<vec3>;
316 using maybe_vec3_arr2 = std::array<maybe_vec3, 2>;
317 using maybe_vec3_arr4 = std::array<maybe_vec3, 4>;
320 auto iz = std::size_t(0);
321 auto const resolution = g.size();
322 auto const gv = g.vertices();
327 auto x_faces = faces_arr{resolution[0], resolution[1] - 1};
332 auto y_faces = faces_arr{resolution[0] - 1, resolution[1]};
337 auto z_faces = faces_arr{2, resolution[0] - 1, resolution[1] - 1};
342 auto inner_faces = inner_faces_arr{resolution[0] - 1, resolution[1] - 1};
344 auto update_x_faces = [&](std::size_t
const ix, std::size_t
const iy) {
345 auto const p = std::array{
349 gv(ix, iy + 1, iz + 1)
352 decltype(
auto) v0 = getv(ix, iy, iz, p[0]);
356 decltype(
auto) v4 = getv(ix, iy, iz + 1, p[1]);
360 decltype(
auto) v2 = getv(ix, iy + 1, iz, p[2]);
364 decltype(
auto) v6 = getv(ix, iy + 1, iz + 1, p[3]);
368 decltype(
auto) w0 = getw(ix, iy, iz, p[0]);
372 decltype(
auto) w4 = getw(ix, iy, iz + 1, p[1]);
376 decltype(
auto) w2 = getw(ix, iy + 1, iz, p[2]);
380 decltype(
auto) w6 = getw(ix, iy + 1, iz + 1, p[3]);
387 std::forward<Preds>(preds)...);
390 std::forward<Preds>(preds)...);
394 std::forward<Preds>(preds)...);
397 std::forward<Preds>(preds)...);
400 auto update_y_faces = [&](std::size_t
const ix, std::size_t
const iy) {
401 auto const p = std::array{
405 gv(ix + 1, iy, iz + 1)
408 decltype(
auto) v0 = getv(ix, iy, iz, p[0]);
412 decltype(
auto) v1 = getv(ix + 1, iy, iz, p[1]);
416 decltype(
auto) v4 = getv(ix, iy, iz + 1, p[2]);
420 decltype(
auto) v5 = getv(ix + 1, iy, iz + 1, p[3]);
424 decltype(
auto) w0 = getw(ix, iy, iz, p[0]);
428 decltype(
auto) w1 = getw(ix + 1, iy, iz, p[1]);
432 decltype(
auto) w4 = getw(ix, iy, iz + 1, p[2]);
436 decltype(
auto) w5 = getw(ix + 1, iy, iz + 1, p[3]);
443 std::forward<Preds>(preds)...);
446 std::forward<Preds>(preds)...);
450 std::forward<Preds>(preds)...);
453 std::forward<Preds>(preds)...);
456 auto update_z = [&](std::size_t
const ix, std::size_t
const iy,
457 std::size_t
const iz, std::size_t
const write_iz) {
458 assert(write_iz == 0 || write_iz == 1);
459 auto const p = std::array{
463 gv(ix + 1, iy + 1, iz)
466 decltype(
auto) v0 = getv(ix, iy, iz, p[0]);
470 decltype(
auto) v1 = getv(ix + 1, iy, iz, p[1]);
474 decltype(
auto) v2 = getv(ix, iy + 1, iz, p[2]);
478 decltype(
auto) v3 = getv(ix + 1, iy + 1, iz, p[3]);
482 decltype(
auto) w0 = getw(ix, iy, iz, p[0]);
486 decltype(
auto) w1 = getw(ix + 1, iy, iz, p[1]);
490 decltype(
auto) w2 = getw(ix, iy + 1, iz, p[2]);
494 decltype(
auto) w3 = getw(ix + 1, iy + 1, iz, p[3]);
499 z_faces(write_iz, ix, iy)[0] =
501 std::forward<Preds>(preds)...);
502 z_faces(write_iz, ix, iy)[1] =
504 std::forward<Preds>(preds)...);
506 z_faces(write_iz, ix, iy)[0] =
508 std::forward<Preds>(preds)...);
509 z_faces(write_iz, ix, iy)[1] =
511 std::forward<Preds>(preds)...);
514 auto move_zs = [&]() {
516 [&](
auto const... is) { z_faces(0, is...) = z_faces(1, is...); },
517 policy, resolution[0] - 1, resolution[1] - 1);
521 resolution[0] - 1, resolution[1] - 1);
522 auto update_z_faces = [&](std::size_t
const ix, std::size_t
const iy) {
523 update_z(ix, iy, iz + 1, 1);
526 auto update_inner_faces = [&](std::size_t
const ix, std::size_t
const iy) {
527 auto const gv = g.vertices();
529 auto const p = std::array{gv(ix, iy, iz), gv(ix + 1, iy + 1, iz),
530 gv(ix + 1, iy, iz + 1), gv(ix, iy + 1, iz + 1)};
532 decltype(
auto) v0 = getv(ix, iy, iz, p[0]);
536 decltype(
auto) v3 = getv(ix + 1, iy + 1, iz, p[1]);
540 decltype(
auto) v5 = getv(ix + 1, iy, iz + 1, p[2]);
544 decltype(
auto) v6 = getv(ix, iy + 1, iz + 1, p[3]);
548 decltype(
auto) w0 = getw(ix, iy, iz, p[0]);
552 decltype(
auto) w3 = getw(ix + 1, iy + 1, iz, p[1]);
556 decltype(
auto) w5 = getw(ix + 1, iy, iz + 1, p[2]);
560 decltype(
auto) w6 = getw(ix, iy + 1, iz + 1, p[3]);
564 inner_faces(ix, iy)[0] =
566 std::forward<Preds>(preds)...);
567 inner_faces(ix, iy)[1] =
569 std::forward<Preds>(preds)...);
570 inner_faces(ix, iy)[2] =
572 std::forward<Preds>(preds)...);
573 inner_faces(ix, iy)[3] =
575 std::forward<Preds>(preds)...);
577 auto const p1 = gv(ix + 1, iy, iz);
578 auto const p2 = gv(ix, iy + 1, iz);
579 auto const p4 = gv(ix, iy, iz + 1);
580 auto const p7 = gv(ix + 1, iy + 1, iz + 1);
582 decltype(
auto) v1 = getv(ix + 1, iy, iz, p1);
586 decltype(
auto) v2 = getv(ix, iy + 1, iz, p2);
590 decltype(
auto) v4 = getv(ix, iy, iz + 1, p4);
594 decltype(
auto) v7 = getv(ix + 1, iy + 1, iz + 1, p7);
598 decltype(
auto) w1 = getw(ix + 1, iy, iz, p1);
602 decltype(
auto) w2 = getw(ix, iy + 1, iz, p2);
606 decltype(
auto) w4 = getw(ix, iy, iz + 1, p4);
610 decltype(
auto) w7 = getw(ix + 1, iy + 1, iz + 1, p7);
614 inner_faces(ix, iy)[0] =
616 std::forward<Preds>(preds)...);
617 inner_faces(ix, iy)[1] =
619 std::forward<Preds>(preds)...);
620 inner_faces(ix, iy)[2] =
622 std::forward<Preds>(preds)...);
623 inner_faces(ix, iy)[3] =
625 std::forward<Preds>(preds)...);
629 auto line_sets_per_thread =
630 std::vector<aligned<std::vector<Line3<Real>>>>(num_threads);
632 auto compute_line_segments = [&](
auto const... ixy) {
633 check_cube(x_faces, y_faces, z_faces, inner_faces,
634 *line_sets_per_thread[omp_get_thread_num()], ixy..., iz);
636 for (; iz < resolution[2] - 1; ++iz) {
647 if (iz < resolution[2] - 2) {
651 using boost::accumulate;
652 using boost::adaptors::transformed;
653 auto const s = [](
auto const& l) {
return l->size(); };
654 auto all_lines = std::vector<Line3<Real>>{};
656 accumulate(line_sets_per_thread | transformed(s), std::size_t(0)));
657 for (
auto const& line_set : line_sets_per_thread) {
658 for (
auto const&
line : *line_set) {
675template <
typename Real,
typename GetV,
typename GetW,
typename XDomain,
678 GetV&& getv, GetW&& getw,
684 using maybe_vec3 = std::optional<vec3>;
685 using maybe_vec3_arr2 = std::array<maybe_vec3, 2>;
686 using maybe_vec3_arr4 = std::array<maybe_vec3, 4>;
689 auto iz = std::size_t(0);
690 auto const resolution = g.
size();
696 auto x_faces = faces_arr{resolution[0], resolution[1] - 1};
697 auto update_x_faces = [&](std::size_t
const ix, std::size_t
const iy) {
698 auto const p = std::array{
702 gv(ix, iy + 1, iz + 1)
705 decltype(
auto) v0 = getv(ix, iy, iz, p[0]);
709 decltype(
auto) v4 = getv(ix, iy, iz + 1, p[1]);
713 decltype(
auto) v2 = getv(ix, iy + 1, iz, p[2]);
717 decltype(
auto) v6 = getv(ix, iy + 1, iz + 1, p[3]);
721 decltype(
auto) w0 = getw(ix, iy, iz, p[0]);
725 decltype(
auto) w4 = getw(ix, iy, iz + 1, p[1]);
729 decltype(
auto) w2 = getw(ix, iy + 1, iz, p[2]);
733 decltype(
auto) w6 = getw(ix, iy + 1, iz + 1, p[3]);
740 std::forward<Preds>(preds)...);
743 std::forward<Preds>(preds)...);
747 std::forward<Preds>(preds)...);
750 std::forward<Preds>(preds)...);
757 auto y_faces = faces_arr{resolution[0] - 1, resolution[1]};
758 auto update_y_faces = [&](std::size_t
const ix, std::size_t
const iy) {
759 auto const p0 = gv(ix, iy, iz);
760 auto const p1 = gv(ix + 1, iy, iz);
761 auto const p4 = gv(ix, iy, iz + 1);
762 auto const p5 = gv(ix + 1, iy, iz + 1);
764 decltype(
auto) v0 = getv(ix, iy, iz, p0);
768 decltype(
auto) v1 = getv(ix + 1, iy, iz, p1);
772 decltype(
auto) v4 = getv(ix, iy, iz + 1, p4);
776 decltype(
auto) v5 = getv(ix + 1, iy, iz + 1, p5);
780 decltype(
auto) w0 = getw(ix, iy, iz, p0);
784 decltype(
auto) w1 = getw(ix + 1, iy, iz, p1);
788 decltype(
auto) w4 = getw(ix, iy, iz + 1, p4);
792 decltype(
auto) w5 = getw(ix + 1, iy, iz + 1, p5);
799 std::forward<Preds>(preds)...);
802 std::forward<Preds>(preds)...);
806 std::forward<Preds>(preds)...);
809 std::forward<Preds>(preds)...);
816 auto z_faces = faces_arr{2, resolution[0] - 1, resolution[1] - 1};
817 auto update_z = [&](std::size_t
const ix, std::size_t
const iy,
818 std::size_t
const iz, std::size_t
const write_iz) {
819 assert(write_iz == 0 || write_iz == 1);
820 auto const p0 = gv(ix, iy, iz);
821 auto const p1 = gv(ix + 1, iy, iz);
822 auto const p2 = gv(ix, iy + 1, iz);
823 auto const p3 = gv(ix + 1, iy + 1, iz);
825 decltype(
auto) v0 = getv(ix, iy, iz, p0);
829 decltype(
auto) v1 = getv(ix + 1, iy, iz, p1);
833 decltype(
auto) v2 = getv(ix, iy + 1, iz, p2);
837 decltype(
auto) v3 = getv(ix + 1, iy + 1, iz, p3);
841 decltype(
auto) w0 = getw(ix, iy, iz, p0);
845 decltype(
auto) w1 = getw(ix + 1, iy, iz, p1);
849 decltype(
auto) w2 = getw(ix, iy + 1, iz, p2);
853 decltype(
auto) w3 = getw(ix + 1, iy + 1, iz, p3);
858 z_faces(write_iz, ix, iy)[0] =
860 std::forward<Preds>(preds)...);
861 z_faces(write_iz, ix, iy)[1] =
863 std::forward<Preds>(preds)...);
865 z_faces(write_iz, ix, iy)[0] =
867 std::forward<Preds>(preds)...);
868 z_faces(write_iz, ix, iy)[1] =
870 std::forward<Preds>(preds)...);
873 auto move_zs = [&]() {
875 [&](
auto const... is) { z_faces(0, is...) = z_faces(1, is...); },
876 policy, resolution[0] - 1, resolution[1] - 1);
880 resolution[0] - 1, resolution[1] - 1);
881 auto update_z_faces = [&](std::size_t
const ix, std::size_t
const iy) {
882 update_z(ix, iy, iz + 1, 1);
889 auto inner_faces = inner_faces_arr{resolution[0] - 1, resolution[1] - 1};
890 auto update_inner_faces = [&](std::size_t ix, std::size_t iy) {
893 auto const p0 = gv(ix, iy, iz);
894 auto const p3 = gv(ix + 1, iy + 1, iz);
895 auto const p5 = gv(ix + 1, iy, iz + 1);
896 auto const p6 = gv(ix, iy + 1, iz + 1);
898 decltype(
auto) v0 = getv(ix, iy, iz, p0);
902 decltype(
auto) v3 = getv(ix + 1, iy + 1, iz, p3);
906 decltype(
auto) v5 = getv(ix + 1, iy, iz + 1, p5);
910 decltype(
auto) v6 = getv(ix, iy + 1, iz + 1, p6);
914 decltype(
auto) w0 = getw(ix, iy, iz, p0);
918 decltype(
auto) w3 = getw(ix + 1, iy + 1, iz, p3);
922 decltype(
auto) w5 = getw(ix + 1, iy, iz + 1, p5);
926 decltype(
auto) w6 = getw(ix, iy + 1, iz + 1, p6);
930 inner_faces(ix, iy)[0] =
932 std::forward<Preds>(preds)...);
933 inner_faces(ix, iy)[1] =
935 std::forward<Preds>(preds)...);
936 inner_faces(ix, iy)[2] =
938 std::forward<Preds>(preds)...);
939 inner_faces(ix, iy)[3] =
941 std::forward<Preds>(preds)...);
943 auto const p1 = gv(ix + 1, iy, iz);
944 auto const p2 = gv(ix, iy + 1, iz);
945 auto const p4 = gv(ix, iy, iz + 1);
946 auto const p7 = gv(ix + 1, iy + 1, iz + 1);
948 decltype(
auto) v1 = getv(ix + 1, iy, iz, p1);
952 decltype(
auto) v2 = getv(ix, iy + 1, iz, p2);
956 decltype(
auto) v4 = getv(ix, iy, iz + 1, p4);
960 decltype(
auto) v7 = getv(ix + 1, iy + 1, iz + 1, p7);
964 decltype(
auto) w1 = getw(ix + 1, iy, iz, p1);
968 decltype(
auto) w2 = getw(ix, iy + 1, iz, p2);
972 decltype(
auto) w4 = getw(ix, iy, iz + 1, p4);
976 decltype(
auto) w7 = getw(ix + 1, iy + 1, iz + 1, p7);
980 inner_faces(ix, iy)[0] =
982 std::forward<Preds>(preds)...);
983 inner_faces(ix, iy)[1] =
985 std::forward<Preds>(preds)...);
986 inner_faces(ix, iy)[2] =
988 std::forward<Preds>(preds)...);
989 inner_faces(ix, iy)[3] =
991 std::forward<Preds>(preds)...);
994 auto lines = std::vector<Line3<Real>>{};
996 auto compute_line_segments = [&](
auto const... ixy) {
997 check_cube(x_faces, y_faces, z_faces, inner_faces, lines, ixy..., iz);
999 for (; iz < resolution[2] - 1; ++iz) {
1010 if (iz < resolution[2] - 2) {
1020template <
typename Real,
typename GetV,
typename GetW,
typename XDomain,
1023 GetV&& getv, GetW&& getw,
1026#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
1028 std::forward<GetV>(getv), std::forward<GetW>(getw), g,
1032 std::forward<GetV>(getv), std::forward<GetW>(getw), g,
1040template <
typename VReal,
typename WReal,
typename XDomain,
typename YDomain,
1041 typename ZDomain, arithmetic TReal,
1042 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1048 return detail::calc_parallel_vectors<common_type<VReal, WReal>>(
1050 [&vf, t](
auto const ,
auto const ,
auto const ,
1051 auto const& p) {
return vf(p, t); },
1053 [&wf, t](
auto const ,
auto const ,
auto const ,
1054 auto const& p) {
return wf(p, t); },
1055 g, policy, std::forward<Preds>(preds)...);
1059template <
typename VReal,
typename WReal,
typename XDomain,
typename YDomain,
1060 typename ZDomain, arithmetic TReal,
1061 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1065 TReal
const t, Preds&&... preds) {
1066#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
1068 std::forward<Preds>(preds)...);
1071 std::forward<Preds>(preds)...);
1076template <
typename V,
typename W,
typename VReal,
typename WReal,
1077 typename XDomain,
typename YDomain,
typename ZDomain,
1079 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1085 return detail::calc_parallel_vectors<common_type<VReal, WReal>>(
1087 [&vf, t](
auto const ,
auto const ,
auto const ,
1088 auto const& p) {
return vf(p, t); },
1090 [&wf, t](
auto const ,
auto const ,
auto const ,
1091 auto const& p) {
return wf(p, t); },
1092 g, policy, std::forward<Preds>(preds)...);
1096template <
typename V,
typename W,
typename VReal,
typename WReal,
1097 typename XDomain,
typename YDomain,
typename ZDomain,
1099 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1103 TReal
const t, Preds&&... preds) {
1104#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
1106 std::forward<Preds>(preds)...);
1109 std::forward<Preds>(preds)...);
1114template <
typename V,
typename W,
typename VReal,
typename WReal,
1115 typename XDomain,
typename YDomain,
typename ZDomain,
1116 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1122 return parallel_vectors(vf, wf, g, 0, policy, std::forward<Preds>(preds)...);
1126template <
typename V,
typename W,
typename VReal,
typename WReal,
1127 typename XDomain,
typename YDomain,
typename ZDomain,
1128 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1133#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
1135 std::forward<Preds>(preds)...);
1138 std::forward<Preds>(preds)...);
1143template <
typename V,
typename W,
typename VReal,
typename WReal,
1144 typename XReal,
typename YReal,
typename ZReal, arithmetic TReal,
1145 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1153 std::forward<Preds>(preds)...);
1157template <
typename V,
typename W,
typename VReal,
typename WReal,
1158 typename XReal,
typename YReal,
typename ZReal, arithmetic TReal,
1159 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1165#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
1167 std::forward<Preds>(preds)...);
1170 std::forward<Preds>(preds)...);
1175template <
typename V,
typename W,
typename VReal,
typename WReal,
1176 typename XReal,
typename YReal,
typename ZReal,
1177 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1185 std::forward<Preds>(preds)...);
1189template <
typename V,
typename W,
typename VReal,
typename WReal,
1190 typename XReal,
typename YReal,
typename ZReal,
1191 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1196#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
1198 std::forward<Preds>(preds)...);
1201 std::forward<Preds>(preds)...);
1206template <
typename VReal,
typename VIndexing,
typename WReal,
1207 typename WIndexing,
typename AABBReal,
1208 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1214 assert(vf.num_dimensions() == 3);
1215 assert(wf.num_dimensions() == 3);
1216 assert(vf.size(0) == wf.size(0));
1217 assert(vf.size(1) == wf.size(1));
1218 assert(vf.size(2) == wf.size(2));
1220 return detail::calc_parallel_vectors<common_type<VReal, WReal>>(
1221 [&vf](
auto ix,
auto iy,
auto iz,
auto const& ) ->
auto const& {
1222 return vf(ix, iy, iz);
1224 [&wf](
auto ix,
auto iy,
auto iz,
auto const& ) ->
auto const& {
1225 return wf(ix, iy, iz);
1230 policy, std::forward<Preds>(preds)...);
1234template <
typename VReal,
typename VIndexing,
typename WReal,
1235 typename WIndexing,
typename AABBReal,
1236 invocable<vec<common_type<VReal, WReal>, 3>>... Preds>
1241#if TATOOINE_PARALLEL_FOR_LOOPS_AVAILABLE
1243 std::forward<Preds>(preds)...);
1246 std::forward<Preds>(preds)...);
Definition: dynamic_multidim_array.h:18
Definition: rectilinear_grid.h:38
auto vertices() const
Definition: rectilinear_grid.h:637
constexpr auto size(std::index_sequence< Seq... >) const
Definition: rectilinear_grid.h:347
Definition: concepts.h:21
Definition: concepts.h:121
auto parallel_vectors(polymorphic::vectorfield< VReal, 3 > const &vf, polymorphic::vectorfield< WReal, 3 > const &wf, rectilinear_grid< XDomain, YDomain, ZDomain > const &g, TReal const t, execution_policy_tag auto const policy, Preds &&... preds)
This is an implementation of .
Definition: parallel_vectors.h:1043
Definition: vtp_writer.h:3
auto constexpr turned(integral auto const ... is) -> bool
Definition: parallel_vectors.h:211
constexpr auto pv_on_tri(Vec3< Real > const &p0, Vec3< Real > const &v0, Vec3< Real > const &w0, Vec3< Real > const &p1, Vec3< Real > const &v1, Vec3< Real > const &w1, Vec3< Real > const &p2, Vec3< Real > const &v2, Vec3< Real > const &w2, Preds &&... preds) -> std::optional< Vec3< Real > >
Definition: parallel_vectors.h:103
auto check_unturned_cube(auto const &x_faces, auto const &y_faces, auto const &z_faces, auto const &inner_faces, auto &ls, auto const ix, auto const iy)
Definition: parallel_vectors.h:250
auto check_cube(auto const &x_faces, auto const &y_faces, auto const &z_faces, auto const &inner_faces, auto &ls, auto const ix, auto const iy, auto const iz)
Definition: parallel_vectors.h:285
auto calc_parallel_vectors(GetV &&getv, GetW &&getw, tatooine::rectilinear_grid< XDomain, YDomain, ZDomain > const &g, execution_policy::parallel_t const policy, Preds &&... preds) -> std::vector< Line3< Real > >
Definition: parallel_vectors.h:307
auto constexpr is_even(integral auto const i)
Definition: parallel_vectors.h:204
static auto check_tet(std::optional< Vec3< Real > > const &tri0, std::optional< Vec3< Real > > const &tri1, std::optional< Vec3< Real > > const &tri2, std::optional< Vec3< Real > > const &tri3, std::vector< Line3< Real > > &lines)
Definition: parallel_vectors.h:173
auto check_turned_cube(auto const &x_faces, auto const &y_faces, auto const &z_faces, auto const &inner_faces, auto &ls, auto const ix, auto const iy)
Definition: parallel_vectors.h:215
auto constexpr sign(bool pred) -> Int
Definition: parallel_vectors.h:207
static constexpr sequential_t sequential
Definition: tags.h:63
static constexpr parallel_t parallel
Definition: tags.h:60
Definition: algorithm.h:6
auto real(base_tensor< Tensor, std::complex< T >, Dims... > const &t)
Definition: complex_tensor_views.h:173
constexpr auto isnan(base_tensor< Tensor, Real, Dims... > const &t) -> bool
Definition: tensor_utility.h:25
auto solve(polynomial< Real, 1 > const &p) -> std::vector< Real >
solve a + b*x
Definition: polynomial.h:187
constexpr auto approx_equal(T0 const &lhs, T1 const &rhs, common_type< tatooine::value_type< T0 >, tatooine::value_type< T1 > > eps=1e-6)
for comparison
Definition: tensor_utility.h:11
auto merge(Lines const &unmerged_lines, Eps const eps=1e-13)
Merges a set of lines and combines lines with equal vertex endings.
Definition: merge.h:165
constexpr auto sum(base_tensor< Tensor, T, VecDim > const &v)
sum of all components of a vector
Definition: tensor_operations.h:110
auto imag(base_tensor< Tensor, std::complex< T >, Dims... > const &tensor)
Definition: complex_tensor_views.h:86
auto for_loop_num_parallel_threads()
Definition: for_loop.h:30
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
constexpr auto det(base_tensor< Tensor, T, 2, 2 > const &A) -> T
Definition: determinant.h:7
auto eigenvectors(Mat &&B)
Definition: eigenvalues.h:123
Definition: axis_aligned_bounding_box.h:103
auto constexpr max() const -> auto const &
Definition: axis_aligned_bounding_box.h:156
auto constexpr min() const -> auto const &
Definition: axis_aligned_bounding_box.h:151
Definition: linspace.h:26
auto constexpr col(std::size_t i)
Definition: mat.h:175