17#include <boost/preprocessor/seq/for_each.hpp>
27using namespace literals;
28using utils::operator+;
37#define IGANET_FUNCTIONSPACE_DEFAULT_OPS(FunctionSpace) \
38 FunctionSpace() = default; \
39 FunctionSpace(FunctionSpace &&) = default; \
40 FunctionSpace(const FunctionSpace &) = default;
48 { t.template find_knot_indices<functionspace::interior>(x) };
55 { t.template find_coeff_indices<functionspace::interior>(x) };
68template <
typename... Splines,
typename... Boundaries>
77 using value_type = std::common_type_t<
typename Splines::value_type...>;
94 template <std::
size_t index>
96 static_assert(index <
nspaces());
97 return std::tuple_element_t<index, spline_type>::geoDim();
103 template <std::
size_t index>
105 static_assert(index <
nspaces());
106 return std::tuple_element_t<index, spline_type>::parDim();
113 template <std::
size_t index>
114 inline static constexpr const auto&
degrees() noexcept {
115 static_assert(index <
nspaces());
116 return std::tuple_element_t<index, spline_type>::degrees();
124 template <std::
size_t index>
126 static_assert(index <
nspaces());
127 return std::tuple_element_t<index, spline_type>::degree(i);
153 const std::array<int64_t, Splines::parDim()> &...ncoeffs,
166 const std::array<std::vector<typename Splines::value_type>,
167 Splines::parDim()> &...kv,
173 static_assert((Splines::is_nonuniform() && ... &&
true),
174 "Constructor is only available for non-uniform splines");
195 const std::tuple<Boundaries...> &
boundary)
202 std::tuple<Boundaries...> &&
boundary)
208 inline static constexpr std::size_t
nspaces() noexcept {
209 return sizeof...(Splines);
215 return sizeof...(Boundaries);
237 template <std::
size_t index>
inline const auto &
space() const noexcept {
238 static_assert(index <
nspaces());
239 return std::get<index>(
spline_);
245 template <std::
size_t index>
inline auto &
space() noexcept {
246 static_assert(index <
nspaces());
247 return std::get<index>(
spline_);
253 template <std::
size_t index>
inline const auto &
boundary() const noexcept {
262 template <std::
size_t index>
inline auto &
boundary() noexcept {
274 template <std::size_t... index>
inline auto clone() const noexcept {
276 static_assert(((index <
nspaces()) && ... &&
true));
279 std::tuple<std::tuple_element_t<index, spline_type>...>,
280 std::tuple<std::tuple_element_t<index, boundary_type>...>>(
281 std::make_tuple(std::get<index>(
spline_)...),
282 std::make_tuple(std::get<index>(
boundary_)...));
288 template <std::size_t... Is>
291 return torch::cat({std::get<Is>(
spline_).as_tensor()...});
299 return spaces_as_tensor_(
300 std::make_index_sequence<FunctionSpace::nspaces()>{});
306 template <std::size_t... Is>
309 return torch::cat({std::get<Is>(
boundary_).as_tensor()...});
317 return boundary_as_tensor_(
318 std::make_index_sequence<FunctionSpace::nboundaries()>{});
327 virtual inline torch::Tensor
as_tensor() const noexcept {
334 template <std::size_t... Is>
338 [](
auto... v) {
return (v + ...); },
347 return spaces_as_tensor_size_(
348 std::make_index_sequence<FunctionSpace::nspaces()>{});
354 template <std::size_t... Is>
358 [](
auto... v) {
return (v + ...); },
367 return boundary_as_tensor_size_(
368 std::make_index_sequence<FunctionSpace::nboundaries()>{});
383 template <std::size_t... Is>
385 const torch::Tensor &tensor) {
388 std::array<int64_t,
sizeof...(Is)> partialSums{0};
389 auto partial_sums = [&partialSums,
390 this]<std::size_t... Js>(std::index_sequence<Js...>) {
391 ((std::get<Js + 1>(partialSums) =
392 std::get<Js>(partialSums) + std::get<Js>(
spline_).as_tensor_size()),
395 partial_sums(std::make_index_sequence<FunctionSpace::nspaces() - 1>{});
398 ((std::get<Is>(
spline_).from_tensor(tensor.index(
399 {torch::indexing::Slice(partialSums[Is],
401 std::get<Is>(spline_).as_tensor_size()),
414 return spaces_from_tensor_(
415 std::make_index_sequence<FunctionSpace::nspaces()>{}, tensor);
421 template <std::size_t... Is>
423 const torch::Tensor &tensor) {
437 return boundary_from_tensor_(
438 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
443 template <std::size_t... Is>
446 const torch::Tensor &tensor) {
447 (std::get<Is>(
boundary_).from_full_tensor(
460 return boundary_from_full_tensor_(
461 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
468 spaces_from_tensor_(std::make_index_sequence<FunctionSpace::nspaces()>{},
470 boundary_from_full_tensor_(
471 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
477 template <std::size_t... Is>
478 inline pugi::xml_node &
to_xml_(std::index_sequence<Is...>,
479 pugi::xml_node &root,
int id = 0,
480 const std::string &label =
"")
const {
482 (std::get<Is>(
spline_).to_xml(root,
id, label, Is), ...);
491 inline pugi::xml_document
to_xml(
int id = 0,
492 const std::string &label =
"")
const {
493 pugi::xml_document doc;
494 pugi::xml_node root = doc.append_child(
"xml");
505 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
506 const std::string &label =
"")
const {
507 return to_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
513 template <std::size_t... Is>
515 const pugi::xml_node &root,
int id = 0,
516 const std::string &label =
"") {
518 (std::get<Is>(
spline_).from_xml(root,
id, label, Is), ...);
529 const std::string &label =
"") {
530 return from_xml(doc.child(
"xml"),
id, label);
539 const std::string &label =
"") {
540 return from_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
546 template <std::size_t... Is>
547 nlohmann::json
to_json_(std::index_sequence<Is...>)
const {
548 auto json_this = nlohmann::json::array();
549 auto json_boundary = nlohmann::json::array();
551 (json_boundary.push_back(std::get<Is>(
boundary_).to_json()), ...);
553 auto json = nlohmann::json::array();
554 for (
auto [t, b] :
utils::zip(json_this, json_boundary)) {
555 auto json_inner = nlohmann::json::array();
556 json_inner.push_back(t);
557 json_inner.push_back(b);
558 json.push_back(json_inner);
568 return to_json_(std::make_index_sequence<FunctionSpace::nspaces()>{});
576 template <
typename SplinesOther,
typename BoundariesOther>
581 if (!std::is_same_v<
spline_type,
typename std::remove_cvref_t<
598 std::size_t... Is,
typename... Xi>
599 inline auto eval_(std::index_sequence<Is...>,
600 const std::tuple<Xi...> &xi)
const {
603 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
604 std::get<Is>(xi))...);
607 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
608 std::get<Is>(xi))...);
613 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
614 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
615 const std::tuple<Knot_Indices...> &knot_indices)
const {
618 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
619 std::get<Is>(xi), std::get<Is>(knot_indices))...);
622 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
623 std::get<Is>(xi), std::get<Is>(knot_indices))...);
628 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
629 typename... Coeff_Indices>
630 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
631 const std::tuple<Knot_Indices...> &knot_indices,
632 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
635 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
636 std::get<Is>(xi), std::get<Is>(knot_indices),
637 std::get<Is>(coeff_indices))...);
640 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
641 std::get<Is>(xi), std::get<Is>(knot_indices),
642 std::get<Is>(coeff_indices))...);
654 inline auto eval(
const std::tuple<Xi...> &xi)
const {
655 static_assert(FunctionSpace::nspaces() ==
sizeof...(Xi),
656 "Size of Xi mismatches functionspace dimension");
657 return eval_<comp, deriv, memory_optimized>(
658 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
667 typename... Xi,
typename... Knot_Indices>
668 inline auto eval(
const std::tuple<Xi...> &xi,
669 const std::tuple<Knot_Indices...> &knot_indices)
const {
671 (FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
672 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)),
673 "Sizes of Xi and Knot_Indices mismatch functionspace dimension");
674 return eval_<comp, deriv, memory_optimized>(
675 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
685 typename... Xi,
typename... Knot_Indices,
typename... Coeff_Indices>
686 inline auto eval(
const std::tuple<Xi...> &xi,
687 const std::tuple<Knot_Indices...> &knot_indices,
688 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
689 static_assert((FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
690 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)) &&
691 (FunctionSpace::nspaces() ==
sizeof...(Coeff_Indices)),
692 "Sizes of Xi, Knot_Indices and Coeff_Indices mismatch "
693 "functionspace dimension");
694 return eval_<comp, deriv, memory_optimized>(
695 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices,
705 typename... Basfunc,
typename... Coeff_Indices,
typename... Numeval,
709 const std::tuple<Basfunc...> &basfunc,
710 const std::tuple<Coeff_Indices...> &coeff_indices,
711 const std::tuple<Numeval...> &numeval,
712 const std::tuple<Sizes...> &sizes)
const {
714 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
715 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
716 std::get<Is>(numeval), std::get<Is>(sizes))...);
718 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
719 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
720 std::get<Is>(numeval), std::get<Is>(sizes))...);
724 typename... Basfunc,
typename... Coeff_Indices,
typename... Xi>
727 const std::tuple<Basfunc...> &basfunc,
728 const std::tuple<Coeff_Indices...> &coeff_indices,
729 const std::tuple<Xi...> &xi)
const {
731 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
732 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
733 std::get<Is>(xi)[0].numel(), std::get<Is>(xi)[0].sizes())...);
735 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
736 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
737 std::get<Is>(xi))...);
751 typename... Coeff_Indices,
typename... Numeval,
typename... Sizes>
754 const std::tuple<Coeff_Indices...> &coeff_indices,
755 const std::tuple<Numeval...> &numeval,
756 const std::tuple<Sizes...> &sizes)
const {
757 return eval_from_precomputed_<comp>(
758 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
759 coeff_indices, numeval, sizes);
768 typename... Coeff_Indices,
typename... Xi>
771 const std::tuple<Coeff_Indices...> &coeff_indices,
772 const std::tuple<Xi...> &xi)
const {
773 return eval_from_precomputed_<comp>(
774 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
787 return std::tuple(std::get<Is>(
spline_).find_knot_indices(xi)...);
789 return std::tuple(std::get<Is>(
boundary_).find_knot_indices(xi)...);
795 const std::tuple<Xi...> &xi)
const {
798 std::get<Is>(
spline_).find_knot_indices(std::get<Is>(xi))...);
801 std::get<Is>(
boundary_).find_knot_indices(std::get<Is>(xi))...);
811 template <functionspace comp = functionspace::
interior>
813 return find_knot_indices_<comp>(
814 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
824 return find_knot_indices_<comp>(
825 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
835 std::size_t... Is,
typename... Xi>
837 const std::tuple<Xi...> &xi)
const {
840 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
841 std::get<Is>(xi))...);
843 return std::tuple(std::get<Is>(
boundary_)
844 .template eval_basfunc<deriv, memory_optimized>(
845 std::get<Is>(xi))...);
850 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
853 const std::tuple<Knot_Indices...> &knot_indices)
const {
856 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
857 std::get<Is>(xi), std::get<Is>(knot_indices))...);
861 .template eval_basfunc<deriv, memory_optimized>(
862 std::get<Is>(xi), std::get<Is>(knot_indices))...);
875 return eval_basfunc_<comp, deriv, memory_optimized>(
876 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
885 typename... Xi,
typename... Knot_Indices>
888 const std::tuple<Knot_Indices...> &knot_indices)
const {
889 return eval_basfunc_<comp, deriv, memory_optimized>(
890 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
898 bool memory_optimized =
false, std::size_t... Is,
899 typename... Knot_Indices>
902 const std::tuple<Knot_Indices...> &knot_indices)
const {
905 std::get<Is>(
spline_).template find_coeff_indices<memory_optimized>(
906 std::get<Is>(knot_indices))...);
909 std::get<Is>(
boundary_).template find_coeff_indices<memory_optimized>(
910 std::get<Is>(knot_indices))...);
919 bool memory_optimized =
false,
typename... Knot_Indices>
922 return find_coeff_indices_<comp, memory_optimized>(
923 std::make_index_sequence<FunctionSpace::nspaces()>{}, knot_indices);
929 template <std::size_t... Is, std::size_t... Js>
931 std::index_sequence<Js...>,
int numRefine = 1,
932 int dimRefine = -1) {
933 (std::get<Is>(
spline_).uniform_refine(numRefine, dimRefine), ...);
934 (std::get<Js>(
boundary_).uniform_refine(numRefine, dimRefine), ...);
945 return uniform_refine_(
946 std::make_index_sequence<FunctionSpace::nspaces()>{},
947 std::make_index_sequence<FunctionSpace::nboundaries()>{}, numRefine,
954 template <
typename real_t, std::size_t... Is, std::size_t... Js>
955 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
958 typename Splines::template real_derived_self_type<real_t>...,
959 typename Boundaries::template real_derived_self_type<real_t>...>(
960 std::get<Is>(
spline_).to(options)...,
971 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
972 std::make_index_sequence<FunctionSpace::nboundaries()>{},
979 template <std::size_t... Is, std::size_t... Js>
980 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
981 torch::Device device)
const {
991 inline auto to(torch::Device device)
const {
992 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
993 std::make_index_sequence<FunctionSpace::nboundaries()>{},
999 template <
typename real_t, std::size_t... Is, std::size_t... Js>
1000 inline auto to_(std::index_sequence<Is...>,
1001 std::index_sequence<Js...>)
const {
1003 typename Splines::template real_derived_self_type<real_t>...,
1004 typename Boundaries::template real_derived_self_type<real_t>...>(
1005 std::get<Is>(
spline_).template to<real_t>()...,
1006 std::get<Js>(
boundary_).template to<real_t>()...);
1013 template <
typename real_t>
inline auto to()
const {
1015 std::make_index_sequence<FunctionSpace::nspaces()>{},
1016 std::make_index_sequence<FunctionSpace::nboundaries()>{});
1021 template <std::size_t... Is>
1023 (std::get<Is>(
spline_).scale(s, dim), ...);
1034 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, s, dim);
1039 template <std::size_t N, std::size_t... Is>
1040 inline auto scale_(std::index_sequence<Is...>, std::array<value_type, N> v) {
1041 (std::get<Is>(
spline_).scale(v), ...);
1042 (std::get<Is>(
boundary_).from_full_tensor(
1053 template <std::
size_t N>
inline auto scale(std::array<value_type, N> v) {
1054 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
1059 template <std::size_t N, std::size_t... Is>
1061 std::array<value_type, N> v) {
1062 (std::get<Is>(
spline_).translate(v), ...);
1063 (std::get<Is>(
boundary_).from_full_tensor(
1074 template <std::
size_t N>
inline auto translate(std::array<value_type, N> v) {
1075 return translate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
1080 template <std::size_t... Is>
1082 (std::get<Is>(
spline_).rotate(angle), ...);
1083 (std::get<Is>(
boundary_).from_full_tensor(
1094 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
1099 template <std::size_t... Is>
1101 std::array<value_type, 3> angle) {
1102 (std::get<Is>(
spline_).rotate(angle), ...);
1103 (std::get<Is>(
boundary_).from_full_tensor(
1113 inline auto rotate(std::array<value_type, 3> angle) {
1114 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
1119 template <std::size_t... Is>
1121 return std::tuple(std::get<Is>(
spline_).boundingBox()...);
1128 return boundingBox_(std::make_index_sequence<FunctionSpace::nspaces()>{});
1134 template <std::size_t... Is>
1135 inline torch::serialize::OutputArchive &
1136 write_(std::index_sequence<Is...>, torch::serialize::OutputArchive &archive,
1137 const std::string &key =
"functionspace")
const {
1139 archive, key +
".fspace[" + std::to_string(Is) +
"].interior"),
1142 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
1153 inline torch::serialize::OutputArchive &
1154 write(torch::serialize::OutputArchive &archive,
1155 const std::string &key =
"functionspace")
const {
1156 write_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
1163 template <std::size_t... Is>
1164 inline torch::serialize::InputArchive &
1165 read_(std::index_sequence<Is...>, torch::serialize::InputArchive &archive,
1166 const std::string &key =
"functionspace") {
1167 (std::get<Is>(
spline_).read(archive, key +
".fspace[" + std::to_string(Is) +
1171 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
1182 inline torch::serialize::InputArchive &
1183 read(torch::serialize::InputArchive &archive,
1184 const std::string &key =
"functionspace") {
1185 read_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
1193 auto pretty_print_ = [
this,
1194 &os]<std::size_t... Is>(std::index_sequence<Is...>) {
1195 ((os <<
"\ninterior = ", std::get<Is>(
spline_).pretty_print(os),
1196 os <<
"\nboundary = ", std::get<Is>(
boundary_).pretty_print(os)),
1200 pretty_print_(std::make_index_sequence<
nspaces()>{});
1225 bool memory_optimized =
false>
1227 return curl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1235 bool memory_optimized =
false,
typename... TensorArrays>
1237 const std::tuple<TensorArrays...> &knot_indices)
const {
1238 return curl<comp, memory_optimized>(xi, knot_indices,
1239 find_coeff_indices<comp>(knot_indices));
1248 bool memory_optimized =
false>
1250 const std::tuple<utils::TensorArray1> &knot_indices,
1251 const std::tuple<torch::Tensor> &coeff_indices)
const {
1253 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1255 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1261 bool memory_optimized =
false>
1264 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1265 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1267 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1268 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1269 xi[0].sizes() == xi[1].sizes());
1277 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1278 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1279 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1280 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1284 bool memory_optimized =
false>
1288 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1289 &coeff_indices)
const {
1291 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1292 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1293 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1294 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1300 *std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1301 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] -
1302 *std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1303 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1304 *std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1305 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] -
1306 *std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1307 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1308 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1309 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1310 *std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1311 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1320 bool memory_optimized =
false>
1325 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1326 torch::Tensor> &coeff_indices)
const {
1328 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1329 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1330 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1331 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1332 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1333 xi[2].sizes() == xi[3].sizes());
1335 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1361 bool memory_optimized =
false>
1363 return div<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1371 bool memory_optimized =
false,
typename... TensorArrays>
1373 const std::tuple<TensorArrays...> &knot_indices)
const {
1374 return div<comp, memory_optimized>(xi, knot_indices,
1375 find_coeff_indices<comp>(knot_indices));
1384 bool memory_optimized =
false>
1386 const std::tuple<utils::TensorArray1> &knot_indices,
1387 const std::tuple<torch::Tensor> &coeff_indices)
const {
1389 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1392 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1393 "div(.) for vector-valued spaces requires 1D variables");
1396 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1397 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1407 bool memory_optimized =
false>
1410 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1411 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1413 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1414 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1415 xi[0].sizes() == xi[1].sizes());
1418 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1419 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1420 "div(.) for vector-valued spaces requires 1D variables");
1423 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1424 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1425 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1426 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1436 bool memory_optimized =
false>
1440 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1441 &coeff_indices)
const {
1443 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1444 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1445 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1446 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1449 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1450 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1451 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1452 "div(.) for vector-valued spaces requires 1D variables");
1455 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1456 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1457 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1458 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1459 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1460 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1470 bool memory_optimized =
false>
1475 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1476 torch::Tensor> &coeff_indices)
const {
1478 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1479 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1480 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1481 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1482 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1483 xi[2].sizes() == xi[3].sizes());
1486 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1487 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1488 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1489 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1490 "div(.) for vector-valued spaces requires 1D variables");
1493 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1494 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1495 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1496 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1497 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1498 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
1499 *std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1500 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1523 bool memory_optimized =
false>
1525 return grad<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1533 bool memory_optimized =
false,
typename... TensorArrays>
1535 const std::tuple<TensorArrays...> &knot_indices)
const {
1536 return grad<comp, memory_optimized>(xi, knot_indices,
1537 find_coeff_indices<comp>(knot_indices));
1546 bool memory_optimized =
false>
1548 const std::tuple<utils::TensorArray1> &knot_indices,
1549 const std::tuple<torch::Tensor> &coeff_indices)
const {
1551 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1554 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1555 "grad(.) for vector-valued spaces requires 1D variables");
1558 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1559 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1569 bool memory_optimized =
false>
1572 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1573 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1575 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1576 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1577 xi[0].sizes() == xi[1].sizes());
1580 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1581 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1582 "grad(.) for vector-valued spaces requires 1D variables");
1585 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1586 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1587 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1588 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1598 bool memory_optimized =
false>
1602 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1603 &coeff_indices)
const {
1605 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1606 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1607 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1608 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1611 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1612 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1613 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1614 "div(.) for vector-valued spaces requires 1D variables");
1617 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1618 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1619 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1620 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1621 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1622 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1632 bool memory_optimized =
false>
1637 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1638 torch::Tensor> &coeff_indices)
const {
1640 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1641 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1642 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1643 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1644 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1645 xi[2].sizes() == xi[3].sizes());
1648 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1649 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1650 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1651 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1652 "grad(.) for vector-valued spaces requires 1D variables");
1655 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1656 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1657 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1658 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1659 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1660 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1661 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1662 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1704 bool memory_optimized =
false>
1706 return hess<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1714 bool memory_optimized =
false,
typename... TensorArrays>
1716 const std::tuple<TensorArrays...> &knot_indices)
const {
1717 return hess<comp, memory_optimized>(xi, knot_indices,
1718 find_coeff_indices<comp>(knot_indices));
1727 bool memory_optimized =
false>
1729 const std::tuple<utils::TensorArray1> &knot_indices,
1730 const std::tuple<torch::Tensor> &coeff_indices)
const {
1732 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1735 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1736 "hess(.) for vector-valued spaces requires 1D variables");
1739 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1740 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)));
1750 bool memory_optimized =
false>
1753 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1754 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1756 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1757 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1758 xi[0].sizes() == xi[1].sizes());
1761 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1762 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1763 "hess(.) for vector-valued spaces requires 1D variables");
1766 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1767 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1769 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1770 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1772 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1773 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1774 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1775 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1777 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1778 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1780 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1781 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1783 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1784 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1785 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1786 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)));
1796 bool memory_optimized =
false>
1800 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1801 &coeff_indices)
const {
1803 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1804 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1805 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1806 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1809 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1810 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1811 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1812 "hess(.) for vector-valued spaces requires 1D variables");
1815 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1816 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1818 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1819 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1821 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1822 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1824 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1825 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1826 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1827 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1829 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1830 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1832 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1833 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1835 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1836 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1837 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1838 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1840 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1841 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1843 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1844 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1846 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1847 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1849 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1850 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1851 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1852 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1854 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1855 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1857 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1858 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1860 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1861 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1862 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1863 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1865 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1866 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1868 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1869 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1871 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1872 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1874 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1875 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1876 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1877 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1879 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1880 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1882 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1883 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1885 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1886 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1887 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1888 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)));
1898 bool memory_optimized =
false>
1903 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1904 torch::Tensor> &coeff_indices)
const {
1906 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1907 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1908 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1909 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1910 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1911 xi[2].sizes() == xi[3].sizes());
1914 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1915 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1916 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1917 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1918 "hess(.) for vector-valued spaces requires 1D variables");
1921 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1922 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1924 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1925 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1927 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1928 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1930 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1931 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1933 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1934 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1935 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1936 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1938 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1939 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1941 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1942 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1944 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1945 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1947 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1948 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1949 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1950 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1952 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1953 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1955 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1956 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1958 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1959 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1961 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1962 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1963 std::get<0>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1964 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1966 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1967 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1969 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1970 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1972 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1973 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1975 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1976 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1978 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1979 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1980 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1981 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1983 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1984 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1986 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1987 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1989 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1990 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1992 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1993 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1994 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1995 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1997 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1998 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
2000 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
2001 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
2003 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
2004 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
2006 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
2007 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
2008 std::get<1>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
2009 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
2011 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2012 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2014 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
2015 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2017 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
2018 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2020 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
2021 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2023 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
2024 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2025 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2026 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2028 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
2029 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2031 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
2032 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2034 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
2035 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2037 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
2038 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2039 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2040 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2042 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
2043 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2045 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
2046 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2048 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
2049 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2051 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
2052 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2053 std::get<2>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
2054 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
2056 std::get<3>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2057 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2059 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
2060 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2062 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
2063 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2065 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
2066 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2068 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
2069 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2070 std::get<3>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2071 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2073 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
2074 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2076 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
2077 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2079 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
2080 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2082 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
2083 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2084 std::get<3>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2085 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2087 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
2088 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2090 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
2091 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2093 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
2094 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2096 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
2097 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
2098 std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
2099 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)));
2136 bool memory_optimized =
false>
2138 return jac<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
2146 bool memory_optimized =
false,
typename... TensorArrays>
2148 const std::tuple<TensorArrays...> &knot_indices)
const {
2149 return jac<comp, memory_optimized>(xi, knot_indices,
2150 find_coeff_indices<comp>(knot_indices));
2159 bool memory_optimized =
false>
2161 const std::tuple<utils::TensorArray1> &knot_indices,
2162 const std::tuple<torch::Tensor> &coeff_indices)
const {
2164 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
2167 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
2168 "jac(.) for vector-valued spaces requires 1D variables");
2171 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
2172 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
2182 bool memory_optimized =
false>
2185 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
2186 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
2188 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2189 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2190 xi[0].sizes() == xi[1].sizes());
2193 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2194 std::tuple_element_t<1, spline_type>::geoDim() == 1,
2195 "jac(.) for vector-valued spaces requires 1D variables");
2198 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
2199 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2200 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
2201 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2203 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
2204 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2205 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
2206 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
2216 bool memory_optimized =
false>
2220 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
2221 &coeff_indices)
const {
2223 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2224 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2225 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2226 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
2229 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2230 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2231 std::tuple_element_t<2, spline_type>::geoDim() == 1,
2232 "jac(.) for vector-valued spaces requires 1D variables");
2235 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
2236 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2237 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
2238 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2239 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
2240 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2242 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
2243 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2244 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
2245 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2246 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
2247 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2249 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
2250 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2251 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
2252 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2253 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
2254 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
2264 bool memory_optimized =
false>
2269 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
2270 torch::Tensor> &coeff_indices)
const {
2272 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2273 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2274 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2275 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
2276 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
2277 xi[2].sizes() == xi[3].sizes());
2280 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2281 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2282 std::tuple_element_t<2, spline_type>::geoDim() == 1,
2283 "jac(.) for vector-valued spaces requires 1D variables");
2286 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
2287 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2288 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
2289 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2290 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
2291 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2292 std::get<0>(
spline_).
template eval<deriv::dt, memory_optimized>(
2293 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2295 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
2296 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2297 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
2298 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2299 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
2300 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2301 std::get<1>(
spline_).
template eval<deriv::dt, memory_optimized>(
2302 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2304 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
2305 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2306 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
2307 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2308 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
2309 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2310 std::get<2>(
spline_).
template eval<deriv::dt, memory_optimized>(
2311 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2313 std::get<3>(
spline_).
template eval<deriv::dx, memory_optimized>(
2314 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2315 std::get<3>(
spline_).
template eval<deriv::dy, memory_optimized>(
2316 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2317 std::get<3>(
spline_).
template eval<deriv::dz, memory_optimized>(
2318 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2319 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
2320 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2346 bool memory_optimized =
false>
2348 return lapl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
2356 bool memory_optimized =
false,
typename... TensorArrays>
2358 const std::tuple<TensorArrays...> &knot_indices)
const {
2359 return lapl<comp, memory_optimized>(xi, knot_indices,
2360 find_coeff_indices<comp>(knot_indices));
2369 bool memory_optimized =
false>
2371 const std::tuple<utils::TensorArray1> &knot_indices,
2372 const std::tuple<torch::Tensor> &coeff_indices)
const {
2374 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
2377 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
2378 "lapl(.) for vector-valued spaces requires 1D variables");
2381 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2382 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
2392 bool memory_optimized =
false>
2395 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
2396 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
2398 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2399 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2400 xi[0].sizes() == xi[1].sizes());
2403 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2404 std::tuple_element_t<1, spline_type>::geoDim() == 1,
2405 "lapl(.) for vector-valued spaces requires 1D variables");
2408 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2409 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2410 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2411 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
2421 bool memory_optimized =
false>
2425 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
2426 &coeff_indices)
const {
2428 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2429 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2430 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2431 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
2434 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2435 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2436 std::tuple_element_t<2, spline_type>::geoDim() == 1,
2437 "div(.) for vector-valued spaces requires 1D variables");
2440 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2441 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2442 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2443 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2444 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2445 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
2455 bool memory_optimized =
false>
2460 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
2461 torch::Tensor> &coeff_indices)
const {
2463 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2464 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2465 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2466 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
2467 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
2468 xi[2].sizes() == xi[3].sizes());
2471 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2472 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2473 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
2474 std::tuple_element_t<3, spline_type>::geoDim() == 1,
2475 "div(.) for vector-valued spaces requires 1D variables");
2478 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2479 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2480 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2481 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2482 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2483 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
2484 *std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
2485 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2490#define GENERATE_EXPR_MACRO(r, data, name) \
2492 template <functionspace comp = functionspace::interior, \
2493 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
2494 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2495 const std::tuple<Xi...> &xi) const { \
2496 if constexpr (comp == functionspace::interior) \
2497 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2498 std::get<Is>(xi))...); \
2499 else if constexpr (comp == functionspace::boundary) \
2500 return std::tuple( \
2501 std::get<Is>(boundary_).template name<memory_optimized>( \
2502 std::get<Is>(xi))...); \
2505 template <functionspace comp = functionspace::interior, \
2506 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2507 typename... Knot_Indices> \
2508 inline auto BOOST_PP_CAT(name, _all_)( \
2509 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2510 const std::tuple<Knot_Indices...> &knot_indices) const { \
2511 if constexpr (comp == functionspace::interior) \
2512 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2513 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2514 else if constexpr (comp == functionspace::boundary) \
2515 return std::tuple( \
2516 std::get<Is>(boundary_).template name<memory_optimized>( \
2517 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2520 template <functionspace comp = functionspace::interior, \
2521 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2522 typename... Knot_Indices, typename... Coeff_Indices> \
2523 inline auto BOOST_PP_CAT(name, _all_)( \
2524 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2525 const std::tuple<Knot_Indices...> &knot_indices, \
2526 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
2527 if constexpr (comp == functionspace::interior) \
2528 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2529 std::get<Is>(xi), std::get<Is>(knot_indices), \
2530 std::get<Is>(coeff_indices))...); \
2531 else if constexpr (comp == functionspace::boundary) \
2532 return std::tuple( \
2533 std::get<Is>(boundary_).template name<memory_optimized>( \
2534 std::get<Is>(xi), std::get<Is>(knot_indices), \
2535 std::get<Is>(coeff_indices))...); \
2538 template <functionspace comp = functionspace::interior, \
2539 bool memory_optimized = false, std::size_t... Is, std::size_t N> \
2540 inline auto BOOST_PP_CAT(name, _)(std::index_sequence<Is...>, \
2541 const utils::TensorArray<N> &xi) const { \
2542 if constexpr (comp == functionspace::interior) \
2543 return name<comp, memory_optimized>( \
2544 xi, std::tuple(std::get<Is>(spline_).find_knot_indices(xi)...)); \
2545 else if constexpr (comp == functionspace::boundary) \
2546 return name<comp, memory_optimized>( \
2547 xi, std::tuple(std::get<Is>(boundary_).find_knot_indices(xi)...)); \
2550 template <functionspace comp = functionspace::interior, \
2551 bool memory_optimized = false, std::size_t... Is, std::size_t N, \
2552 typename... Knot_Indices> \
2553 inline auto BOOST_PP_CAT(name, _)( \
2554 std::index_sequence<Is...>, const utils::TensorArray<N> &xi, \
2555 const std::tuple<Knot_Indices...> &knot_indices) const { \
2556 if constexpr (comp == functionspace::interior) \
2557 return name<comp, memory_optimized>( \
2559 std::tuple(std::get<Is>(spline_).find_coeff_indices( \
2560 std::get<Is>(knot_indices))...)); \
2561 else if constexpr (comp == functionspace::boundary) \
2562 return name<comp, memory_optimized>( \
2564 std::tuple(std::get<Is>(boundary_).find_coeff_indices( \
2565 std::get<Is>(knot_indices))...)); \
2569 template <functionspace comp = functionspace::interior, \
2570 bool memory_optimized = false, typename... Args> \
2571 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2572 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2573 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2576 template <functionspace comp = functionspace::interior, \
2577 bool memory_optimized = false> \
2578 inline auto name(const torch::Tensor &xi) const { \
2579 return name<comp, memory_optimized>(utils::TensorArray1({xi})); \
2582 template <functionspace comp = functionspace::interior, \
2583 bool memory_optimized = false, std::size_t N> \
2584 inline auto name(const utils::TensorArray<N> &xi) const { \
2585 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2586 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi); \
2589 template <functionspace comp = functionspace::interior, \
2590 bool memory_optimized = false, std::size_t N, \
2591 typename... Knot_Indices> \
2592 inline auto name(const utils::TensorArray<N> &xi, \
2593 const std::tuple<Knot_Indices...> &knot_indices) const { \
2594 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2595 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, \
2603#undef GENERATE_EXPR_MACRO
2605#define GENERATE_IEXPR_MACRO(r, data, name) \
2607 template <functionspace comp = functionspace::interior, \
2608 bool memory_optimized = false, std::size_t... Is, \
2609 typename Geometry, typename... Xi> \
2610 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2611 const Geometry &G, \
2612 const std::tuple<Xi...> &xi) const { \
2613 if constexpr (comp == functionspace::interior) { \
2614 if constexpr (Geometry::nspaces() == 1) \
2615 return std::tuple( \
2616 std::get<Is>(spline_).template name<memory_optimized>( \
2617 G.space(), std::get<Is>(xi))...); \
2618 else if constexpr (Geometry::nspaces() == nspaces()) \
2619 return std::tuple( \
2620 std::get<Is>(spline_).template name<memory_optimized>( \
2621 G.template space<Is>(), std::get<Is>(xi))...); \
2622 } else if constexpr (comp == functionspace::boundary) { \
2623 if constexpr (Geometry::nboundaries() == 1) \
2624 return std::tuple( \
2625 std::get<Is>(boundary_).template name<memory_optimized>( \
2626 static_cast<typename Geometry::boundary_type::boundary_type>( \
2627 G.boundary().coeffs()), \
2628 std::get<Is>(xi))...); \
2629 else if constexpr (Geometry::nboundaries() == nboundaries()) \
2630 return std::tuple( \
2631 std::get<Is>(boundary_).template name<memory_optimized>( \
2632 G.template boundary<Is>().coeffs(), std::get<Is>(xi))...); \
2636 template <functionspace comp = functionspace::interior, \
2637 bool memory_optimized = false, std::size_t... Is, \
2638 typename Geometry, typename... Xi, typename... Knot_Indices, \
2639 typename... Knot_Indices_G> \
2640 inline auto BOOST_PP_CAT(name, _all_)( \
2641 std::index_sequence<Is...>, const Geometry &G, \
2642 const std::tuple<Xi...> &xi, \
2643 const std::tuple<Knot_Indices...> &knot_indices, \
2644 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
2645 if constexpr (comp == functionspace::interior) { \
2646 if constexpr (Geometry::nspaces() == 1) \
2647 return std::tuple( \
2648 std::get<Is>(spline_).template name<memory_optimized>( \
2649 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2650 std::get<Is>(knot_indices_G))...); \
2652 return std::tuple( \
2653 std::get<Is>(spline_).template name<memory_optimized>( \
2654 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2655 std::get<Is>(knot_indices_G))...); \
2656 } else if constexpr (comp == functionspace::boundary) { \
2657 if constexpr (Geometry::nspaces() == 1) \
2658 return std::tuple( \
2659 std::get<Is>(boundary_).template name<memory_optimized>( \
2660 static_cast<typename Geometry::boundary_type::boundary_type>( \
2661 G.boundary().coeffs()), \
2662 std::get<Is>(xi), std::get<Is>(knot_indices), \
2663 std::get<Is>(knot_indices_G))...); \
2665 return std::tuple( \
2666 std::get<Is>(boundary_).template name<memory_optimized>( \
2667 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2668 std::get<Is>(knot_indices), std::get<Is>(knot_indices_G))...); \
2672 template <functionspace comp = functionspace::interior, \
2673 bool memory_optimized = false, std::size_t... Is, \
2674 typename Geometry, typename... Xi, typename... Knot_Indices, \
2675 typename... Coeff_Indices, typename... Knot_Indices_G, \
2676 typename... Coeff_Indices_G> \
2677 inline auto BOOST_PP_CAT(name, _all_)( \
2678 std::index_sequence<Is...>, const Geometry &G, \
2679 const std::tuple<Xi...> &xi, \
2680 const std::tuple<Knot_Indices...> &knot_indices, \
2681 const std::tuple<Coeff_Indices...> &coeff_indices, \
2682 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
2683 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
2684 if constexpr (comp == functionspace::interior) { \
2685 if constexpr (Geometry::nspaces() == 1) \
2686 return std::tuple( \
2687 std::get<Is>(spline_).template name<memory_optimized>( \
2688 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2689 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2690 std::get<Is>(coeff_indices_G))...); \
2692 return std::tuple( \
2693 std::get<Is>(spline_).template name<memory_optimized>( \
2694 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2695 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2696 std::get<Is>(coeff_indices_G))...); \
2697 } else if constexpr (comp == functionspace::boundary) { \
2698 if constexpr (Geometry::nspaces() == 1) \
2699 return std::tuple( \
2700 std::get<Is>(boundary_).template name<memory_optimized>( \
2701 static_cast<typename Geometry::boundary_type::boundary_type>( \
2702 G.boundary().coeffs()), \
2703 std::get<Is>(xi), std::get<Is>(knot_indices), \
2704 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2705 std::get<Is>(coeff_indices_G))...); \
2707 return std::tuple( \
2708 std::get<Is>(boundary_).template name<memory_optimized>( \
2709 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2710 std::get<Is>(knot_indices), std::get<Is>(coeff_indices), \
2711 std::get<Is>(knot_indices_G), \
2712 std::get<Is>(coeff_indices_G))...); \
2717 template <functionspace comp = functionspace::interior, \
2718 bool memory_optimized = false, typename... Args> \
2719 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2720 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2721 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2728#undef GENERATE_IEXPR_MACRO
2736template <
typename... Splines>
2747template <
typename Spline,
typename Boundary>
2772 template <std::
size_t index=0>
2774 static_assert(index <
nspaces());
2775 return spline_type::geoDim();
2781 template <std::
size_t index=0>
2783 static_assert(index <
nspaces());
2784 return spline_type::parDim();
2791 template <std::
size_t index=0>
2792 inline static constexpr const auto&
degrees() noexcept {
2793 static_assert(index <
nspaces());
2794 return spline_type::degrees();
2802 template <std::
size_t index=0>
2804 static_assert(index <
nspaces());
2805 return spline_type::degree(i);
2831 const std::array<int64_t, Spline::parDim()> &ncoeffs,
2844 std::array<std::vector<value_type>, Spline::parDim()> kv,
2848 static_assert(Spline::is_nonuniform(),
2849 "Constructor is only available for non-uniform splines");
2872 inline static constexpr std::size_t
nspaces() noexcept {
return 1; }
2876 inline static constexpr std::size_t
nboundaries() noexcept {
return 1; }
2897 template <std::
size_t index = 0>
2899 static_assert(index <
nspaces());
2906 template <std::
size_t index = 0>
2908 static_assert(index <
nspaces());
2915 template <std::
size_t index = 0>
2925 template <std::
size_t index = 0>
2940 template <std::size_t... index>
inline constexpr auto clone() const noexcept {
2942 static_assert(((index <
nspaces()) && ... &&
true));
2944 if constexpr (
sizeof...(index) == 1)
2948 std::tuple<std::tuple_element_t<index, std::tuple<spline_type>>...>,
2950 std::tuple_element_t<index, std::tuple<boundary_type>>...>>(
2951 std::get<index>(std::make_tuple(
spline_))...,
2952 std::get<index>(std::make_tuple(
boundary_))...);
2981 return spline_.as_tensor_size();
3043 const std::string &label =
"")
const {
3044 pugi::xml_document doc;
3045 pugi::xml_node root = doc.append_child(
"xml");
3056 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
3057 const std::string &label =
"")
const {
3058 return spline_.to_xml(root,
id, label);
3067 const std::string &label =
"") {
3068 return from_xml(doc.child(
"xml"),
id, label);
3077 const std::string &label =
"") {
3085 auto json = nlohmann::json::array();
3096 template <
typename SplinesOther,
typename BoundariesOther>
3101 if (!std::is_same_v<
spline_type,
typename std::remove_cvref_t<
3103 !std::is_same_v<
boundary_type,
typename std::remove_cvref_t<
3117 const std::function<std::array<
typename Spline::value_type,
3119 const std::array<
typename Spline::value_type, Spline::parDim()> &)>
3130 std::size_t... Is,
typename... Xi>
3131 inline auto eval_(std::index_sequence<Is...>,
3132 const std::tuple<Xi...> &xi)
const {
3135 spline_.template eval<deriv, memory_optimized>(std::get<Is>(xi))...);
3137 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
3138 std::get<Is>(xi))...);
3143 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
3144 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
3145 const std::tuple<Knot_Indices...> &knot_indices)
const {
3147 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
3148 std::get<Is>(xi), std::get<Is>(knot_indices))...);
3150 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
3151 std::get<Is>(xi), std::get<Is>(knot_indices))...);
3156 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
3157 typename... Coeff_Indices>
3158 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
3159 const std::tuple<Knot_Indices...> &knot_indices,
3160 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
3162 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
3163 std::get<Is>(xi), std::get<Is>(knot_indices),
3164 std::get<Is>(coeff_indices))...);
3166 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
3167 std::get<Is>(xi), std::get<Is>(knot_indices),
3168 std::get<Is>(coeff_indices))...);
3179 typename Arg,
typename... Args>
3180 inline auto eval(
const Arg &arg,
const Args &...args)
const {
3182 if constexpr (utils::is_tuple_v<Arg>)
3183 return eval_<comp, deriv, memory_optimized>(
3184 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
3186 return spline_.template eval<deriv, memory_optimized>(arg, args...);
3188 if constexpr (utils::is_tuple_of_tuples_v<Arg>)
3189 return eval_<comp, deriv, memory_optimized>(
3190 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
3192 return boundary_.template eval<deriv, memory_optimized>(arg, args...);
3205 return spline_.eval_from_precomputed(args...);
3215 const Xi &xi)
const {
3217 return std::tuple(
spline_.find_knot_indices(std::get<Is>(xi))...);
3228 template <functionspace comp = functionspace::
interior,
typename Xi>
3231 if constexpr (utils::is_tuple_v<Xi>)
3232 return find_knot_indices_<comp>(
3233 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
3235 return spline_.find_knot_indices(xi);
3237 if constexpr (utils::is_tuple_of_tuples_v<Xi>)
3238 return find_knot_indices_<comp>(
3239 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
3254 return spline_.template eval_basfunc<deriv, memory_optimized>(args...);
3256 return boundary_.template eval_basfunc<deriv, memory_optimized>(args...);
3263 bool memory_optimized =
false, std::size_t... Is,
3264 typename Knot_Indices>
3266 const Knot_Indices &knot_indices)
const {
3268 return std::tuple(
spline_.template find_coeff_indices<memory_optimized>(
3269 std::get<Is>(knot_indices))...);
3271 return std::tuple(
boundary_.template find_coeff_indices<memory_optimized>(
3272 std::get<Is>(knot_indices))...);
3281 bool memory_optimized =
false,
typename Knot_Indices>
3284 if constexpr (utils::is_tuple_v<Knot_Indices>)
3285 return find_coeff_indices_<comp, memory_optimized>(
3286 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
3289 return spline_.template find_coeff_indices<memory_optimized>(
3292 if constexpr (utils::is_tuple_of_tuples_v<Knot_Indices>)
3293 return find_coeff_indices_<comp, memory_optimized>(
3294 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
3297 return boundary_.template find_coeff_indices<memory_optimized>(
3308 spline_.uniform_refine(numRefine, dimRefine);
3320 typename spline_type::template real_derived_self_type<real_t>,
3321 typename boundary_type::template real_derived_self_type<real_t>>(
3329 inline auto to(torch::Device device)
const {
3336 template <
typename real_t>
inline auto to()
const {
3338 typename spline_type::template real_derived_self_type<real_t>,
3339 typename boundary_type::template real_derived_self_type<real_t>>(
3357 template <std::
size_t N>
inline auto scale(std::array<value_type, N> v) {
3367 template <std::
size_t N>
inline auto translate(std::array<value_type, N> v) {
3385 inline auto rotate(std::array<value_type, 3> angle) {
3396 inline torch::serialize::OutputArchive &
3397 write(torch::serialize::OutputArchive &archive,
3398 const std::string &key =
"functionspace")
const {
3409 inline torch::serialize::InputArchive &
3410 read(torch::serialize::InputArchive &archive,
3411 const std::string &key =
"functionspace") {
3420 os <<
name() <<
"(\nspline = ";
3422 os <<
"\nboundary = ";
3427#define GENERATE_EXPR_MACRO(r, data, name) \
3429 template <functionspace comp = functionspace::interior, \
3430 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
3431 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
3432 const std::tuple<Xi...> &xi) const { \
3433 if constexpr (comp == functionspace::interior) \
3434 return std::tuple( \
3435 spline_.template name<memory_optimized>(std::get<Is>(xi))...); \
3436 else if constexpr (comp == functionspace::boundary) \
3437 return std::tuple( \
3438 boundary_.template name<memory_optimized>(std::get<Is>(xi))...); \
3441 template <functionspace comp = functionspace::interior, \
3442 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
3443 typename... Knot_Indices> \
3444 inline auto BOOST_PP_CAT(name, _all_)( \
3445 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
3446 const std::tuple<Knot_Indices...> &knot_indices) const { \
3447 if constexpr (comp == functionspace::interior) \
3448 return std::tuple(spline_.template name<memory_optimized>( \
3449 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
3450 else if constexpr (comp == functionspace::boundary) \
3451 return std::tuple(boundary_.template name<memory_optimized>( \
3452 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
3455 template <functionspace comp = functionspace::interior, \
3456 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
3457 typename... Knot_Indices, typename... Coeff_Indices> \
3458 inline auto BOOST_PP_CAT(name, _all_)( \
3459 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
3460 const std::tuple<Knot_Indices...> &knot_indices, \
3461 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
3462 if constexpr (comp == functionspace::interior) \
3463 return std::tuple(spline_.template name<memory_optimized>( \
3464 std::get<Is>(xi), std::get<Is>(knot_indices), \
3465 std::get<Is>(coeff_indices))...); \
3466 else if constexpr (comp == functionspace::boundary) \
3467 return std::tuple(boundary_.template name<memory_optimized>( \
3468 std::get<Is>(xi), std::get<Is>(knot_indices), \
3469 std::get<Is>(coeff_indices))...); \
3473 template <functionspace comp = functionspace::interior, \
3474 bool memory_optimized = false, typename Arg, typename... Args> \
3475 inline auto name(const Arg &arg, const Args &...args) const { \
3476 if constexpr (comp == functionspace::interior) \
3477 if constexpr (utils::is_tuple_v<Arg>) \
3478 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3479 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
3481 return spline_.template name<memory_optimized>(arg, args...); \
3482 else if constexpr (comp == functionspace::boundary) { \
3483 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
3484 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3485 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
3487 return boundary_.template name<memory_optimized>(arg, args...); \
3495#undef GENERATE_EXPR_MACRO
3497#define GENERATE_IEXPR_MACRO(r, data, name) \
3499 template <functionspace comp = functionspace::interior, \
3500 bool memory_optimized = false, std::size_t... Is, \
3501 typename Geometry, typename... Xi> \
3502 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
3503 const Geometry &G, \
3504 const std::tuple<Xi...> &xi) const { \
3505 if constexpr (comp == functionspace::interior) \
3506 return std::tuple(spline_.template name<memory_optimized>( \
3507 G.space(), std::get<Is>(xi))...); \
3508 else if constexpr (comp == functionspace::boundary) \
3509 return std::tuple(boundary_.template name<memory_optimized>( \
3510 static_cast<typename Geometry::boundary_type::boundary_type>( \
3511 G.boundary().coeffs()), \
3512 std::get<Is>(xi))...); \
3515 template <functionspace comp = functionspace::interior, \
3516 bool memory_optimized = false, std::size_t... Is, \
3517 typename Geometry, typename... Xi, typename... Knot_Indices, \
3518 typename... Knot_Indices_G> \
3519 inline auto BOOST_PP_CAT(name, _all_)( \
3520 std::index_sequence<Is...>, const Geometry &G, \
3521 const std::tuple<Xi...> &xi, \
3522 const std::tuple<Knot_Indices...> &knot_indices, \
3523 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
3524 if constexpr (comp == functionspace::interior) \
3525 return std::tuple(spline_.template name<memory_optimized>( \
3526 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
3527 std::get<Is>(knot_indices_G))...); \
3528 else if constexpr (comp == functionspace::boundary) \
3529 return std::tuple(boundary_.template name<memory_optimized>( \
3530 static_cast<typename Geometry::boundary_type::boundary_type>( \
3531 G.boundary().coeffs()), \
3532 std::get<Is>(xi), std::get<Is>(knot_indices), \
3533 std::get<Is>(knot_indices_G))...); \
3536 template <functionspace comp = functionspace::interior, \
3537 bool memory_optimized = false, std::size_t... Is, \
3538 typename Geometry, typename... Xi, typename... Knot_Indices, \
3539 typename... Coeff_Indices, typename... Knot_Indices_G, \
3540 typename... Coeff_Indices_G> \
3541 inline auto BOOST_PP_CAT(name, _all_)( \
3542 std::index_sequence<Is...>, const Geometry &G, \
3543 const std::tuple<Xi...> &xi, \
3544 const std::tuple<Knot_Indices...> &knot_indices, \
3545 const std::tuple<Coeff_Indices...> &coeff_indices, \
3546 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
3547 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
3548 if constexpr (comp == functionspace::interior) \
3549 return std::tuple(spline_.template name<memory_optimized>( \
3550 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
3551 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3552 std::get<Is>(coeff_indices_G))...); \
3553 else if constexpr (comp == functionspace::boundary) \
3554 return std::tuple(boundary_.template name<memory_optimized>( \
3555 static_cast<typename Geometry::boundary_type::boundary_type>( \
3556 G.boundary().coeffs()), \
3557 std::get<Is>(xi), std::get<Is>(knot_indices), \
3558 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3559 std::get<Is>(coeff_indices_G))...); \
3563 template <functionspace comp = functionspace::interior, \
3564 bool memory_optimized = false, typename Geometry, typename Arg, \
3566 inline auto name(const Geometry &G, const Arg &arg, const Args &...args) \
3568 if constexpr (comp == functionspace::interior) { \
3569 if constexpr (utils::is_tuple_v<Arg>) \
3570 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3571 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3574 return spline_.template name<memory_optimized>(G.space(), arg, \
3576 } else if constexpr (comp == functionspace::boundary) { \
3577 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
3578 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3579 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3582 return boundary_.template name<memory_optimized>( \
3583 static_cast<typename Geometry::boundary_type::boundary_type>( \
3584 G.boundary().coeffs()), \
3593#undef GENERATE_IEXPR_MACRO
3605template <
typename Spline,
typename Boundary>
3611template <
typename... Splines>
3618template <
typename... Splines,
typename... Boundaries>
3627template <
typename Spline,
typename Boundary>
3635template <
typename... Splines,
typename... Boundaries>
3645template <
typename T>
3649template <
typename... Args>
3659template <
typename Splines,
typename Boundaries>
3662 obj.pretty_print(os);
3686template <
typename Spline,
short_t = Spline::parDim()>
class TH;
3697template <
typename Spline>
3700 std::tuple<typename Spline::template derived_self_type<
3701 typename Spline::value_type, Spline::geoDim(),
3702 Spline::degree(0) + 1>,
3703 typename Spline::template derived_self_type<
3704 typename Spline::value_type, Spline::geoDim(),
3705 Spline::degree(0)>>> {
3709 typename Spline::template derived_self_type<
3710 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3711 typename Spline::template derived_self_type<
3712 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3719 explicit TH(
const std::array<int64_t, 1> &ncoeffs,
3723 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {
3724 static_assert(Spline::is_nonuniform(),
3725 "TH function space requires non-uniform splines");
3726 Base::template space<0>().reduce_continuity();
3733 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3737 : Base({{kv[0].front + kv[0] + kv[0].back(), kv[1]}}, kv,
init, options) {
3738 static_assert(Spline::is_nonuniform(),
3739 "TH function space requires non-uniform splines");
3740 Base::template space<0>().reduce_continuity();
3759template <
typename Spline>
3762 std::tuple<typename Spline::template derived_self_type<
3763 typename Spline::value_type, Spline::geoDim(),
3764 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3765 typename Spline::template derived_self_type<
3766 typename Spline::value_type, Spline::geoDim(),
3767 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3768 typename Spline::template derived_self_type<
3769 typename Spline::value_type, Spline::geoDim(),
3770 Spline::degree(0), Spline::degree(1)>>> {
3774 std::tuple<
typename Spline::template derived_self_type<
3775 typename Spline::value_type, Spline::geoDim(),
3776 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3777 typename Spline::template derived_self_type<
3778 typename Spline::value_type, Spline::geoDim(),
3779 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3780 typename Spline::template derived_self_type<
3781 typename Spline::value_type, Spline::geoDim(),
3782 Spline::degree(0), Spline::degree(1)>>>;
3789 explicit TH(
const std::array<int64_t, 2> &ncoeffs,
3793 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
3794 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
3795 static_assert(Spline::is_nonuniform(),
3796 "TH function space requires non-uniform splines");
3797 Base::template space<0>().reduce_continuity();
3798 Base::template space<1>().reduce_continuity();
3805 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3809 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3810 kv[1].front() + kv[1] + kv[1].back()}},
3811 {{kv[0].front() + kv[0] + kv[0].back(),
3812 kv[1].front() + kv[1] + kv[1].back()}},
3813 kv,
init, options) {
3814 static_assert(Spline::is_nonuniform(),
3815 "TH function space requires non-uniform splines");
3816 Base::template space<0>().reduce_continuity();
3817 Base::template space<1>().reduce_continuity();
3837template <
typename Spline>
3840 typename Spline::template derived_self_type<
3841 typename Spline::value_type, Spline::geoDim(),
3842 Spline::degree(0) + 1, Spline::degree(1) + 1,
3843 Spline::degree(2) + 1>,
3844 typename Spline::template derived_self_type<
3845 typename Spline::value_type, Spline::geoDim(),
3846 Spline::degree(0) + 1, Spline::degree(1) + 1,
3847 Spline::degree(2) + 1>,
3848 typename Spline::template derived_self_type<
3849 typename Spline::value_type, Spline::geoDim(),
3850 Spline::degree(0) + 1, Spline::degree(1) + 1,
3851 Spline::degree(2) + 1>,
3852 typename Spline::template derived_self_type<
3853 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3854 Spline::degree(1), Spline::degree(2)>>> {
3858 typename Spline::template derived_self_type<
3859 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3860 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3861 typename Spline::template derived_self_type<
3862 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3863 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3864 typename Spline::template derived_self_type<
3865 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3866 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3867 typename Spline::template derived_self_type<
3868 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3869 Spline::degree(1), Spline::degree(2)>>>;
3876 explicit TH(
const std::array<int64_t, 3> &ncoeffs,
3880 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3881 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3882 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
3884 static_assert(Spline::is_nonuniform(),
3885 "TH function space requires non-uniform splines");
3886 Base::template space<0>().reduce_continuity();
3887 Base::template space<1>().reduce_continuity();
3888 Base::template space<2>().reduce_continuity();
3895 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3899 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3900 kv[1].front() + kv[1] + kv[1].back(),
3901 kv[2].front() + kv[2] + kv[2].back()}},
3902 {{kv[0].front() + kv[0] + kv[0].back(),
3903 kv[1].front() + kv[1] + kv[1].back(),
3904 kv[2].front() + kv[2] + kv[2].back()}},
3905 {{kv[0].front() + kv[0] + kv[0].back(),
3906 kv[1].front() + kv[1] + kv[1].back(),
3907 kv[2].front() + kv[2] + kv[2].back()}},
3908 kv,
init, options) {
3909 static_assert(Spline::is_nonuniform(),
3910 "TH function space requires non-uniform splines");
3911 Base::template space<0>().reduce_continuity();
3912 Base::template space<1>().reduce_continuity();
3913 Base::template space<2>().reduce_continuity();
3934template <
typename Spline>
3937 typename Spline::template derived_self_type<
3938 typename Spline::value_type, Spline::geoDim(),
3939 Spline::degree(0) + 1, Spline::degree(1) + 1,
3940 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3941 typename Spline::template derived_self_type<
3942 typename Spline::value_type, Spline::geoDim(),
3943 Spline::degree(0) + 1, Spline::degree(1) + 1,
3944 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3945 typename Spline::template derived_self_type<
3946 typename Spline::value_type, Spline::geoDim(),
3947 Spline::degree(0) + 1, Spline::degree(1) + 1,
3948 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3949 typename Spline::template derived_self_type<
3950 typename Spline::value_type, Spline::geoDim(),
3951 Spline::degree(0) + 1, Spline::degree(1) + 1,
3952 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3953 typename Spline::template derived_self_type<
3954 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3955 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3959 typename Spline::template derived_self_type<
3960 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3961 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3962 typename Spline::template derived_self_type<
3963 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3964 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3965 typename Spline::template derived_self_type<
3966 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3967 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3968 typename Spline::template derived_self_type<
3969 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3970 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3971 typename Spline::template derived_self_type<
3972 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3973 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
3980 explicit TH(
const std::array<int64_t, 4> &ncoeffs,
3984 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3985 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3986 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3987 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64), ncoeffs,
3989 static_assert(Spline::is_nonuniform(),
3990 "TH function space requires non-uniform splines");
3991 Base::template space<0>().reduce_continuity();
3992 Base::template space<1>().reduce_continuity();
3993 Base::template space<2>().reduce_continuity();
3994 Base::template space<3>().reduce_continuity();
4001 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
4005 : Base({{kv[0].front() + kv[0] + kv[0].back(),
4006 kv[1].front() + kv[1] + kv[1].back(),
4007 kv[2].front() + kv[2] + kv[2].back(),
4008 kv[3].front() + kv[3] + kv[3].back()}},
4009 {{kv[0].front() + kv[0] + kv[0].back(),
4010 kv[1].front() + kv[1] + kv[1].back(),
4011 kv[2].front() + kv[2] + kv[2].back(),
4012 kv[3].front() + kv[3] + kv[3].back()}},
4013 {{kv[0].front() + kv[0] + kv[0].back(),
4014 kv[1].front() + kv[1] + kv[1].back(),
4015 kv[2].front() + kv[2] + kv[2].back(),
4016 kv[3].front() + kv[3] + kv[3].back()}},
4017 {{kv[0].front() + kv[0] + kv[0].back(),
4018 kv[1].front() + kv[1] + kv[1].back(),
4019 kv[2].front() + kv[2] + kv[2].back(),
4020 kv[3].front() + kv[3] + kv[3].back()}},
4021 kv,
init, options) {
4022 static_assert(Spline::is_nonuniform(),
4023 "TH function space requires non-uniform splines");
4024 Base::template space<0>().reduce_continuity();
4025 Base::template space<1>().reduce_continuity();
4026 Base::template space<2>().reduce_continuity();
4027 Base::template space<3>().reduce_continuity();
4036template <
typename Spline,
short_t = Spline::parDim()>
class NE;
4047template <
typename Spline>
4050 std::tuple<typename Spline::template derived_self_type<
4051 typename Spline::value_type, Spline::geoDim(),
4052 Spline::degree(0) + 1>,
4053 typename Spline::template derived_self_type<
4054 typename Spline::value_type, Spline::geoDim(),
4055 Spline::degree(0)>>> {
4059 typename Spline::template derived_self_type<
4060 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
4061 typename Spline::template derived_self_type<
4062 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
4069 explicit NE(
const std::array<int64_t, 1> &ncoeffs,
4073 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
4079 explicit NE(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
4083 : Base(kv, kv,
init, options) {
4084 static_assert(Spline::is_nonuniform(),
4085 "Constructor only available for non-uniform splines");
4103template <
typename Spline>
4106 std::tuple<typename Spline::template derived_self_type<
4107 typename Spline::value_type, Spline::geoDim(),
4108 Spline::degree(0) + 1, Spline::degree(1) + 1>,
4109 typename Spline::template derived_self_type<
4110 typename Spline::value_type, Spline::geoDim(),
4111 Spline::degree(0) + 1, Spline::degree(1) + 1>,
4112 typename Spline::template derived_self_type<
4113 typename Spline::value_type, Spline::geoDim(),
4114 Spline::degree(0), Spline::degree(1)>>> {
4118 std::tuple<
typename Spline::template derived_self_type<
4119 typename Spline::value_type, Spline::geoDim(),
4120 Spline::degree(0) + 1, Spline::degree(1) + 1>,
4121 typename Spline::template derived_self_type<
4122 typename Spline::value_type, Spline::geoDim(),
4123 Spline::degree(0) + 1, Spline::degree(1) + 1>,
4124 typename Spline::template derived_self_type<
4125 typename Spline::value_type, Spline::geoDim(),
4126 Spline::degree(0), Spline::degree(1)>>>;
4133 explicit NE(
const std::array<int64_t, 2> &ncoeffs,
4137 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
4138 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
4139 static_assert(Spline::is_nonuniform(),
4140 "NE function space requires non-uniform splines");
4141 Base::template space<0>().reduce_continuity(1, 1);
4142 Base::template space<1>().reduce_continuity(1, 0);
4149 explicit NE(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
4153 : Base(kv, kv, kv,
init, options) {
4154 static_assert(Spline::is_nonuniform(),
4155 "NE function space requires non-uniform splines");
4156 Base::template space<0>().reduce_continuity(1, 1);
4157 Base::template space<1>().reduce_continuity(1, 0);
4177template <
typename Spline>
4180 typename Spline::template derived_self_type<
4181 typename Spline::value_type, Spline::geoDim(),
4182 Spline::degree(0) + 1, Spline::degree(1) + 1,
4183 Spline::degree(2) + 1>,
4184 typename Spline::template derived_self_type<
4185 typename Spline::value_type, Spline::geoDim(),
4186 Spline::degree(0) + 1, Spline::degree(1) + 1,
4187 Spline::degree(2) + 1>,
4188 typename Spline::template derived_self_type<
4189 typename Spline::value_type, Spline::geoDim(),
4190 Spline::degree(0) + 1, Spline::degree(1) + 1,
4191 Spline::degree(2) + 1>,
4192 typename Spline::template derived_self_type<
4193 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4194 Spline::degree(1), Spline::degree(2)>>> {
4198 typename Spline::template derived_self_type<
4199 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4200 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4201 typename Spline::template derived_self_type<
4202 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4203 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4204 typename Spline::template derived_self_type<
4205 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4206 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4207 typename Spline::template derived_self_type<
4208 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4209 Spline::degree(1), Spline::degree(2)>>>;
4216 explicit NE(
const std::array<int64_t, 3> &ncoeffs,
4220 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
4221 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
4222 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
4224 static_assert(Spline::is_nonuniform(),
4225 "NE function space requires non-uniform splines");
4226 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
4227 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
4228 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
4235 explicit NE(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4239 : Base(kv, kv, kv, kv,
init, options) {
4240 static_assert(Spline::is_nonuniform(),
4241 "NE function space requires non-uniform splines");
4242 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
4243 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
4244 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
4265template <
typename Spline>
4268 typename Spline::template derived_self_type<
4269 typename Spline::value_type, Spline::geoDim(),
4270 Spline::degree(0) + 1, Spline::degree(1) + 1,
4271 Spline::degree(2) + 1, Spline::degree(3) + 1>,
4272 typename Spline::template derived_self_type<
4273 typename Spline::value_type, Spline::geoDim(),
4274 Spline::degree(0) + 1, Spline::degree(1) + 1,
4275 Spline::degree(2) + 1, Spline::degree(3) + 1>,
4276 typename Spline::template derived_self_type<
4277 typename Spline::value_type, Spline::geoDim(),
4278 Spline::degree(0) + 1, Spline::degree(1) + 1,
4279 Spline::degree(2) + 1, Spline::degree(3) + 1>,
4280 typename Spline::template derived_self_type<
4281 typename Spline::value_type, Spline::geoDim(),
4282 Spline::degree(0) + 1, Spline::degree(1) + 1,
4283 Spline::degree(2) + 1, Spline::degree(3) + 1>,
4284 typename Spline::template derived_self_type<
4285 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4286 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
4290 typename Spline::template derived_self_type<
4291 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4292 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
4293 typename Spline::template derived_self_type<
4294 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4295 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
4296 typename Spline::template derived_self_type<
4297 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4298 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
4299 typename Spline::template derived_self_type<
4300 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4301 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
4302 typename Spline::template derived_self_type<
4303 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4304 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
4311 explicit NE(
const std::array<int64_t, 4> &ncoeffs,
4315 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
4316 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
4317 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
4318 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64), ncoeffs,
4320 static_assert(Spline::is_nonuniform(),
4321 "NE function space requires non-uniform splines");
4322 Base::template space<0>()
4323 .reduce_continuity(1, 1)
4324 .reduce_continuity(1, 2)
4325 .reduce_continuity(1, 3);
4326 Base::template space<1>()
4327 .reduce_continuity(1, 0)
4328 .reduce_continuity(1, 2)
4329 .reduce_continuity(1, 3);
4330 Base::template space<2>()
4331 .reduce_continuity(1, 0)
4332 .reduce_continuity(1, 1)
4333 .reduce_continuity(1, 3);
4334 Base::template space<3>()
4335 .reduce_continuity(1, 0)
4336 .reduce_continuity(1, 1)
4337 .reduce_continuity(1, 2);
4344 explicit NE(
const std::array<std::vector<typename Spline::value_type>,
4345 Spline::parDim()> &kv,
4349 : Base(kv, kv, kv, kv, kv,
init, options) {
4350 static_assert(Spline::is_nonuniform(),
4351 "NE function space requires non-uniform splines");
4352 Base::template space<0>()
4353 .reduce_continuity(1, 1)
4354 .reduce_continuity(1, 2)
4355 .reduce_continuity(1, 3);
4356 Base::template space<1>()
4357 .reduce_continuity(1, 0)
4358 .reduce_continuity(1, 2)
4359 .reduce_continuity(1, 3);
4360 Base::template space<2>()
4361 .reduce_continuity(1, 0)
4362 .reduce_continuity(1, 1)
4363 .reduce_continuity(1, 3);
4364 Base::template space<3>()
4365 .reduce_continuity(1, 0)
4366 .reduce_continuity(1, 1)
4367 .reduce_continuity(1, 2);
4376template <
typename Spline,
short_t = Spline::parDim()>
class RT;
4387template <
typename Spline>
4390 std::tuple<typename Spline::template derived_self_type<
4391 typename Spline::value_type, Spline::geoDim(),
4392 Spline::degree(0) + 1>,
4393 typename Spline::template derived_self_type<
4394 typename Spline::value_type, Spline::geoDim(),
4395 Spline::degree(0)>>> {
4399 typename Spline::template derived_self_type<
4400 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
4401 typename Spline::template derived_self_type<
4402 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
4409 explicit RT(
const std::array<int64_t, 1> &ncoeffs,
4413 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
4419 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
4423 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}}, kv,
init,
4425 static_assert(Spline::is_nonuniform(),
4426 "Constructor only available for non-uniform splines");
4445template <
typename Spline>
4448 std::tuple<typename Spline::template derived_self_type<
4449 typename Spline::value_type, Spline::geoDim(),
4450 Spline::degree(0) + 1, Spline::degree(1)>,
4451 typename Spline::template derived_self_type<
4452 typename Spline::value_type, Spline::geoDim(),
4453 Spline::degree(0), Spline::degree(1) + 1>,
4454 typename Spline::template derived_self_type<
4455 typename Spline::value_type, Spline::geoDim(),
4456 Spline::degree(0), Spline::degree(1)>>> {
4459 std::tuple<
typename Spline::template derived_self_type<
4460 typename Spline::value_type, Spline::geoDim(),
4461 Spline::degree(0) + 1, Spline::degree(1)>,
4462 typename Spline::template derived_self_type<
4463 typename Spline::value_type, Spline::geoDim(),
4464 Spline::degree(0), Spline::degree(1) + 1>,
4465 typename Spline::template derived_self_type<
4466 typename Spline::value_type, Spline::geoDim(),
4467 Spline::degree(0), Spline::degree(1)>>>;
4474 explicit RT(
const std::array<int64_t, 2> &ncoeffs,
4478 : Base(ncoeffs + utils::to_array(1_i64, 0_i64),
4479 ncoeffs + utils::to_array(0_i64, 1_i64), ncoeffs,
init, options) {}
4485 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
4489 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}},
4490 {{kv[0], kv[1].front() + kv[1] + kv[1].back()}}, kv,
init,
4492 static_assert(Spline::is_nonuniform(),
4493 "Constructor only available for non-uniform splines");
4512template <
typename Spline>
4515 typename Spline::template derived_self_type<
4516 typename Spline::value_type, Spline::geoDim(),
4517 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2)>,
4518 typename Spline::template derived_self_type<
4519 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4520 Spline::degree(1) + 1, Spline::degree(2)>,
4521 typename Spline::template derived_self_type<
4522 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4523 Spline::degree(1), Spline::degree(2) + 1>,
4524 typename Spline::template derived_self_type<
4525 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4526 Spline::degree(1), Spline::degree(2)>>> {
4530 typename Spline::template derived_self_type<
4531 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4532 Spline::degree(1), Spline::degree(2)>,
4533 typename Spline::template derived_self_type<
4534 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4535 Spline::degree(1) + 1, Spline::degree(2)>,
4536 typename Spline::template derived_self_type<
4537 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4538 Spline::degree(1), Spline::degree(2) + 1>,
4539 typename Spline::template derived_self_type<
4540 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4541 Spline::degree(1), Spline::degree(2)>>>;
4548 explicit RT(
const std::array<int64_t, 3> &ncoeffs,
4552 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4553 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4554 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64), ncoeffs,
init,
4561 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4565 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4566 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4567 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}}, kv,
init,
4569 static_assert(Spline::is_nonuniform(),
4570 "Constructor only available for non-uniform splines");
4591template <
typename Spline>
4594 typename Spline::template derived_self_type<
4595 typename Spline::value_type, Spline::geoDim(),
4596 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2),
4598 typename Spline::template derived_self_type<
4599 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4600 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
4601 typename Spline::template derived_self_type<
4602 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4603 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
4604 typename Spline::template derived_self_type<
4605 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4606 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
4607 typename Spline::template derived_self_type<
4608 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4609 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
4613 typename Spline::template derived_self_type<
4614 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4615 Spline::degree(1), Spline::degree(2), Spline::degree(3)>,
4616 typename Spline::template derived_self_type<
4617 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4618 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
4619 typename Spline::template derived_self_type<
4620 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4621 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
4622 typename Spline::template derived_self_type<
4623 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4624 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
4625 typename Spline::template derived_self_type<
4626 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4627 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
4634 explicit RT(
const std::array<int64_t, 4> &ncoeffs,
4638 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64, 0_i64),
4639 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64, 0_i64),
4640 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64, 0_i64),
4641 ncoeffs + utils::to_array(0_i64, 0_i64, 0_i64, 1_i64), ncoeffs,
4648 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
4652 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2], kv[3]}},
4653 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2], kv[3]}},
4654 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back(), kv[3]}},
4655 {{kv[0], kv[1], kv[2], kv[3].front() + kv[3] + kv[3].back()}}, kv,
4657 static_assert(Spline::is_nonuniform(),
4658 "Constructor only available for non-uniform splines");
4667template <
typename Spline,
short_t = Spline::parDim()>
class Hcurl;
4680template <
typename Spline>
4683 typename Spline::template derived_self_type<
4684 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4685 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4686 typename Spline::template derived_self_type<
4687 typename Spline::value_type, Spline::geoDim(),
4688 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2) + 1>,
4689 typename Spline::template derived_self_type<
4690 typename Spline::value_type, Spline::geoDim(),
4691 Spline::degree(0) + 1, Spline::degree(1) + 1,
4692 Spline::degree(2)>>> {
4697 typename Spline::template derived_self_type<
4698 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4699 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4700 typename Spline::template derived_self_type<
4701 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4702 Spline::degree(1), Spline::degree(2) + 1>,
4703 typename Spline::template derived_self_type<
4704 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4705 Spline::degree(1) + 1, Spline::degree(2)>>>;
4712 explicit Hcurl(
const std::array<int64_t, 3> &ncoeffs,
4716 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4717 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4718 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64),
init, options) {}
4725 const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4729 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4730 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4731 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}},
init,
4733 static_assert(Spline::is_nonuniform(),
4734 "Constructor only available for non-uniform splines");
4741template <
typename Spline,
short_t = Spline::parDim()>
class NE_RT_DG;
4758template <
typename Spline>
4762 typename Spline::template derived_self_type<
4763 typename Spline::value_type, Spline::geoDim(),
4764 Spline::degree(0) + 1, Spline::degree(1) + 1>,
4766 typename Spline::template derived_self_type<
4767 typename Spline::value_type, Spline::geoDim(),
4768 Spline::degree(0) + 1, Spline::degree(1)>,
4769 typename Spline::template derived_self_type<
4770 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4771 Spline::degree(1) + 1>,
4773 typename Spline::template derived_self_type<
4774 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4775 Spline::degree(1)>>> {
4781 typename Spline::template derived_self_type<
4782 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4783 Spline::degree(1) + 1>,
4785 typename Spline::template derived_self_type<
4786 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4788 typename Spline::template derived_self_type<
4789 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4790 Spline::degree(1) + 1>,
4792 typename Spline::template derived_self_type<
4793 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4794 Spline::degree(1)>>>;
4801 explicit NE_RT_DG(
const std::array<int64_t, 2> &ncoeffs,
4805 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
4806 ncoeffs + utils::to_array(1_i64, 0_i64),
4807 ncoeffs + utils::to_array(0_i64, 1_i64), ncoeffs,
init, options) {}
4814 const std::array<std::vector<typename Spline::value_type>, 2> &kv,
4818 : Base({{kv[0].front() + kv[0] + kv[0].back(),
4819 kv[1].front() + kv[1] + kv[1].back()}},
4820 {{kv[0].front() + kv[0] + kv[0].back(), kv[1]}},
4821 {{kv[0], kv[1].front() + kv[1] + kv[1].back()}}, {{kv[0], kv[1]}},
4823 static_assert(Spline::is_nonuniform(),
4824 "Constructor only available for non-uniform splines");
4846template <
typename Spline>
4850 typename Spline::template derived_self_type<
4851 typename Spline::value_type, Spline::geoDim(),
4852 Spline::degree(0) + 1, Spline::degree(1) + 1,
4853 Spline::degree(2) + 1>,
4855 typename Spline::template derived_self_type<
4856 typename Spline::value_type, Spline::geoDim(),
4857 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2)>,
4858 typename Spline::template derived_self_type<
4859 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4860 Spline::degree(1) + 1, Spline::degree(2)>,
4861 typename Spline::template derived_self_type<
4862 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4863 Spline::degree(1), Spline::degree(2) + 1>,
4865 typename Spline::template derived_self_type<
4866 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4867 Spline::degree(1), Spline::degree(2)>>> {
4873 typename Spline::template derived_self_type<
4874 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4875 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4877 typename Spline::template derived_self_type<
4878 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4879 Spline::degree(1), Spline::degree(2)>,
4880 typename Spline::template derived_self_type<
4881 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4882 Spline::degree(1) + 1, Spline::degree(2)>,
4883 typename Spline::template derived_self_type<
4884 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4885 Spline::degree(1), Spline::degree(2) + 1>,
4887 typename Spline::template derived_self_type<
4888 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4889 Spline::degree(1), Spline::degree(2)>>>;
4896 explicit NE_RT_DG(
const std::array<int64_t, 3> &ncoeffs,
4900 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
4901 ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4902 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4903 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64), ncoeffs,
init,
4911 const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4915 : Base({{kv[0].front() + kv[0] + kv[0].back(),
4916 kv[1].front() + kv[1] + kv[1].back(),
4917 kv[2].front() + kv[2] + kv[2].back()}},
4918 {{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4919 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4920 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}},
4921 {{kv[0], kv[1], kv[2]}},
init, options) {
4922 static_assert(Spline::is_nonuniform(),
4923 "Constructor only available for non-uniform splines");
4929#undef IGANET_FUNCTIONSPACE_DEFAULT_OPS
#define GENERATE_IEXPR_MACRO(r, data, name)
Auto-generated functions.
Definition boundary.hpp:1972
#define GENERATE_EXPR_MACRO(r, data, name)
Definition boundary.hpp:1926
#define GENERATE_EXPR_SEQ
Sequence of expression (parametric coordinates).
Definition bspline.hpp:43
#define GENERATE_IEXPR_SEQ
Sequence of expression (physical coordinates).
Definition bspline.hpp:49
Boundary (common high-level functionality).
Definition boundary.hpp:1237
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Returns the knot indices of knot spans containing xi.
Definition boundary.hpp:1491
auto eval_from_precomputed(const std::tuple< Basfunc... > &basfunc, const std::tuple< Coeff_Indices... > &coeff_indices, const std::tuple< Numeval... > &numeval, const std::tuple< Sizes... > &sizes) const
Returns the value of the spline objects from precomputed basis function.
Definition boundary.hpp:1442
torch::serialize::InputArchive & read(torch::serialize::InputArchive &archive, const std::string &key="boundary")
Loads the boundary spline object from a torch::serialize::InputArchive object.
Definition boundary.hpp:1765
auto to(Options< real_t > options) const
Returns a copy of the boundary object with settings from options.
Definition boundary.hpp:2129
auto & from_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor.
Definition boundary.hpp:1316
torch::Tensor as_tensor() const
Returns all coefficients of all spline objects as a single tensor.
Definition boundary.hpp:1261
auto & uniform_refine(int numRefine=1, int dim=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition boundary.hpp:1586
int64_t as_tensor_size() const
Returns the size of the single tensor representation of all spline objects.
Definition boundary.hpp:1282
torch::serialize::OutputArchive & write(torch::serialize::OutputArchive &archive, const std::string &key="boundary") const
Writes the boundary spline object into a torch::serialize::OutputArchive object.
Definition boundary.hpp:1729
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1), Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)> > > Base
Base type.
Definition functionspace.hpp:4705
Hcurl(const std::array< int64_t, 3 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4712
Hcurl(const std::array< std::vector< typename Spline::value_type >, 3 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the Hcurl operation.
Definition functionspace.hpp:4724
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)> > > Base
Base type.
Definition functionspace.hpp:4062
NE(const std::array< int64_t, 1 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4069
NE(const std::array< std::vector< typename Spline::value_type >, 1 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the NE operation.
Definition functionspace.hpp:4079
NE(const std::array< int64_t, 2 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4133
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)> > > Base
Base type.
Definition functionspace.hpp:4126
NE(const std::array< std::vector< typename Spline::value_type >, 2 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the NE operation.
Definition functionspace.hpp:4149
NE(const std::array< int64_t, 3 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4216
NE(const std::array< std::vector< typename Spline::value_type >, 3 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the NE operation.
Definition functionspace.hpp:4235
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)> > > Base
Base type.
Definition functionspace.hpp:4209
NE(const std::array< int64_t, 4 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4311
NE(const std::array< std::vector< typename Spline::value_type >, Spline::parDim()> &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the NE operation.
Definition functionspace.hpp:4344
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2), Spline::degree(3)> > > Base
Base type.
Definition functionspace.hpp:4304
NE_RT_DG(const std::array< int64_t, 2 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4801
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)> > > Base
Base type.
Definition functionspace.hpp:4794
NE_RT_DG(const std::array< std::vector< typename Spline::value_type >, 2 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the NE_RT_DG operation.
Definition functionspace.hpp:4813
NE_RT_DG(const std::array< std::vector< typename Spline::value_type >, 3 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the NE_RT_DG operation.
Definition functionspace.hpp:4910
NE_RT_DG(const std::array< int64_t, 3 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4896
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1), Spline::degree(2)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)+1, Spline::degree(2)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)> > > Base
Base type.
Definition functionspace.hpp:4889
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:47
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)> > > Base
Base type.
Definition functionspace.hpp:4402
RT(const std::array< int64_t, 1 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4409
RT(const std::array< std::vector< typename Spline::value_type >, 1 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the RT operation.
Definition functionspace.hpp:4419
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)> > > Base
Definition functionspace.hpp:4467
RT(const std::array< int64_t, 2 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4474
RT(const std::array< std::vector< typename Spline::value_type >, 2 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the RT operation.
Definition functionspace.hpp:4485
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1), Spline::degree(2)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)+1, Spline::degree(2)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)> > > Base
Base type.
Definition functionspace.hpp:4541
RT(const std::array< int64_t, 3 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4548
RT(const std::array< std::vector< typename Spline::value_type >, 3 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the RT operation.
Definition functionspace.hpp:4561
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1), Spline::degree(2), Spline::degree(3)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)+1, Spline::degree(2), Spline::degree(3)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)+1, Spline::degree(3)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2), Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2), Spline::degree(3)> > > Base
Base type.
Definition functionspace.hpp:4627
RT(const std::array< int64_t, 4 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:4634
RT(const std::array< std::vector< typename Spline::value_type >, 4 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the RT operation.
Definition functionspace.hpp:4648
TH(const std::array< int64_t, 1 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:3719
TH(const std::array< std::vector< typename Spline::value_type >, 1 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the TH operation.
Definition functionspace.hpp:3733
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)> > > Base
Base type.
Definition functionspace.hpp:3712
TH(const std::array< std::vector< typename Spline::value_type >, 2 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the TH operation.
Definition functionspace.hpp:3805
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)> > > Base
Base type.
Definition functionspace.hpp:3782
TH(const std::array< int64_t, 2 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:3789
TH(const std::array< int64_t, 3 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:3876
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)> > > Base
Base type.
Definition functionspace.hpp:3869
TH(const std::array< std::vector< typename Spline::value_type >, 3 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the TH operation.
Definition functionspace.hpp:3895
TH(const std::array< std::vector< typename Spline::value_type >, 4 > &kv, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Provides the TH operation.
Definition functionspace.hpp:4001
TH(const std::array< int64_t, 4 > &ncoeffs, enum init init=init::greville, Options< typename Spline::value_type > options=iganet::Options< typename Spline::value_type >{})
Constructor.
Definition functionspace.hpp:3980
FunctionSpace< std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)+1, Spline::degree(1)+1, Spline::degree(2)+1, Spline::degree(3)+1 >, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2), Spline::degree(3)> > > Base
Base type.
Definition functionspace.hpp:3973
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:1013
auto find_knot_indices(const utils::TensorArray< nspaces()> &xi) const
Returns the knot indices of knot spans containing xi
Definition functionspace.hpp:812
auto eval_basfunc_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the values of the spline objects' basis functions in the points xi
Definition functionspace.hpp:836
auto eval_from_precomputed(const std::tuple< Basfunc... > &basfunc, const std::tuple< Coeff_Indices... > &coeff_indices, const std::tuple< Numeval... > &numeval, const std::tuple< Sizes... > &sizes) const
Returns the value of the spline objects from precomputed basis function.
Definition functionspace.hpp:753
virtual int64_t boundary_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:366
auto hess(const utils::TensorArray< nspaces()> &xi) const
Returns a block-tensor with the Hessian of the function space object in the points xi with respect to...
Definition functionspace.hpp:1705
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:567
auto jac(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Provides the jac operation.
Definition functionspace.hpp:2160
static constexpr short_t geoDim() noexcept
Returns the geometric dimensions of the index-th space.
Definition functionspace.hpp:95
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:991
auto rotate_(std::index_sequence< Is... >, std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:1100
torch::serialize::InputArchive & read(torch::serialize::InputArchive &archive, const std::string &key="functionspace")
Loads the function space object from a torch::serialize::InputArchive object.
Definition functionspace.hpp:1183
int64_t boundary_as_tensor_size_(std::index_sequence< Is... >) const noexcept
Returns the size of the single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:356
auto & boundary() noexcept
Returns a non-constant reference to the index-th boundary object.
Definition functionspace.hpp:262
auto boundingBox() const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:1127
FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:269
auto div(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Provides the div operation.
Definition functionspace.hpp:1372
auto curl(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Provides the curl operation.
Definition functionspace.hpp:1249
static constexpr std::size_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:214
auto to_(std::index_sequence< Is... >, std::index_sequence< Js... >, Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:955
auto jac(const utils::TensorArray3 &xi, const std::tuple< utils::TensorArray3, utils::TensorArray3, utils::TensorArray3 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the jac operation.
Definition functionspace.hpp:2217
auto jac(const utils::TensorArray< nspaces()> &xi) const
Returns a block-tensor with the Jacobian of the function space object in the points xi with respect t...
Definition functionspace.hpp:2137
static constexpr const auto & degrees() noexcept
Returns a constant reference to the array of degrees of the index-th space.
Definition functionspace.hpp:114
FunctionSpace(FunctionSpace &&)=default
Move constructor.
virtual torch::Tensor spaces_as_tensor() const noexcept
Returns a single-tensor representation of the tuple of spaces.
Definition functionspace.hpp:298
torch::Tensor boundary_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:308
auto & space() noexcept
Returns a non-constant reference to the index-th space.
Definition functionspace.hpp:245
auto & uniform_refine_(std::index_sequence< Is... >, std::index_sequence< Js... >, int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:930
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:1074
std::tuple< Boundaries... > boundary_type
Boundary type.
Definition functionspace.hpp:86
FunctionSpace(std::tuple< Splines... > &&spline, std::tuple< Boundaries... > &&boundary)
Provides the FunctionSpace operation.
Definition functionspace.hpp:201
std::common_type_t< typename Splines::value_type... > value_type
Value type.
Definition functionspace.hpp:77
auto eval_from_precomputed_(std::index_sequence< Is... >, const std::tuple< Basfunc... > &basfunc, const std::tuple< Coeff_Indices... > &coeff_indices, const std::tuple< Xi... > &xi) const
Returns the value of the spline objects from precomputed basis function.
Definition functionspace.hpp:726
virtual FunctionSpace & from_tensor(const torch::Tensor &tensor)
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:467
auto clone() const noexcept
Returns a clone of a subset of the function space.
Definition functionspace.hpp:274
auto div(const utils::TensorArray< nspaces()> &xi) const
Returns a block-tensor with the divergence of the function space object with respect to the parametri...
Definition functionspace.hpp:1362
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:1093
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:944
FunctionSpace & from_xml(const pugi::xml_node &root, int id=0, const std::string &label="")
Updates the function space object from XML node.
Definition functionspace.hpp:538
FunctionSpace & boundary_from_tensor_(std::index_sequence< Is... >, const torch::Tensor &tensor)
Sets the tuple of boundaries from a single-tensor representation of the boundaries only.
Definition functionspace.hpp:422
auto eval_basfunc(const std::tuple< Xi... > &xi) const
Returns the values of the spline objects' basis functions in the points xi
Definition functionspace.hpp:874
FunctionSpace(const FunctionSpace &)=default
Copy constructor.
auto hess(const utils::TensorArray4 &xi, const std::tuple< utils::TensorArray4, utils::TensorArray4, utils::TensorArray4, utils::TensorArray4 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the hess operation.
Definition functionspace.hpp:1900
spline_type spline_
Splines.
Definition functionspace.hpp:132
virtual FunctionSpace & boundary_from_tensor(const torch::Tensor &tensor)
Sets the tuple of boundaries from a single-tensor representation of the boundaries only.
Definition functionspace.hpp:436
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices, const std::tuple< Coeff_Indices... > &coeff_indices) const
Returns the values of the spline objects in the points xi
Definition functionspace.hpp:630
auto curl(const utils::TensorArray< nspaces()> &xi) const
Returns a block-tensor with the curl of the function space object with respect to the parametric vari...
Definition functionspace.hpp:1226
auto lapl(const utils::TensorArray2 &xi, const std::tuple< utils::TensorArray2, utils::TensorArray2 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the lapl operation.
Definition functionspace.hpp:2394
FunctionSpace & boundary_from_full_tensor_(std::index_sequence< Is... >, const torch::Tensor &tensor)
Sets the tuple of boundaries from a single-tensor representation.
Definition functionspace.hpp:445
auto find_coeff_indices(const std::tuple< Knot_Indices... > &knot_indices) const
Returns the indices of the spline objects' coefficients corresponding to the knot indices indices.
Definition functionspace.hpp:921
auto scale_(std::index_sequence< Is... >, value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:1022
auto eval_basfunc_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices) const
Returns the values of the spline objects' basis functions in the points xi
Definition functionspace.hpp:852
auto boundingBox_(std::index_sequence< Is... >) const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:1120
std::tuple< typename Boundaries::eval_type... > boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:89
auto grad(const utils::TensorArray2 &xi, const std::tuple< utils::TensorArray2, utils::TensorArray2 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the grad operation.
Definition functionspace.hpp:1571
auto eval(const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices, const std::tuple< Coeff_Indices... > &coeff_indices) const
Provides the eval operation.
Definition functionspace.hpp:686
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:1053
auto lapl(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Provides the lapl operation.
Definition functionspace.hpp:2370
auto eval(const std::tuple< Xi... > &xi) const
Returns the values of the spline objects in the points xi
Definition functionspace.hpp:654
auto curl(const utils::TensorArray4 &xi, const std::tuple< utils::TensorArray4, utils::TensorArray4, utils::TensorArray4, utils::TensorArray4 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the curl operation.
Definition functionspace.hpp:1322
auto lapl(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Provides the lapl operation.
Definition functionspace.hpp:2357
auto hess(const utils::TensorArray2 &xi, const std::tuple< utils::TensorArray2, utils::TensorArray2 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the hess operation.
Definition functionspace.hpp:1752
auto div(const utils::TensorArray3 &xi, const std::tuple< utils::TensorArray3, utils::TensorArray3, utils::TensorArray3 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the div operation.
Definition functionspace.hpp:1437
FunctionSpace(const std::array< std::vector< typename Splines::value_type >, Splines::parDim()> &...kv, enum init init=init::greville, Options< value_type > options=iganet::Options< value_type >{})
Provides the FunctionSpace operation.
Definition functionspace.hpp:165
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:970
FunctionSpace(std::tuple< Splines... > &&spline)
Provides the FunctionSpace operation.
Definition functionspace.hpp:187
auto grad(const utils::TensorArray< nspaces()> &xi) const
Returns a block-tensor with the gradient of the function space object in the points xi with respect t...
Definition functionspace.hpp:1524
FunctionSpace()=default
Default constructor.
int64_t spaces_as_tensor_size_(std::index_sequence< Is... >) const noexcept
Returns the size of the single-tensor representation of the tuple of function spaces.
Definition functionspace.hpp:336
auto to_(std::index_sequence< Is... >, std::index_sequence< Js... >, torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:980
std::tuple< utils::TensorArray< Splines::parDim()>... > eval_type
Spline evaluation type.
Definition functionspace.hpp:83
auto hess(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Provides the hess operation.
Definition functionspace.hpp:1715
auto eval_from_precomputed_(std::index_sequence< Is... >, const std::tuple< Basfunc... > &basfunc, const std::tuple< Coeff_Indices... > &coeff_indices, const std::tuple< Numeval... > &numeval, const std::tuple< Sizes... > &sizes) const
Returns the value of the spline objects from precomputed basis function.
Definition functionspace.hpp:708
auto to_(std::index_sequence< Is... >, std::index_sequence< Js... >) const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:1000
nlohmann::json to_json_(std::index_sequence< Is... >) const
Serialization to JSON.
Definition functionspace.hpp:547
auto eval_basfunc(const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices) const
Provides the eval_basfunc operation.
Definition functionspace.hpp:887
virtual int64_t spaces_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the tuple of function spaces.
Definition functionspace.hpp:346
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:1113
auto div(const utils::TensorArray2 &xi, const std::tuple< utils::TensorArray2, utils::TensorArray2 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the div operation.
Definition functionspace.hpp:1409
auto find_coeff_indices_(std::index_sequence< Is... >, const std::tuple< Knot_Indices... > &knot_indices) const
Returns the indices of the spline objects' coefficients corresponding to the knot indices indices.
Definition functionspace.hpp:901
constexpr auto & boundaries() noexcept
Returns a non-constant reference to the tuple of boundary object.
Definition functionspace.hpp:232
auto lapl(const utils::TensorArray3 &xi, const std::tuple< utils::TensorArray3, utils::TensorArray3, utils::TensorArray3 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the lapl operation.
Definition functionspace.hpp:2422
const auto & boundary() const noexcept
Returns a constant reference to the index-th boundary object.
Definition functionspace.hpp:253
FunctionSpace(const std::array< int64_t, Splines::parDim()> &...ncoeffs, enum init init=init::greville, Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition functionspace.hpp:152
auto jac(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Provides the jac operation.
Definition functionspace.hpp:2147
auto curl(const utils::TensorArray2 &xi, const std::tuple< utils::TensorArray2, utils::TensorArray2 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor > &coeff_indices) const
Definition functionspace.hpp:1263
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:327
auto jac(const utils::TensorArray2 &xi, const std::tuple< utils::TensorArray2, utils::TensorArray2 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the jac operation.
Definition functionspace.hpp:2184
boundary_type boundary_
Boundaries.
Definition functionspace.hpp:135
auto div(const utils::TensorArray4 &xi, const std::tuple< utils::TensorArray4, utils::TensorArray4, utils::TensorArray4, utils::TensorArray4 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the div operation.
Definition functionspace.hpp:1472
constexpr const auto & boundaries() const noexcept
Returns a constant reference to the tuple of boundary object.
Definition functionspace.hpp:228
auto hess(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Provides the hess operation.
Definition functionspace.hpp:1728
constexpr const auto & spaces() const noexcept
Returns a constant reference to the tuple of function spaces.
Definition functionspace.hpp:220
void pretty_print(std::ostream &os) const noexcept override
Returns a string representation of the function space object.
Definition functionspace.hpp:1191
const auto & space() const noexcept
Returns a constant reference to the index-th function space.
Definition functionspace.hpp:237
auto jac(const utils::TensorArray4 &xi, const std::tuple< utils::TensorArray4, utils::TensorArray4, utils::TensorArray4, utils::TensorArray4 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the jac operation.
Definition functionspace.hpp:2266
FunctionSpace & from_xml(const pugi::xml_document &doc, int id=0, const std::string &label="")
Updates the function space object from XML object.
Definition functionspace.hpp:528
pugi::xml_node & to_xml_(std::index_sequence< Is... >, pugi::xml_node &root, int id=0, const std::string &label="") const
Returns the function space object as XML node.
Definition functionspace.hpp:478
static constexpr short_t degree(short_t i) noexcept
Returns a constant reference to the degree in the. -th dimension of the index-th space.
Definition functionspace.hpp:125
torch::serialize::OutputArchive & write(torch::serialize::OutputArchive &archive, const std::string &key="functionspace") const
Writes the function space object into a torch::serialize::OutputArchive object.
Definition functionspace.hpp:1154
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices) const
Returns the values of the spline objects in the points xi
Definition functionspace.hpp:614
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Provides the find_knot_indices operation.
Definition functionspace.hpp:823
auto grad(const utils::TensorArray4 &xi, const std::tuple< utils::TensorArray4, utils::TensorArray4, utils::TensorArray4, utils::TensorArray4 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the grad operation.
Definition functionspace.hpp:1634
FunctionSpace & spaces_from_tensor_(std::index_sequence< Is... >, const torch::Tensor &tensor)
Sets the tuple of spaces from a single-tensor representation.
Definition functionspace.hpp:384
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:1033
auto find_knot_indices_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the knot indices of knot spans containing xi
Definition functionspace.hpp:794
bool operator==(const FunctionSpace< SplinesOther, BoundariesOther > &other) const
Returns true if both function space objects are the same.
Definition functionspace.hpp:578
auto eval(const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices) const
Provides the eval operation.
Definition functionspace.hpp:668
auto div(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Provides the div operation.
Definition functionspace.hpp:1385
FunctionSpace(const std::tuple< Splines... > &spline)
Provides the FunctionSpace operation.
Definition functionspace.hpp:180
torch::serialize::InputArchive & read_(std::index_sequence< Is... >, torch::serialize::InputArchive &archive, const std::string &key="functionspace")
Loads the function space object from a torch::serialize::InputArchive object.
Definition functionspace.hpp:1165
pugi::xml_node & to_xml(pugi::xml_node &root, int id=0, const std::string &label="") const
Returns the function space object as XML node.
Definition functionspace.hpp:505
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &tensor)
Sets the tuple of boundaries from a single-tensor representation.
Definition functionspace.hpp:459
torch::Tensor spaces_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of spaces.
Definition functionspace.hpp:290
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &tensor)
Sets the tuple of spaces from a single-tensor representation.
Definition functionspace.hpp:413
auto curl(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Provides the curl operation.
Definition functionspace.hpp:1236
static constexpr short_t parDim() noexcept
Returns the parametric dimensions of the index-th space.
Definition functionspace.hpp:104
auto scale_(std::index_sequence< Is... >, std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:1040
auto hess(const utils::TensorArray3 &xi, const std::tuple< utils::TensorArray3, utils::TensorArray3, utils::TensorArray3 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the hess operation.
Definition functionspace.hpp:1797
auto lapl(const utils::TensorArray< nspaces()> &xi) const
Returns a block-tensor with the Laplacian of the function space object in the points xi with respect ...
Definition functionspace.hpp:2347
auto curl(const utils::TensorArray3 &xi, const std::tuple< utils::TensorArray3, utils::TensorArray3, utils::TensorArray3 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Definition functionspace.hpp:1285
constexpr auto & spaces() noexcept
Returns a non-constant reference to the tuple of function spaces.
Definition functionspace.hpp:224
auto translate_(std::index_sequence< Is... >, std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:1060
auto find_knot_indices_(std::index_sequence< Is... >, const utils::TensorArray< nspaces()> &xi) const
Returns the knot indices of knot spans containing xi
Definition functionspace.hpp:784
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the values of the spline objects in the points xi
Definition functionspace.hpp:599
std::tuple< Splines... > spline_type
Spline type.
Definition functionspace.hpp:80
auto lapl(const utils::TensorArray4 &xi, const std::tuple< utils::TensorArray4, utils::TensorArray4, utils::TensorArray4, utils::TensorArray4 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the lapl operation.
Definition functionspace.hpp:2457
FunctionSpace(const std::tuple< Splines... > &spline, const std::tuple< Boundaries... > &boundary)
Provides the FunctionSpace operation.
Definition functionspace.hpp:194
auto grad(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Provides the grad operation.
Definition functionspace.hpp:1547
auto rotate_(std::index_sequence< Is... >, value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:1081
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:316
auto grad(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Provides the grad operation.
Definition functionspace.hpp:1534
torch::serialize::OutputArchive & write_(std::index_sequence< Is... >, torch::serialize::OutputArchive &archive, const std::string &key="functionspace") const
Writes the function space object into a torch::serialize::OutputArchive object.
Definition functionspace.hpp:1136
auto grad(const utils::TensorArray3 &xi, const std::tuple< utils::TensorArray3, utils::TensorArray3, utils::TensorArray3 > &knot_indices, const std::tuple< torch::Tensor, torch::Tensor, torch::Tensor > &coeff_indices) const
Provides the grad operation.
Definition functionspace.hpp:1599
static constexpr std::size_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:208
auto eval_from_precomputed(const std::tuple< Basfunc... > &basfunc, const std::tuple< Coeff_Indices... > &coeff_indices, const std::tuple< Xi... > &xi) const
Provides the eval_from_precomputed operation.
Definition functionspace.hpp:770
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:377
pugi::xml_document to_xml(int id=0, const std::string &label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:491
FunctionSpace & from_xml_(std::index_sequence< Is... >, const pugi::xml_node &root, int id=0, const std::string &label="")
Updates the function space object from XML object.
Definition functionspace.hpp:514
Function space.
Definition functionspace.hpp:2751
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:3307
auto find_coeff_indices(const Knot_Indices &knot_indices) const
Returns the indices of the spline objects' coefficients corresponding to the knot indices indices.
Definition functionspace.hpp:3282
FunctionSpace(const Spline &spline)
Provides the FunctionSpace operation.
Definition functionspace.hpp:2855
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:3357
FunctionSpace(const std::array< int64_t, Spline::parDim()> &ncoeffs, enum init init=init::greville, Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition functionspace.hpp:2830
auto eval_basfunc(const Args &...args) const
Returns the values of the spline objects' basis functions in the points xi.
Definition functionspace.hpp:3252
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:2997
bool operator==(const FunctionSpace< SplinesOther, BoundariesOther > &other) const
Returns true if both function space objects are the same.
Definition functionspace.hpp:3098
auto find_coeff_indices_(std::index_sequence< Is... >, const Knot_Indices &knot_indices) const
Returns the indices of the spline objects' coefficients corresponding to the knot indices indices.
Definition functionspace.hpp:3265
constexpr const boundary_type & boundary() const noexcept
Returns a constant reference to the index-th boundary object.
Definition functionspace.hpp:2916
virtual torch::Tensor spaces_as_tensor() const noexcept
Returns a single-tensor representation of the space.
Definition functionspace.hpp:2957
pugi::xml_document to_xml(int id=0, const std::string &label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:3042
FunctionSpace()=default
Default constructor.
torch::serialize::InputArchive & read(torch::serialize::InputArchive &archive, const std::string &key="functionspace")
Loads the function space object from a torch::serialize::InputArchive object.
Definition functionspace.hpp:3410
virtual int64_t boundary_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the boundary.
Definition functionspace.hpp:2987
static constexpr short_t geoDim() noexcept
Returns the geometric dimensions of the index-th space.
Definition functionspace.hpp:2773
FunctionSpace & transform(const std::function< std::array< typename Spline::value_type, Spline::geoDim()>(const std::array< typename Spline::value_type, Spline::parDim()> &)> mapping)
Transforms the coefficients based on the given mapping.
Definition functionspace.hpp:3116
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the boundary.
Definition functionspace.hpp:2963
constexpr boundary_type & boundary() noexcept
Returns a non-constant reference to the index-th boundary object.
Definition functionspace.hpp:2926
static constexpr short_t parDim() noexcept
Returns the parametric dimensions of the index-th space.
Definition functionspace.hpp:2782
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:3347
Spline spline_type
Spline type.
Definition functionspace.hpp:2758
void pretty_print(std::ostream &os) const noexcept override
Returns a string representation of the function space object.
Definition functionspace.hpp:3419
pugi::xml_node & to_xml(pugi::xml_node &root, int id=0, const std::string &label="") const
Returns the function space object as XML node.
Definition functionspace.hpp:3056
virtual int64_t spaces_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the space.
Definition functionspace.hpp:2980
FunctionSpace & from_xml(const pugi::xml_document &doc, int id=0, const std::string &label="")
Updates the function space object from XML object.
Definition functionspace.hpp:3066
auto find_knot_indices(const Xi &xi) const
Returns the knot indices of knot spans containing xi.
Definition functionspace.hpp:3229
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the values of the spline object in the points xi
Definition functionspace.hpp:3131
torch::serialize::OutputArchive & write(torch::serialize::OutputArchive &archive, const std::string &key="functionspace") const
Writes the function space object into a torch::serialize::OutputArchive object.
Definition functionspace.hpp:3397
FunctionSpace(Spline &&spline)
Provides the FunctionSpace operation.
Definition functionspace.hpp:2863
Boundary::eval_type boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:2767
constexpr spline_type & space() noexcept
Returns a non-constant reference to the index-th function space.
Definition functionspace.hpp:2907
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:3329
auto eval(const Arg &arg, const Args &...args) const
Returns the values of the spline object in the points xi.
Definition functionspace.hpp:3180
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices, const std::tuple< Coeff_Indices... > &coeff_indices) const
Returns the values of the spline object in the points xi
Definition functionspace.hpp:3158
constexpr auto & spaces() noexcept
Returns a non-constant reference to the tuple of function spaces.
Definition functionspace.hpp:2884
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:3385
static constexpr std::size_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:2872
constexpr FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:2933
auto find_knot_indices_(std::index_sequence< Is... >, const Xi &xi) const
Returns the knot indices of knot spans containing xi.
Definition functionspace.hpp:3214
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:3376
static constexpr std::size_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:2876
static constexpr const auto & degrees() noexcept
Returns a constant reference to the array of degrees of the index-th space.
Definition functionspace.hpp:2792
constexpr const auto & spaces() const noexcept
Returns a constant reference to the tuple of function spaces.
Definition functionspace.hpp:2880
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:3367
static constexpr short_t degree(short_t i) noexcept
Returns a constant reference to the degree in the. -th dimension of the index-th space.
Definition functionspace.hpp:2803
FunctionSpace & from_xml(const pugi::xml_node &root, int id=0, const std::string &label="")
Updates the function space object from XML node.
Definition functionspace.hpp:3076
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:3318
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Knot_Indices... > &knot_indices) const
Returns the values of the spline object in the points xi
Definition functionspace.hpp:3144
virtual FunctionSpace & boundary_from_tensor(const torch::Tensor &coeffs) noexcept
Sets the boundary from a single-tensor representation of the boundary only.
Definition functionspace.hpp:3015
constexpr auto & boundaries() noexcept
Returns a non-constant reference to the tuple of boundary object.
Definition functionspace.hpp:2892
FunctionSpace(FunctionSpace &&)=default
Move constructor.
boundary_type boundary_
Boundary.
Definition functionspace.hpp:2813
Boundary boundary_type
Boundary type.
Definition functionspace.hpp:2764
utils::TensorArray< Spline::parDim()> eval_type
Spline evaluation type.
Definition functionspace.hpp:2761
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &coeffs) noexcept
Sets the space from a single-tensor representation.
Definition functionspace.hpp:3005
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &coeffs) noexcept
Sets the boundary from a single-tensor representation.
Definition functionspace.hpp:3024
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:2973
constexpr const auto & boundaries() const noexcept
Returns a constant reference to the tuple of boundary object.
Definition functionspace.hpp:2888
FunctionSpace(const FunctionSpace &)=default
Copy constructor.
spline_type spline_
Spline.
Definition functionspace.hpp:2810
Spline::value_type value_type
Value type.
Definition functionspace.hpp:2755
auto eval_from_precomputed(const Args &...args) const
Returns the value of the spline object from precomputed basis function.
Definition functionspace.hpp:3203
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:3084
FunctionSpace & from_tensor(const torch::Tensor &coeffs) noexcept
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:3032
FunctionSpace(std::array< std::vector< value_type >, Spline::parDim()> kv, enum init init=init::greville, Options< value_type > options=iganet::Options< value_type >{})
Provides the FunctionSpace operation.
Definition functionspace.hpp:2843
constexpr const spline_type & space() const noexcept
Returns a constant reference to the index-th function space.
Definition functionspace.hpp:2898
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:3336
constexpr auto clone() const noexcept
Returns a subset of the tuple of function spaces.
Definition functionspace.hpp:2940
Full qualified name descriptor.
Definition fqn.hpp:22
virtual const std::string & name() const noexcept
Returns the full qualified name of the object.
Definition fqn.hpp:28
Concept to identify template parameters that are derived from iganet::details::FunctionSpaceType.
Definition functionspace.hpp:3646
Definition functionspace.hpp:54
Definition functionspace.hpp:47
Container utility functions.
#define IGANET_FUNCTIONSPACE_DEFAULT_OPS(FunctionSpace)
Macro: Implements the default methods of a function space.
Definition functionspace.hpp:37
FunctionSpace_trait< Spline, Boundary >::type type
Definition functionspace.hpp:3629
FunctionSpace_trait< utils::tuple_cat_t< Splines... >, utils::tuple_cat_t< Boundaries... > >::type type
Definition functionspace.hpp:3638
std::ostream & operator<<(std::ostream &os, const FunctionSpace< Splines... > &obj)
Print (as string) a function space object.
Definition functionspace.hpp:2737
Forward declaration.
Definition functionspace.hpp:3597
TensorArray< 4 > TensorArray4
Definition tensorarray.hpp:32
std::array< torch::Tensor, N > TensorArray
Definition tensorarray.hpp:26
auto zip(T &&...seqs)
Provides the zip operation.
Definition zip.hpp:135
TensorArray< 3 > TensorArray3
Definition tensorarray.hpp:31
TensorArray< 1 > TensorArray1
Definition tensorarray.hpp:29
tuple_cat< Tuples... >::type tuple_cat_t
Alias for tuple_cat::type.
Definition tuple.hpp:73
TensorArray< 2 > TensorArray2
Definition tensorarray.hpp:30
Forward declaration of BlockTensor.
Definition blocktensor.hpp:47
deriv
Enumerator for specifying the derivative of B-spline evaluation.
Definition bspline.hpp:76
BoundaryCommon< BoundaryCore< Spline, Spline::parDim()> > Boundary
Boundary.
Definition boundary.hpp:2171
detail::FunctionSpace_trait< Args... >::type FunctionSpace
Function space alias.
Definition functionspace.hpp:3650
std::ostream & operator<<(std::ostream &os, const MemoryDebugger< id > &obj)
Prints a memory debugger object.
Definition memory.hpp:145
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:58
FunctionSpace< Spline > S
Spline function space .
Definition functionspace.hpp:3683
functionspace
Enumerator for the function space component.
Definition functionspace.hpp:31
@ none
Definition boundary.hpp:38
short int short_t
Signed short integer type used by IgANet's compact enumerations.
Definition core.hpp:76
H(curl) function space.
Definition functionspace.hpp:4667
Nedelec like function space.
Definition functionspace.hpp:4036
Nedelec-Raviart-Thomas-$P$ triple function space.
Definition functionspace.hpp:4741
Raviart-Thomas like function space.
Definition functionspace.hpp:4376
Taylor-Hood like function space.
Definition functionspace.hpp:3686
Serialization prototype.
Definition serialize.hpp:29