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...>;
92 template <std::
size_t index>
94 static_assert(index <
nspaces());
95 return std::tuple_element_t<index, spline_type>::geoDim();
99 template <std::
size_t index>
101 static_assert(index <
nspaces());
102 return std::tuple_element_t<index, spline_type>::parDim();
107 template <std::
size_t index>
108 inline static constexpr const auto&
degrees() noexcept {
109 static_assert(index <
nspaces());
110 return std::tuple_element_t<index, spline_type>::degrees();
115 template <std::
size_t index>
117 static_assert(index <
nspaces());
118 return std::tuple_element_t<index, spline_type>::degree(i);
141 const std::array<int64_t, Splines::parDim()> &...ncoeffs,
150 const std::array<std::vector<typename Splines::value_type>,
151 Splines::parDim()> &...kv,
157 static_assert((Splines::is_nonuniform() && ... &&
true),
158 "Constructor is only available for non-uniform splines");
172 const std::tuple<Boundaries...> &
boundary)
176 std::tuple<Boundaries...> &&
boundary)
181 inline static constexpr std::size_t
nspaces() noexcept {
182 return sizeof...(Splines);
187 return sizeof...(Boundaries);
203 template <std::
size_t index>
inline const auto &
space() const noexcept {
204 static_assert(index <
nspaces());
205 return std::get<index>(
spline_);
209 template <std::
size_t index>
inline auto &
space() noexcept {
210 static_assert(index <
nspaces());
211 return std::get<index>(
spline_);
215 template <std::
size_t index>
inline const auto &
boundary() const noexcept {
222 template <std::
size_t index>
inline auto &
boundary() noexcept {
231 template <std::size_t... index>
inline auto clone() const noexcept {
233 static_assert(((index <
nspaces()) && ... &&
true));
236 std::tuple<std::tuple_element_t<index, spline_type>...>,
237 std::tuple<std::tuple_element_t<index, boundary_type>...>>(
238 std::make_tuple(std::get<index>(
spline_)...),
239 std::make_tuple(std::get<index>(
boundary_)...));
245 template <std::size_t... Is>
248 return torch::cat({std::get<Is>(
spline_).as_tensor()...});
255 return spaces_as_tensor_(
256 std::make_index_sequence<FunctionSpace::nspaces()>{});
262 template <std::size_t... Is>
265 return torch::cat({std::get<Is>(
boundary_).as_tensor()...});
272 return boundary_as_tensor_(
273 std::make_index_sequence<FunctionSpace::nboundaries()>{});
281 virtual inline torch::Tensor
as_tensor() const noexcept {
288 template <std::size_t... Is>
292 [](
auto... v) {
return (v + ...); },
300 return spaces_as_tensor_size_(
301 std::make_index_sequence<FunctionSpace::nspaces()>{});
307 template <std::size_t... Is>
311 [](
auto... v) {
return (v + ...); },
319 return boundary_as_tensor_size_(
320 std::make_index_sequence<FunctionSpace::nboundaries()>{});
334 template <std::size_t... Is>
336 const torch::Tensor &tensor) {
339 std::array<int64_t,
sizeof...(Is)> partialSums{0};
340 auto partial_sums = [&partialSums,
341 this]<std::size_t... Js>(std::index_sequence<Js...>) {
342 ((std::get<Js + 1>(partialSums) =
343 std::get<Js>(partialSums) + std::get<Js>(
spline_).as_tensor_size()),
346 partial_sums(std::make_index_sequence<FunctionSpace::nspaces() - 1>{});
349 ((std::get<Is>(
spline_).from_tensor(tensor.index(
350 {torch::indexing::Slice(partialSums[Is],
352 std::get<Is>(spline_).as_tensor_size()),
363 return spaces_from_tensor_(
364 std::make_index_sequence<FunctionSpace::nspaces()>{}, tensor);
370 template <std::size_t... Is>
372 const torch::Tensor &tensor) {
384 return boundary_from_tensor_(
385 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
390 template <std::size_t... Is>
393 const torch::Tensor &tensor) {
394 (std::get<Is>(
boundary_).from_full_tensor(
405 return boundary_from_full_tensor_(
406 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
411 spaces_from_tensor_(std::make_index_sequence<FunctionSpace::nspaces()>{},
413 boundary_from_full_tensor_(
414 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
420 template <std::size_t... Is>
421 inline pugi::xml_node &
to_xml_(std::index_sequence<Is...>,
422 pugi::xml_node &root,
int id = 0,
423 std::string label =
"")
const {
425 (std::get<Is>(
spline_).to_xml(root,
id, label, Is), ...);
431 inline pugi::xml_document
to_xml(
int id = 0,
432 const std::string &label =
"")
const {
433 pugi::xml_document doc;
434 pugi::xml_node root = doc.append_child(
"xml");
441 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
442 std::string label =
"")
const {
443 return to_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
449 template <std::size_t... Is>
451 const pugi::xml_node &root,
int id = 0,
452 std::string label =
"") {
454 (std::get<Is>(
spline_).from_xml(root,
id, label, Is), ...);
461 const std::string &label =
"") {
462 return from_xml(doc.child(
"xml"),
id, label);
467 std::string label =
"") {
468 return from_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
474 template <std::size_t... Is>
475 nlohmann::json
to_json_(std::index_sequence<Is...>)
const {
476 auto json_this = nlohmann::json::array();
477 auto json_boundary = nlohmann::json::array();
479 (json_boundary.push_back(std::get<Is>(
boundary_).to_json()), ...);
481 auto json = nlohmann::json::array();
482 for (
auto [t, b] :
utils::zip(json_this, json_boundary)) {
483 auto json_inner = nlohmann::json::array();
484 json_inner.push_back(t);
485 json_inner.push_back(b);
486 json.push_back(json_inner);
495 return to_json_(std::make_index_sequence<FunctionSpace::nspaces()>{});
499 template <
typename SplinesOther,
typename BoundariesOther>
504 if (!std::is_same_v<
spline_type,
typename std::remove_cvref_t<
521 std::size_t... Is,
typename... Xi>
522 inline auto eval_(std::index_sequence<Is...>,
523 const std::tuple<Xi...> &xi)
const {
526 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
527 std::get<Is>(xi))...);
530 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
531 std::get<Is>(xi))...);
536 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
537 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
538 const std::tuple<Knot_Indices...> &knot_indices)
const {
541 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
542 std::get<Is>(xi), std::get<Is>(knot_indices))...);
545 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
546 std::get<Is>(xi), std::get<Is>(knot_indices))...);
551 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
552 typename... Coeff_Indices>
553 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
554 const std::tuple<Knot_Indices...> &knot_indices,
555 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
558 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
559 std::get<Is>(xi), std::get<Is>(knot_indices),
560 std::get<Is>(coeff_indices))...);
563 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
564 std::get<Is>(xi), std::get<Is>(knot_indices),
565 std::get<Is>(coeff_indices))...);
575 inline auto eval(
const std::tuple<Xi...> &xi)
const {
576 static_assert(FunctionSpace::nspaces() ==
sizeof...(Xi),
577 "Size of Xi mismatches functionspace dimension");
578 return eval_<comp, deriv, memory_optimized>(
579 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
584 typename... Xi,
typename... Knot_Indices>
585 inline auto eval(
const std::tuple<Xi...> &xi,
586 const std::tuple<Knot_Indices...> &knot_indices)
const {
588 (FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
589 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)),
590 "Sizes of Xi and Knot_Indices mismatch functionspace dimension");
591 return eval_<comp, deriv, memory_optimized>(
592 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
597 typename... Xi,
typename... Knot_Indices,
typename... Coeff_Indices>
598 inline auto eval(
const std::tuple<Xi...> &xi,
599 const std::tuple<Knot_Indices...> &knot_indices,
600 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
601 static_assert((FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
602 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)) &&
603 (FunctionSpace::nspaces() ==
sizeof...(Coeff_Indices)),
604 "Sizes of Xi, Knot_Indices and Coeff_Indices mismatch "
605 "functionspace dimension");
606 return eval_<comp, deriv, memory_optimized>(
607 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices,
617 typename... Basfunc,
typename... Coeff_Indices,
typename... Numeval,
621 const std::tuple<Basfunc...> &basfunc,
622 const std::tuple<Coeff_Indices...> &coeff_indices,
623 const std::tuple<Numeval...> &numeval,
624 const std::tuple<Sizes...> &sizes)
const {
626 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
627 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
628 std::get<Is>(numeval), std::get<Is>(sizes))...);
630 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
631 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
632 std::get<Is>(numeval), std::get<Is>(sizes))...);
636 typename... Basfunc,
typename... Coeff_Indices,
typename... Xi>
639 const std::tuple<Basfunc...> &basfunc,
640 const std::tuple<Coeff_Indices...> &coeff_indices,
641 const std::tuple<Xi...> &xi)
const {
643 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
644 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
645 std::get<Is>(xi)[0].numel(), std::get<Is>(xi)[0].sizes())...);
647 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
648 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
649 std::get<Is>(xi))...);
658 typename... Coeff_Indices,
typename... Numeval,
typename... Sizes>
661 const std::tuple<Coeff_Indices...> &coeff_indices,
662 const std::tuple<Numeval...> &numeval,
663 const std::tuple<Sizes...> &sizes)
const {
664 return eval_from_precomputed_<comp>(
665 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
666 coeff_indices, numeval, sizes);
670 typename... Coeff_Indices,
typename... Xi>
673 const std::tuple<Coeff_Indices...> &coeff_indices,
674 const std::tuple<Xi...> &xi)
const {
675 return eval_from_precomputed_<comp>(
676 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
689 return std::tuple(std::get<Is>(
spline_).find_knot_indices(xi)...);
691 return std::tuple(std::get<Is>(
boundary_).find_knot_indices(xi)...);
697 const std::tuple<Xi...> &xi)
const {
700 std::get<Is>(
spline_).find_knot_indices(std::get<Is>(xi))...);
703 std::get<Is>(
boundary_).find_knot_indices(std::get<Is>(xi))...);
710 template <functionspace comp = functionspace::
interior>
712 return find_knot_indices_<comp>(
713 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
718 return find_knot_indices_<comp>(
719 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
729 std::size_t... Is,
typename... Xi>
731 const std::tuple<Xi...> &xi)
const {
734 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
735 std::get<Is>(xi))...);
737 return std::tuple(std::get<Is>(
boundary_)
738 .template eval_basfunc<deriv, memory_optimized>(
739 std::get<Is>(xi))...);
744 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
747 const std::tuple<Knot_Indices...> &knot_indices)
const {
750 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
751 std::get<Is>(xi), std::get<Is>(knot_indices))...);
755 .template eval_basfunc<deriv, memory_optimized>(
756 std::get<Is>(xi), std::get<Is>(knot_indices))...);
767 return eval_basfunc_<comp, deriv, memory_optimized>(
768 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
773 typename... Xi,
typename... Knot_Indices>
776 const std::tuple<Knot_Indices...> &knot_indices)
const {
777 return eval_basfunc_<comp, deriv, memory_optimized>(
778 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
786 bool memory_optimized =
false, std::size_t... Is,
787 typename... Knot_Indices>
790 const std::tuple<Knot_Indices...> &knot_indices)
const {
793 std::get<Is>(
spline_).template find_coeff_indices<memory_optimized>(
794 std::get<Is>(knot_indices))...);
797 std::get<Is>(
boundary_).template find_coeff_indices<memory_optimized>(
798 std::get<Is>(knot_indices))...);
805 bool memory_optimized =
false,
typename... Knot_Indices>
808 return find_coeff_indices_<comp, memory_optimized>(
809 std::make_index_sequence<FunctionSpace::nspaces()>{}, knot_indices);
815 template <std::size_t... Is, std::size_t... Js>
817 std::index_sequence<Js...>,
int numRefine = 1,
818 int dimRefine = -1) {
819 (std::get<Is>(
spline_).uniform_refine(numRefine, dimRefine), ...);
820 (std::get<Js>(
boundary_).uniform_refine(numRefine, dimRefine), ...);
828 return uniform_refine_(
829 std::make_index_sequence<FunctionSpace::nspaces()>{},
830 std::make_index_sequence<FunctionSpace::nboundaries()>{}, numRefine,
837 template <
typename real_t, std::size_t... Is, std::size_t... Js>
838 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
841 typename Splines::template real_derived_self_type<real_t>...,
842 typename Boundaries::template real_derived_self_type<real_t>...>(
843 std::get<Is>(
spline_).to(options)...,
851 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
852 std::make_index_sequence<FunctionSpace::nboundaries()>{},
859 template <std::size_t... Is, std::size_t... Js>
860 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
861 torch::Device device)
const {
869 inline auto to(torch::Device device)
const {
870 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
871 std::make_index_sequence<FunctionSpace::nboundaries()>{},
877 template <
typename real_t, std::size_t... Is, std::size_t... Js>
878 inline auto to_(std::index_sequence<Is...>,
879 std::index_sequence<Js...>)
const {
881 typename Splines::template real_derived_self_type<real_t>...,
882 typename Boundaries::template real_derived_self_type<real_t>...>(
883 std::get<Is>(
spline_).template to<real_t>()...,
884 std::get<Js>(
boundary_).template to<real_t>()...);
889 template <
typename real_t>
inline auto to()
const {
891 std::make_index_sequence<FunctionSpace::nspaces()>{},
892 std::make_index_sequence<FunctionSpace::nboundaries()>{});
897 template <std::size_t... Is>
899 (std::get<Is>(
spline_).scale(s, dim), ...);
907 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, s, dim);
912 template <std::size_t N, std::size_t... Is>
913 inline auto scale_(std::index_sequence<Is...>, std::array<value_type, N> v) {
914 (std::get<Is>(
spline_).scale(v), ...);
915 (std::get<Is>(
boundary_).from_full_tensor(
923 template <std::
size_t N>
inline auto scale(std::array<value_type, N> v) {
924 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
929 template <std::size_t N, std::size_t... Is>
931 std::array<value_type, N> v) {
932 (std::get<Is>(
spline_).translate(v), ...);
933 (std::get<Is>(
boundary_).from_full_tensor(
941 template <std::
size_t N>
inline auto translate(std::array<value_type, N> v) {
942 return translate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
947 template <std::size_t... Is>
949 (std::get<Is>(
spline_).rotate(angle), ...);
950 (std::get<Is>(
boundary_).from_full_tensor(
959 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
964 template <std::size_t... Is>
965 inline auto rotate_(std::index_sequence<Is...>,
966 std::array<value_type, 3> angle) {
967 (std::get<Is>(
spline_).rotate(angle), ...);
968 (std::get<Is>(
boundary_).from_full_tensor(
976 inline auto rotate(std::array<value_type, 3> angle) {
977 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
982 template <std::size_t... Is>
984 return std::tuple(std::get<Is>(
spline_).boundingBox()...);
990 return boundingBox_(std::make_index_sequence<FunctionSpace::nspaces()>{});
996 template <std::size_t... Is>
997 inline torch::serialize::OutputArchive &
998 write_(std::index_sequence<Is...>, torch::serialize::OutputArchive &archive,
999 const std::string &key =
"functionspace")
const {
1001 archive, key +
".fspace[" + std::to_string(Is) +
"].interior"),
1004 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
1012 inline torch::serialize::OutputArchive &
1013 write(torch::serialize::OutputArchive &archive,
1014 const std::string &key =
"functionspace")
const {
1015 write_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
1022 template <std::size_t... Is>
1023 inline torch::serialize::InputArchive &
1024 read_(std::index_sequence<Is...>, torch::serialize::InputArchive &archive,
1025 const std::string &key =
"functionspace") {
1026 (std::get<Is>(
spline_).read(archive, key +
".fspace[" + std::to_string(Is) +
1030 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
1038 inline torch::serialize::InputArchive &
1039 read(torch::serialize::InputArchive &archive,
1040 const std::string &key =
"functionspace") {
1041 read_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
1048 auto pretty_print_ = [
this,
1049 &os]<std::size_t... Is>(std::index_sequence<Is...>) {
1050 ((os <<
"\ninterior = ", std::get<Is>(
spline_).pretty_print(os),
1051 os <<
"\nboundary = ", std::get<Is>(
boundary_).pretty_print(os)),
1055 pretty_print_(std::make_index_sequence<
nspaces()>{});
1080 bool memory_optimized =
false>
1082 return curl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1086 bool memory_optimized =
false,
typename... TensorArrays>
1088 const std::tuple<TensorArrays...> &knot_indices)
const {
1089 return curl<comp, memory_optimized>(xi, knot_indices,
1090 find_coeff_indices<comp>(knot_indices));
1094 bool memory_optimized =
false>
1096 const std::tuple<utils::TensorArray1> &knot_indices,
1097 const std::tuple<torch::Tensor> &coeff_indices)
const {
1099 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1101 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1107 bool memory_optimized =
false>
1110 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1111 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1113 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1114 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1115 xi[0].sizes() == xi[1].sizes());
1123 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1124 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1125 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1126 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1130 bool memory_optimized =
false>
1134 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1135 &coeff_indices)
const {
1137 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1138 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1139 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1140 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1146 *std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1147 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] -
1148 *std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1149 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1150 *std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1151 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] -
1152 *std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1153 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1154 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1155 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1156 *std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1157 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1161 bool memory_optimized =
false>
1166 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1167 torch::Tensor> &coeff_indices)
const {
1169 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1170 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1171 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1172 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1173 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1174 xi[2].sizes() == xi[3].sizes());
1176 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1207 bool memory_optimized =
false>
1209 return div<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1213 bool memory_optimized =
false,
typename... TensorArrays>
1215 const std::tuple<TensorArrays...> &knot_indices)
const {
1216 return div<comp, memory_optimized>(xi, knot_indices,
1217 find_coeff_indices<comp>(knot_indices));
1221 bool memory_optimized =
false>
1223 const std::tuple<utils::TensorArray1> &knot_indices,
1224 const std::tuple<torch::Tensor> &coeff_indices)
const {
1226 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1229 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1230 "div(.) for vector-valued spaces requires 1D variables");
1233 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1234 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1239 bool memory_optimized =
false>
1242 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1243 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1245 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1246 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1247 xi[0].sizes() == xi[1].sizes());
1250 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1251 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1252 "div(.) for vector-valued spaces requires 1D variables");
1255 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1256 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1257 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1258 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1263 bool memory_optimized =
false>
1267 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1268 &coeff_indices)
const {
1270 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1271 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1272 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1273 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1276 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1277 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1278 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1279 "div(.) for vector-valued spaces requires 1D variables");
1282 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1283 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1284 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1285 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1286 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1287 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1292 bool memory_optimized =
false>
1297 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1298 torch::Tensor> &coeff_indices)
const {
1300 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1301 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1302 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1303 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1304 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1305 xi[2].sizes() == xi[3].sizes());
1308 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1309 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1310 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1311 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1312 "div(.) for vector-valued spaces requires 1D variables");
1315 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1316 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1317 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1318 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1319 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1320 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
1321 *std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1322 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1345 bool memory_optimized =
false>
1347 return grad<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1351 bool memory_optimized =
false,
typename... TensorArrays>
1353 const std::tuple<TensorArrays...> &knot_indices)
const {
1354 return grad<comp, memory_optimized>(xi, knot_indices,
1355 find_coeff_indices<comp>(knot_indices));
1359 bool memory_optimized =
false>
1361 const std::tuple<utils::TensorArray1> &knot_indices,
1362 const std::tuple<torch::Tensor> &coeff_indices)
const {
1364 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1367 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1368 "grad(.) for vector-valued spaces requires 1D variables");
1371 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1372 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1377 bool memory_optimized =
false>
1380 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1381 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1383 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1384 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1385 xi[0].sizes() == xi[1].sizes());
1388 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1389 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1390 "grad(.) for vector-valued spaces requires 1D variables");
1393 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1394 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1395 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1396 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1401 bool memory_optimized =
false>
1405 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1406 &coeff_indices)
const {
1408 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1409 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1410 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1411 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1414 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1415 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1416 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1417 "div(.) for vector-valued spaces requires 1D variables");
1420 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1421 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1422 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1423 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1424 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1425 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1430 bool memory_optimized =
false>
1435 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1436 torch::Tensor> &coeff_indices)
const {
1438 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1439 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1440 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1441 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1442 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1443 xi[2].sizes() == xi[3].sizes());
1446 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1447 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1448 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1449 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1450 "grad(.) for vector-valued spaces requires 1D variables");
1453 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1454 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1455 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1456 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1457 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1458 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1459 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1460 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1502 bool memory_optimized =
false>
1504 return hess<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1508 bool memory_optimized =
false,
typename... TensorArrays>
1510 const std::tuple<TensorArrays...> &knot_indices)
const {
1511 return hess<comp, memory_optimized>(xi, knot_indices,
1512 find_coeff_indices<comp>(knot_indices));
1516 bool memory_optimized =
false>
1518 const std::tuple<utils::TensorArray1> &knot_indices,
1519 const std::tuple<torch::Tensor> &coeff_indices)
const {
1521 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1524 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1525 "hess(.) for vector-valued spaces requires 1D variables");
1528 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1529 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)));
1534 bool memory_optimized =
false>
1537 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1538 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1540 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1541 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1542 xi[0].sizes() == xi[1].sizes());
1545 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1546 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1547 "hess(.) for vector-valued spaces requires 1D variables");
1550 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1551 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1553 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1554 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1556 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1557 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1558 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1559 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1561 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1562 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1564 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1565 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1567 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1568 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1569 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1570 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)));
1575 bool memory_optimized =
false>
1579 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1580 &coeff_indices)
const {
1582 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1583 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1584 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1585 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1588 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1589 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1590 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1591 "hess(.) for vector-valued spaces requires 1D variables");
1594 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1595 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1597 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1598 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1600 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1601 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1603 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1604 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1605 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1606 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1608 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1609 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1611 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1612 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1614 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1615 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1616 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1617 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1619 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1620 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1622 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1623 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1625 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1626 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1628 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1629 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1630 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1631 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1633 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1634 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1636 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1637 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1639 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1640 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1641 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1642 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1644 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1645 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1647 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1648 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1650 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1651 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1653 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1654 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1655 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1656 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1658 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1659 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1661 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1662 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1664 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1665 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1666 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1667 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)));
1672 bool memory_optimized =
false>
1677 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1678 torch::Tensor> &coeff_indices)
const {
1680 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1681 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1682 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1683 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1684 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1685 xi[2].sizes() == xi[3].sizes());
1688 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1689 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1690 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1691 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1692 "hess(.) for vector-valued spaces requires 1D variables");
1695 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1696 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1698 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1699 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1701 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1702 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1704 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1705 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1707 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1708 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1709 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1710 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1712 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1713 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1715 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1716 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1718 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1719 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1721 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1722 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1723 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1724 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1726 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1727 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1729 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1730 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1732 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1733 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1735 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1736 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1737 std::get<0>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1738 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1740 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1741 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1743 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1744 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1746 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1747 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1749 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1750 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1752 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1753 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1754 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1755 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1757 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1758 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1760 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1761 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1763 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1764 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1766 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1767 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1768 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1769 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1771 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1772 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1774 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1775 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1777 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1778 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1780 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1781 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1782 std::get<1>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1783 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1785 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1786 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1788 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1789 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1791 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1792 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1794 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1795 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1797 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1798 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1799 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1800 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1802 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1803 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1805 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1806 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1808 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1809 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1811 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1812 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1813 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1814 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1816 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1817 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1819 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1820 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1822 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1823 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1825 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1826 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1827 std::get<2>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1828 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1830 std::get<3>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1831 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1833 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1834 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1836 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1837 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1839 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1840 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1842 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1843 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1844 std::get<3>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1845 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1847 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1848 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1850 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1851 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1853 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1854 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1856 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1857 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1858 std::get<3>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1859 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1861 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1862 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1864 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1865 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1867 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1868 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1870 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1871 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1872 std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1873 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)));
1915 bool memory_optimized =
false>
1917 return jac<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1921 bool memory_optimized =
false,
typename... TensorArrays>
1923 const std::tuple<TensorArrays...> &knot_indices)
const {
1924 return jac<comp, memory_optimized>(xi, knot_indices,
1925 find_coeff_indices<comp>(knot_indices));
1929 bool memory_optimized =
false>
1931 const std::tuple<utils::TensorArray1> &knot_indices,
1932 const std::tuple<torch::Tensor> &coeff_indices)
const {
1934 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1937 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1938 "jac(.) for vector-valued spaces requires 1D variables");
1941 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1942 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1947 bool memory_optimized =
false>
1950 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1951 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1953 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1954 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1955 xi[0].sizes() == xi[1].sizes());
1958 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1959 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1960 "jac(.) for vector-valued spaces requires 1D variables");
1963 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1964 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1965 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1966 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1968 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1969 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1970 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1971 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1976 bool memory_optimized =
false>
1980 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1981 &coeff_indices)
const {
1983 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1984 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1985 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1986 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1989 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1990 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1991 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1992 "jac(.) for vector-valued spaces requires 1D variables");
1995 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1996 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1997 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1998 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1999 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
2000 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2002 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
2003 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2004 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
2005 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2006 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
2007 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2009 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
2010 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2011 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
2012 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2013 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
2014 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
2019 bool memory_optimized =
false>
2024 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
2025 torch::Tensor> &coeff_indices)
const {
2027 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2028 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2029 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2030 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
2031 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
2032 xi[2].sizes() == xi[3].sizes());
2035 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2036 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2037 std::tuple_element_t<2, spline_type>::geoDim() == 1,
2038 "jac(.) for vector-valued spaces requires 1D variables");
2041 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
2042 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2043 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
2044 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2045 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
2046 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2047 std::get<0>(
spline_).
template eval<deriv::dt, memory_optimized>(
2048 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
2050 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
2051 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2052 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
2053 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2054 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
2055 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2056 std::get<1>(
spline_).
template eval<deriv::dt, memory_optimized>(
2057 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
2059 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
2060 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2061 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
2062 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2063 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
2064 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2065 std::get<2>(
spline_).
template eval<deriv::dt, memory_optimized>(
2066 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
2068 std::get<3>(
spline_).
template eval<deriv::dx, memory_optimized>(
2069 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2070 std::get<3>(
spline_).
template eval<deriv::dy, memory_optimized>(
2071 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2072 std::get<3>(
spline_).
template eval<deriv::dz, memory_optimized>(
2073 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2074 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
2075 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2101 bool memory_optimized =
false>
2103 return lapl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
2107 bool memory_optimized =
false,
typename... TensorArrays>
2109 const std::tuple<TensorArrays...> &knot_indices)
const {
2110 return lapl<comp, memory_optimized>(xi, knot_indices,
2111 find_coeff_indices<comp>(knot_indices));
2115 bool memory_optimized =
false>
2117 const std::tuple<utils::TensorArray1> &knot_indices,
2118 const std::tuple<torch::Tensor> &coeff_indices)
const {
2120 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
2123 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
2124 "lapl(.) for vector-valued spaces requires 1D variables");
2127 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2128 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
2133 bool memory_optimized =
false>
2136 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
2137 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
2139 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2140 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2141 xi[0].sizes() == xi[1].sizes());
2144 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2145 std::tuple_element_t<1, spline_type>::geoDim() == 1,
2146 "lapl(.) for vector-valued spaces requires 1D variables");
2149 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2150 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2151 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2152 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
2157 bool memory_optimized =
false>
2161 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
2162 &coeff_indices)
const {
2164 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2165 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2166 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2167 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
2170 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2171 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2172 std::tuple_element_t<2, spline_type>::geoDim() == 1,
2173 "div(.) for vector-valued spaces requires 1D variables");
2176 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2177 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2178 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2179 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2180 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2181 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
2186 bool memory_optimized =
false>
2191 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
2192 torch::Tensor> &coeff_indices)
const {
2194 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2195 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2196 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2197 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
2198 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
2199 xi[2].sizes() == xi[3].sizes());
2202 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2203 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2204 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
2205 std::tuple_element_t<3, spline_type>::geoDim() == 1,
2206 "div(.) for vector-valued spaces requires 1D variables");
2209 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2210 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2211 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2212 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2213 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2214 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
2215 *std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
2216 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2221#define GENERATE_EXPR_MACRO(r, data, name) \
2223 template <functionspace comp = functionspace::interior, \
2224 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
2225 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2226 const std::tuple<Xi...> &xi) const { \
2227 if constexpr (comp == functionspace::interior) \
2228 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2229 std::get<Is>(xi))...); \
2230 else if constexpr (comp == functionspace::boundary) \
2231 return std::tuple( \
2232 std::get<Is>(boundary_).template name<memory_optimized>( \
2233 std::get<Is>(xi))...); \
2236 template <functionspace comp = functionspace::interior, \
2237 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2238 typename... Knot_Indices> \
2239 inline auto BOOST_PP_CAT(name, _all_)( \
2240 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2241 const std::tuple<Knot_Indices...> &knot_indices) const { \
2242 if constexpr (comp == functionspace::interior) \
2243 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2244 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2245 else if constexpr (comp == functionspace::boundary) \
2246 return std::tuple( \
2247 std::get<Is>(boundary_).template name<memory_optimized>( \
2248 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2251 template <functionspace comp = functionspace::interior, \
2252 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2253 typename... Knot_Indices, typename... Coeff_Indices> \
2254 inline auto BOOST_PP_CAT(name, _all_)( \
2255 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2256 const std::tuple<Knot_Indices...> &knot_indices, \
2257 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
2258 if constexpr (comp == functionspace::interior) \
2259 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2260 std::get<Is>(xi), std::get<Is>(knot_indices), \
2261 std::get<Is>(coeff_indices))...); \
2262 else if constexpr (comp == functionspace::boundary) \
2263 return std::tuple( \
2264 std::get<Is>(boundary_).template name<memory_optimized>( \
2265 std::get<Is>(xi), std::get<Is>(knot_indices), \
2266 std::get<Is>(coeff_indices))...); \
2269 template <functionspace comp = functionspace::interior, \
2270 bool memory_optimized = false, std::size_t... Is, std::size_t N> \
2271 inline auto BOOST_PP_CAT(name, _)(std::index_sequence<Is...>, \
2272 const utils::TensorArray<N> &xi) const { \
2273 if constexpr (comp == functionspace::interior) \
2274 return name<comp, memory_optimized>( \
2275 xi, std::tuple(std::get<Is>(spline_).find_knot_indices(xi)...)); \
2276 else if constexpr (comp == functionspace::boundary) \
2277 return name<comp, memory_optimized>( \
2278 xi, std::tuple(std::get<Is>(boundary_).find_knot_indices(xi)...)); \
2281 template <functionspace comp = functionspace::interior, \
2282 bool memory_optimized = false, std::size_t... Is, std::size_t N, \
2283 typename... Knot_Indices> \
2284 inline auto BOOST_PP_CAT(name, _)( \
2285 std::index_sequence<Is...>, const utils::TensorArray<N> &xi, \
2286 const std::tuple<Knot_Indices...> &knot_indices) const { \
2287 if constexpr (comp == functionspace::interior) \
2288 return name<comp, memory_optimized>( \
2290 std::tuple(std::get<Is>(spline_).find_coeff_indices( \
2291 std::get<Is>(knot_indices))...)); \
2292 else if constexpr (comp == functionspace::boundary) \
2293 return name<comp, memory_optimized>( \
2295 std::tuple(std::get<Is>(boundary_).find_coeff_indices( \
2296 std::get<Is>(knot_indices))...)); \
2300 template <functionspace comp = functionspace::interior, \
2301 bool memory_optimized = false, typename... Args> \
2302 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2303 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2304 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2307 template <functionspace comp = functionspace::interior, \
2308 bool memory_optimized = false> \
2309 inline auto name(const torch::Tensor &xi) const { \
2310 return name<comp, memory_optimized>(utils::TensorArray1({xi})); \
2313 template <functionspace comp = functionspace::interior, \
2314 bool memory_optimized = false, std::size_t N> \
2315 inline auto name(const utils::TensorArray<N> &xi) const { \
2316 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2317 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi); \
2320 template <functionspace comp = functionspace::interior, \
2321 bool memory_optimized = false, std::size_t N, \
2322 typename... Knot_Indices> \
2323 inline auto name(const utils::TensorArray<N> &xi, \
2324 const std::tuple<Knot_Indices...> &knot_indices) const { \
2325 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2326 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, \
2334#undef GENERATE_EXPR_MACRO
2336#define GENERATE_IEXPR_MACRO(r, data, name) \
2338 template <functionspace comp = functionspace::interior, \
2339 bool memory_optimized = false, std::size_t... Is, \
2340 typename Geometry, typename... Xi> \
2341 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2342 const Geometry &G, \
2343 const std::tuple<Xi...> &xi) const { \
2344 if constexpr (comp == functionspace::interior) { \
2345 if constexpr (Geometry::nspaces() == 1) \
2346 return std::tuple( \
2347 std::get<Is>(spline_).template name<memory_optimized>( \
2348 G.space(), std::get<Is>(xi))...); \
2349 else if constexpr (Geometry::nspaces() == nspaces()) \
2350 return std::tuple( \
2351 std::get<Is>(spline_).template name<memory_optimized>( \
2352 G.template space<Is>(), std::get<Is>(xi))...); \
2353 } else if constexpr (comp == functionspace::boundary) { \
2354 if constexpr (Geometry::nboundaries() == 1) \
2355 return std::tuple( \
2356 std::get<Is>(boundary_).template name<memory_optimized>( \
2357 static_cast<typename Geometry::boundary_type::boundary_type>( \
2358 G.boundary().coeffs()), \
2359 std::get<Is>(xi))...); \
2360 else if constexpr (Geometry::nboundaries() == nboundaries()) \
2361 return std::tuple( \
2362 std::get<Is>(boundary_).template name<memory_optimized>( \
2363 G.template boundary<Is>().coeffs(), std::get<Is>(xi))...); \
2367 template <functionspace comp = functionspace::interior, \
2368 bool memory_optimized = false, std::size_t... Is, \
2369 typename Geometry, typename... Xi, typename... Knot_Indices, \
2370 typename... Knot_Indices_G> \
2371 inline auto BOOST_PP_CAT(name, _all_)( \
2372 std::index_sequence<Is...>, const Geometry &G, \
2373 const std::tuple<Xi...> &xi, \
2374 const std::tuple<Knot_Indices...> &knot_indices, \
2375 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
2376 if constexpr (comp == functionspace::interior) { \
2377 if constexpr (Geometry::nspaces() == 1) \
2378 return std::tuple( \
2379 std::get<Is>(spline_).template name<memory_optimized>( \
2380 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2381 std::get<Is>(knot_indices_G))...); \
2383 return std::tuple( \
2384 std::get<Is>(spline_).template name<memory_optimized>( \
2385 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2386 std::get<Is>(knot_indices_G))...); \
2387 } else if constexpr (comp == functionspace::boundary) { \
2388 if constexpr (Geometry::nspaces() == 1) \
2389 return std::tuple( \
2390 std::get<Is>(boundary_).template name<memory_optimized>( \
2391 static_cast<typename Geometry::boundary_type::boundary_type>( \
2392 G.boundary().coeffs()), \
2393 std::get<Is>(xi), std::get<Is>(knot_indices), \
2394 std::get<Is>(knot_indices_G))...); \
2396 return std::tuple( \
2397 std::get<Is>(boundary_).template name<memory_optimized>( \
2398 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2399 std::get<Is>(knot_indices), std::get<Is>(knot_indices_G))...); \
2403 template <functionspace comp = functionspace::interior, \
2404 bool memory_optimized = false, std::size_t... Is, \
2405 typename Geometry, typename... Xi, typename... Knot_Indices, \
2406 typename... Coeff_Indices, typename... Knot_Indices_G, \
2407 typename... Coeff_Indices_G> \
2408 inline auto BOOST_PP_CAT(name, _all_)( \
2409 std::index_sequence<Is...>, const Geometry &G, \
2410 const std::tuple<Xi...> &xi, \
2411 const std::tuple<Knot_Indices...> &knot_indices, \
2412 const std::tuple<Coeff_Indices...> &coeff_indices, \
2413 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
2414 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
2415 if constexpr (comp == functionspace::interior) { \
2416 if constexpr (Geometry::nspaces() == 1) \
2417 return std::tuple( \
2418 std::get<Is>(spline_).template name<memory_optimized>( \
2419 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2420 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2421 std::get<Is>(coeff_indices_G))...); \
2423 return std::tuple( \
2424 std::get<Is>(spline_).template name<memory_optimized>( \
2425 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2426 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2427 std::get<Is>(coeff_indices_G))...); \
2428 } else if constexpr (comp == functionspace::boundary) { \
2429 if constexpr (Geometry::nspaces() == 1) \
2430 return std::tuple( \
2431 std::get<Is>(boundary_).template name<memory_optimized>( \
2432 static_cast<typename Geometry::boundary_type::boundary_type>( \
2433 G.boundary().coeffs()), \
2434 std::get<Is>(xi), std::get<Is>(knot_indices), \
2435 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2436 std::get<Is>(coeff_indices_G))...); \
2438 return std::tuple( \
2439 std::get<Is>(boundary_).template name<memory_optimized>( \
2440 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2441 std::get<Is>(knot_indices), std::get<Is>(coeff_indices), \
2442 std::get<Is>(knot_indices_G), \
2443 std::get<Is>(coeff_indices_G))...); \
2448 template <functionspace comp = functionspace::interior, \
2449 bool memory_optimized = false, typename... Args> \
2450 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2451 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2452 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2459#undef GENERATE_IEXPR_MACRO
2463template <
typename... Splines>
2474template <
typename Spline,
typename Boundary>
2497 template <std::
size_t index=0>
2499 static_assert(index <
nspaces());
2500 return spline_type::geoDim();
2504 template <std::
size_t index=0>
2506 static_assert(index <
nspaces());
2507 return spline_type::parDim();
2512 template <std::
size_t index=0>
2513 inline static constexpr const auto&
degrees() noexcept {
2514 static_assert(index <
nspaces());
2515 return spline_type::degrees();
2520 template <std::
size_t index=0>
2522 static_assert(index <
nspaces());
2523 return spline_type::degree(i);
2546 const std::array<int64_t, Spline::parDim()> &ncoeffs,
2555 std::array<std::vector<value_type>, Spline::parDim()> kv,
2559 static_assert(Spline::is_nonuniform(),
2560 "Constructor is only available for non-uniform splines");
2578 inline static constexpr std::size_t
nspaces() noexcept {
return 1; }
2581 inline static constexpr std::size_t
nboundaries() noexcept {
return 1; }
2596 template <std::
size_t index = 0>
2598 static_assert(index <
nspaces());
2603 template <std::
size_t index = 0>
2605 static_assert(index <
nspaces());
2610 template <std::
size_t index = 0>
2618 template <std::
size_t index = 0>
2630 template <std::size_t... index>
inline constexpr auto clone() const noexcept {
2632 static_assert(((index <
nspaces()) && ... &&
true));
2634 if constexpr (
sizeof...(index) == 1)
2638 std::tuple<std::tuple_element_t<index, std::tuple<spline_type>>...>,
2640 std::tuple_element_t<index, std::tuple<boundary_type>>...>>(
2641 std::get<index>(std::make_tuple(
spline_))...,
2642 std::get<index>(std::make_tuple(
boundary_))...);
2667 return spline_.as_tensor_size();
2716 const std::string &label =
"")
const {
2717 pugi::xml_document doc;
2718 pugi::xml_node root = doc.append_child(
"xml");
2725 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
2726 std::string label =
"")
const {
2727 return spline_.to_xml(root,
id, label);
2732 const std::string &label =
"") {
2733 return from_xml(doc.child(
"xml"),
id, label);
2738 std::string label =
"") {
2745 auto json = nlohmann::json::array();
2746 json.push_back(
spline_.to_json());
2752 template <
typename SplinesOther,
typename BoundariesOther>
2757 if (!std::is_same_v<
spline_type,
typename std::remove_cvref_t<
2759 !std::is_same_v<
boundary_type,
typename std::remove_cvref_t<
2771 const std::function<std::array<
typename Spline::value_type,
2773 const std::array<
typename Spline::value_type, Spline::parDim()> &)>
2784 std::size_t... Is,
typename... Xi>
2785 inline auto eval_(std::index_sequence<Is...>,
2786 const std::tuple<Xi...> &xi)
const {
2789 spline_.template eval<deriv, memory_optimized>(std::get<Is>(xi))...);
2791 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2792 std::get<Is>(xi))...);
2797 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
2798 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
2799 const std::tuple<Knot_Indices...> &knot_indices)
const {
2801 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
2802 std::get<Is>(xi), std::get<Is>(knot_indices))...);
2804 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2805 std::get<Is>(xi), std::get<Is>(knot_indices))...);
2810 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
2811 typename... Coeff_Indices>
2812 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
2813 const std::tuple<Knot_Indices...> &knot_indices,
2814 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
2816 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
2817 std::get<Is>(xi), std::get<Is>(knot_indices),
2818 std::get<Is>(coeff_indices))...);
2820 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2821 std::get<Is>(xi), std::get<Is>(knot_indices),
2822 std::get<Is>(coeff_indices))...);
2830 typename Arg,
typename... Args>
2831 inline auto eval(
const Arg &arg,
const Args &...args)
const {
2833 if constexpr (utils::is_tuple_v<Arg>)
2834 return eval_<comp, deriv, memory_optimized>(
2835 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
2837 return spline_.template eval<deriv, memory_optimized>(arg, args...);
2839 if constexpr (utils::is_tuple_of_tuples_v<Arg>)
2840 return eval_<comp, deriv, memory_optimized>(
2841 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
2843 return boundary_.template eval<deriv, memory_optimized>(arg, args...);
2852 return spline_.eval_from_precomputed(args...);
2862 const Xi &xi)
const {
2864 return std::tuple(
spline_.find_knot_indices(std::get<Is>(xi))...);
2871 template <functionspace comp = functionspace::
interior,
typename Xi>
2874 if constexpr (utils::is_tuple_v<Xi>)
2875 return find_knot_indices_<comp>(
2876 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
2878 return spline_.find_knot_indices(xi);
2880 if constexpr (utils::is_tuple_of_tuples_v<Xi>)
2881 return find_knot_indices_<comp>(
2882 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
2895 return spline_.template eval_basfunc<deriv, memory_optimized>(args...);
2897 return boundary_.template eval_basfunc<deriv, memory_optimized>(args...);
2904 bool memory_optimized =
false, std::size_t... Is,
2905 typename Knot_Indices>
2907 const Knot_Indices &knot_indices)
const {
2909 return std::tuple(
spline_.template find_coeff_indices<memory_optimized>(
2910 std::get<Is>(knot_indices))...);
2912 return std::tuple(
boundary_.template find_coeff_indices<memory_optimized>(
2913 std::get<Is>(knot_indices))...);
2920 bool memory_optimized =
false,
typename Knot_Indices>
2923 if constexpr (utils::is_tuple_v<Knot_Indices>)
2924 return find_coeff_indices_<comp, memory_optimized>(
2925 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
2928 return spline_.template find_coeff_indices<memory_optimized>(
2931 if constexpr (utils::is_tuple_of_tuples_v<Knot_Indices>)
2932 return find_coeff_indices_<comp, memory_optimized>(
2933 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
2936 return boundary_.template find_coeff_indices<memory_optimized>(
2944 spline_.uniform_refine(numRefine, dimRefine);
2953 typename spline_type::template real_derived_self_type<real_t>,
2954 typename boundary_type::template real_derived_self_type<real_t>>(
2960 inline auto to(torch::Device device)
const {
2965 template <
typename real_t>
inline auto to()
const {
2967 typename spline_type::template real_derived_self_type<real_t>,
2968 typename boundary_type::template real_derived_self_type<real_t>>(
2980 template <std::
size_t N>
inline auto scale(std::array<value_type, N> v) {
2987 template <std::
size_t N>
inline auto translate(std::array<value_type, N> v) {
3001 inline auto rotate(std::array<value_type, 3> angle) {
3009 inline torch::serialize::OutputArchive &
3010 write(torch::serialize::OutputArchive &archive,
3011 const std::string &key =
"functionspace")
const {
3019 inline torch::serialize::InputArchive &
3020 read(torch::serialize::InputArchive &archive,
3021 const std::string &key =
"functionspace") {
3029 os <<
name() <<
"(\nspline = ";
3031 os <<
"\nboundary = ";
3036#define GENERATE_EXPR_MACRO(r, data, name) \
3038 template <functionspace comp = functionspace::interior, \
3039 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
3040 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
3041 const std::tuple<Xi...> &xi) const { \
3042 if constexpr (comp == functionspace::interior) \
3043 return std::tuple( \
3044 spline_.template name<memory_optimized>(std::get<Is>(xi))...); \
3045 else if constexpr (comp == functionspace::boundary) \
3046 return std::tuple( \
3047 boundary_.template name<memory_optimized>(std::get<Is>(xi))...); \
3050 template <functionspace comp = functionspace::interior, \
3051 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
3052 typename... Knot_Indices> \
3053 inline auto BOOST_PP_CAT(name, _all_)( \
3054 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
3055 const std::tuple<Knot_Indices...> &knot_indices) const { \
3056 if constexpr (comp == functionspace::interior) \
3057 return std::tuple(spline_.template name<memory_optimized>( \
3058 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
3059 else if constexpr (comp == functionspace::boundary) \
3060 return std::tuple(boundary_.template name<memory_optimized>( \
3061 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
3064 template <functionspace comp = functionspace::interior, \
3065 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
3066 typename... Knot_Indices, typename... Coeff_Indices> \
3067 inline auto BOOST_PP_CAT(name, _all_)( \
3068 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
3069 const std::tuple<Knot_Indices...> &knot_indices, \
3070 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
3071 if constexpr (comp == functionspace::interior) \
3072 return std::tuple(spline_.template name<memory_optimized>( \
3073 std::get<Is>(xi), std::get<Is>(knot_indices), \
3074 std::get<Is>(coeff_indices))...); \
3075 else if constexpr (comp == functionspace::boundary) \
3076 return std::tuple(boundary_.template name<memory_optimized>( \
3077 std::get<Is>(xi), std::get<Is>(knot_indices), \
3078 std::get<Is>(coeff_indices))...); \
3082 template <functionspace comp = functionspace::interior, \
3083 bool memory_optimized = false, typename Arg, typename... Args> \
3084 inline auto name(const Arg &arg, const Args &...args) const { \
3085 if constexpr (comp == functionspace::interior) \
3086 if constexpr (utils::is_tuple_v<Arg>) \
3087 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3088 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
3090 return spline_.template name<memory_optimized>(arg, args...); \
3091 else if constexpr (comp == functionspace::boundary) { \
3092 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
3093 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3094 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
3096 return boundary_.template name<memory_optimized>(arg, args...); \
3104#undef GENERATE_EXPR_MACRO
3106#define GENERATE_IEXPR_MACRO(r, data, name) \
3108 template <functionspace comp = functionspace::interior, \
3109 bool memory_optimized = false, std::size_t... Is, \
3110 typename Geometry, typename... Xi> \
3111 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
3112 const Geometry &G, \
3113 const std::tuple<Xi...> &xi) const { \
3114 if constexpr (comp == functionspace::interior) \
3115 return std::tuple(spline_.template name<memory_optimized>( \
3116 G.space(), std::get<Is>(xi))...); \
3117 else if constexpr (comp == functionspace::boundary) \
3118 return std::tuple(boundary_.template name<memory_optimized>( \
3119 static_cast<typename Geometry::boundary_type::boundary_type>( \
3120 G.boundary().coeffs()), \
3121 std::get<Is>(xi))...); \
3124 template <functionspace comp = functionspace::interior, \
3125 bool memory_optimized = false, std::size_t... Is, \
3126 typename Geometry, typename... Xi, typename... Knot_Indices, \
3127 typename... Knot_Indices_G> \
3128 inline auto BOOST_PP_CAT(name, _all_)( \
3129 std::index_sequence<Is...>, const Geometry &G, \
3130 const std::tuple<Xi...> &xi, \
3131 const std::tuple<Knot_Indices...> &knot_indices, \
3132 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
3133 if constexpr (comp == functionspace::interior) \
3134 return std::tuple(spline_.template name<memory_optimized>( \
3135 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
3136 std::get<Is>(knot_indices_G))...); \
3137 else if constexpr (comp == functionspace::boundary) \
3138 return std::tuple(boundary_.template name<memory_optimized>( \
3139 static_cast<typename Geometry::boundary_type::boundary_type>( \
3140 G.boundary().coeffs()), \
3141 std::get<Is>(xi), std::get<Is>(knot_indices), \
3142 std::get<Is>(knot_indices_G))...); \
3145 template <functionspace comp = functionspace::interior, \
3146 bool memory_optimized = false, std::size_t... Is, \
3147 typename Geometry, typename... Xi, typename... Knot_Indices, \
3148 typename... Coeff_Indices, typename... Knot_Indices_G, \
3149 typename... Coeff_Indices_G> \
3150 inline auto BOOST_PP_CAT(name, _all_)( \
3151 std::index_sequence<Is...>, const Geometry &G, \
3152 const std::tuple<Xi...> &xi, \
3153 const std::tuple<Knot_Indices...> &knot_indices, \
3154 const std::tuple<Coeff_Indices...> &coeff_indices, \
3155 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
3156 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
3157 if constexpr (comp == functionspace::interior) \
3158 return std::tuple(spline_.template name<memory_optimized>( \
3159 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
3160 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3161 std::get<Is>(coeff_indices_G))...); \
3162 else if constexpr (comp == functionspace::boundary) \
3163 return std::tuple(boundary_.template name<memory_optimized>( \
3164 static_cast<typename Geometry::boundary_type::boundary_type>( \
3165 G.boundary().coeffs()), \
3166 std::get<Is>(xi), std::get<Is>(knot_indices), \
3167 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3168 std::get<Is>(coeff_indices_G))...); \
3172 template <functionspace comp = functionspace::interior, \
3173 bool memory_optimized = false, typename Geometry, typename Arg, \
3175 inline auto name(const Geometry &G, const Arg &arg, const Args &...args) \
3177 if constexpr (comp == functionspace::interior) { \
3178 if constexpr (utils::is_tuple_v<Arg>) \
3179 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3180 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3183 return spline_.template name<memory_optimized>(G.space(), arg, \
3185 } else if constexpr (comp == functionspace::boundary) { \
3186 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
3187 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3188 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3191 return boundary_.template name<memory_optimized>( \
3192 static_cast<typename Geometry::boundary_type::boundary_type>( \
3193 G.boundary().coeffs()), \
3202#undef GENERATE_IEXPR_MACRO
3214template <
typename Spline,
typename Boundary>
3220template <
typename... Splines>
3227template <
typename... Splines,
typename... Boundaries>
3236template <
typename Spline,
typename Boundary>
3244template <
typename... Splines,
typename... Boundaries>
3254template <
typename T>
3258template <
typename... Args>
3262template <
typename Splines,
typename Boundaries>
3265 obj.pretty_print(os);
3289template <
typename Spline,
short_t = Spline::parDim()>
class TH;
3300template <
typename Spline>
3303 std::tuple<typename Spline::template derived_self_type<
3304 typename Spline::value_type, Spline::geoDim(),
3305 Spline::degree(0) + 1>,
3306 typename Spline::template derived_self_type<
3307 typename Spline::value_type, Spline::geoDim(),
3308 Spline::degree(0)>>> {
3312 typename Spline::template derived_self_type<
3313 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3314 typename Spline::template derived_self_type<
3315 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3319 explicit TH(
const std::array<int64_t, 1> &ncoeffs,
3323 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {
3324 static_assert(Spline::is_nonuniform(),
3325 "TH function space requires non-uniform splines");
3326 Base::template space<0>().reduce_continuity();
3329 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3333 : Base({{kv[0].front + kv[0] + kv[0].back(), kv[1]}}, kv,
init, options) {
3334 static_assert(Spline::is_nonuniform(),
3335 "TH function space requires non-uniform splines");
3336 Base::template space<0>().reduce_continuity();
3354template <
typename Spline>
3357 std::tuple<typename Spline::template derived_self_type<
3358 typename Spline::value_type, Spline::geoDim(),
3359 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3360 typename Spline::template derived_self_type<
3361 typename Spline::value_type, Spline::geoDim(),
3362 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3363 typename Spline::template derived_self_type<
3364 typename Spline::value_type, Spline::geoDim(),
3365 Spline::degree(0), Spline::degree(1)>>> {
3369 std::tuple<
typename Spline::template derived_self_type<
3370 typename Spline::value_type, Spline::geoDim(),
3371 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3372 typename Spline::template derived_self_type<
3373 typename Spline::value_type, Spline::geoDim(),
3374 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3375 typename Spline::template derived_self_type<
3376 typename Spline::value_type, Spline::geoDim(),
3377 Spline::degree(0), Spline::degree(1)>>>;
3381 explicit TH(
const std::array<int64_t, 2> &ncoeffs,
3385 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
3386 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
3387 static_assert(Spline::is_nonuniform(),
3388 "TH function space requires non-uniform splines");
3389 Base::template space<0>().reduce_continuity();
3390 Base::template space<1>().reduce_continuity();
3393 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3397 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3398 kv[1].front() + kv[1] + kv[1].back()}},
3399 {{kv[0].front() + kv[0] + kv[0].back(),
3400 kv[1].front() + kv[1] + kv[1].back()}},
3401 kv,
init, options) {
3402 static_assert(Spline::is_nonuniform(),
3403 "TH function space requires non-uniform splines");
3404 Base::template space<0>().reduce_continuity();
3405 Base::template space<1>().reduce_continuity();
3424template <
typename Spline>
3427 typename Spline::template derived_self_type<
3428 typename Spline::value_type, Spline::geoDim(),
3429 Spline::degree(0) + 1, Spline::degree(1) + 1,
3430 Spline::degree(2) + 1>,
3431 typename Spline::template derived_self_type<
3432 typename Spline::value_type, Spline::geoDim(),
3433 Spline::degree(0) + 1, Spline::degree(1) + 1,
3434 Spline::degree(2) + 1>,
3435 typename Spline::template derived_self_type<
3436 typename Spline::value_type, Spline::geoDim(),
3437 Spline::degree(0) + 1, Spline::degree(1) + 1,
3438 Spline::degree(2) + 1>,
3439 typename Spline::template derived_self_type<
3440 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3441 Spline::degree(1), Spline::degree(2)>>> {
3445 typename Spline::template derived_self_type<
3446 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3447 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3448 typename Spline::template derived_self_type<
3449 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3450 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3451 typename Spline::template derived_self_type<
3452 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3453 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3454 typename Spline::template derived_self_type<
3455 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3456 Spline::degree(1), Spline::degree(2)>>>;
3460 explicit TH(
const std::array<int64_t, 3> &ncoeffs,
3464 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3465 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3466 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
3468 static_assert(Spline::is_nonuniform(),
3469 "TH function space requires non-uniform splines");
3470 Base::template space<0>().reduce_continuity();
3471 Base::template space<1>().reduce_continuity();
3472 Base::template space<2>().reduce_continuity();
3475 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3479 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3480 kv[1].front() + kv[1] + kv[1].back(),
3481 kv[2].front() + kv[2] + kv[2].back()}},
3482 {{kv[0].front() + kv[0] + kv[0].back(),
3483 kv[1].front() + kv[1] + kv[1].back(),
3484 kv[2].front() + kv[2] + kv[2].back()}},
3485 {{kv[0].front() + kv[0] + kv[0].back(),
3486 kv[1].front() + kv[1] + kv[1].back(),
3487 kv[2].front() + kv[2] + kv[2].back()}},
3488 kv,
init, options) {
3489 static_assert(Spline::is_nonuniform(),
3490 "TH function space requires non-uniform splines");
3491 Base::template space<0>().reduce_continuity();
3492 Base::template space<1>().reduce_continuity();
3493 Base::template space<2>().reduce_continuity();
3513template <
typename Spline>
3516 typename Spline::template derived_self_type<
3517 typename Spline::value_type, Spline::geoDim(),
3518 Spline::degree(0) + 1, Spline::degree(1) + 1,
3519 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3520 typename Spline::template derived_self_type<
3521 typename Spline::value_type, Spline::geoDim(),
3522 Spline::degree(0) + 1, Spline::degree(1) + 1,
3523 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3524 typename Spline::template derived_self_type<
3525 typename Spline::value_type, Spline::geoDim(),
3526 Spline::degree(0) + 1, Spline::degree(1) + 1,
3527 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3528 typename Spline::template derived_self_type<
3529 typename Spline::value_type, Spline::geoDim(),
3530 Spline::degree(0) + 1, Spline::degree(1) + 1,
3531 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3532 typename Spline::template derived_self_type<
3533 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3534 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3538 typename Spline::template derived_self_type<
3539 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3540 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3541 typename Spline::template derived_self_type<
3542 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3543 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3544 typename Spline::template derived_self_type<
3545 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3546 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3547 typename Spline::template derived_self_type<
3548 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3549 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3550 typename Spline::template derived_self_type<
3551 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3552 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
3556 explicit TH(
const std::array<int64_t, 4> &ncoeffs,
3560 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3561 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3562 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3563 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64), ncoeffs,
3565 static_assert(Spline::is_nonuniform(),
3566 "TH function space requires non-uniform splines");
3567 Base::template space<0>().reduce_continuity();
3568 Base::template space<1>().reduce_continuity();
3569 Base::template space<2>().reduce_continuity();
3570 Base::template space<3>().reduce_continuity();
3573 explicit TH(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
3577 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3578 kv[1].front() + kv[1] + kv[1].back(),
3579 kv[2].front() + kv[2] + kv[2].back(),
3580 kv[3].front() + kv[3] + kv[3].back()}},
3581 {{kv[0].front() + kv[0] + kv[0].back(),
3582 kv[1].front() + kv[1] + kv[1].back(),
3583 kv[2].front() + kv[2] + kv[2].back(),
3584 kv[3].front() + kv[3] + kv[3].back()}},
3585 {{kv[0].front() + kv[0] + kv[0].back(),
3586 kv[1].front() + kv[1] + kv[1].back(),
3587 kv[2].front() + kv[2] + kv[2].back(),
3588 kv[3].front() + kv[3] + kv[3].back()}},
3589 {{kv[0].front() + kv[0] + kv[0].back(),
3590 kv[1].front() + kv[1] + kv[1].back(),
3591 kv[2].front() + kv[2] + kv[2].back(),
3592 kv[3].front() + kv[3] + kv[3].back()}},
3593 kv,
init, options) {
3594 static_assert(Spline::is_nonuniform(),
3595 "TH function space requires non-uniform splines");
3596 Base::template space<0>().reduce_continuity();
3597 Base::template space<1>().reduce_continuity();
3598 Base::template space<2>().reduce_continuity();
3599 Base::template space<3>().reduce_continuity();
3607template <
typename Spline,
short_t = Spline::parDim()>
class NE;
3618template <
typename Spline>
3621 std::tuple<typename Spline::template derived_self_type<
3622 typename Spline::value_type, Spline::geoDim(),
3623 Spline::degree(0) + 1>,
3624 typename Spline::template derived_self_type<
3625 typename Spline::value_type, Spline::geoDim(),
3626 Spline::degree(0)>>> {
3630 typename Spline::template derived_self_type<
3631 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3632 typename Spline::template derived_self_type<
3633 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3637 explicit NE(
const std::array<int64_t, 1> &ncoeffs,
3641 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
3643 explicit NE(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3647 : Base(kv, kv,
init, options) {
3648 static_assert(Spline::is_nonuniform(),
3649 "Constructor only available for non-uniform splines");
3666template <
typename Spline>
3669 std::tuple<typename Spline::template derived_self_type<
3670 typename Spline::value_type, Spline::geoDim(),
3671 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3672 typename Spline::template derived_self_type<
3673 typename Spline::value_type, Spline::geoDim(),
3674 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3675 typename Spline::template derived_self_type<
3676 typename Spline::value_type, Spline::geoDim(),
3677 Spline::degree(0), Spline::degree(1)>>> {
3681 std::tuple<
typename Spline::template derived_self_type<
3682 typename Spline::value_type, Spline::geoDim(),
3683 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3684 typename Spline::template derived_self_type<
3685 typename Spline::value_type, Spline::geoDim(),
3686 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3687 typename Spline::template derived_self_type<
3688 typename Spline::value_type, Spline::geoDim(),
3689 Spline::degree(0), Spline::degree(1)>>>;
3693 explicit NE(
const std::array<int64_t, 2> &ncoeffs,
3697 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
3698 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
3699 static_assert(Spline::is_nonuniform(),
3700 "NE function space requires non-uniform splines");
3701 Base::template space<0>().reduce_continuity(1, 1);
3702 Base::template space<1>().reduce_continuity(1, 0);
3705 explicit NE(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3709 : Base(kv, kv, kv,
init, options) {
3710 static_assert(Spline::is_nonuniform(),
3711 "NE function space requires non-uniform splines");
3712 Base::template space<0>().reduce_continuity(1, 1);
3713 Base::template space<1>().reduce_continuity(1, 0);
3732template <
typename Spline>
3735 typename Spline::template derived_self_type<
3736 typename Spline::value_type, Spline::geoDim(),
3737 Spline::degree(0) + 1, Spline::degree(1) + 1,
3738 Spline::degree(2) + 1>,
3739 typename Spline::template derived_self_type<
3740 typename Spline::value_type, Spline::geoDim(),
3741 Spline::degree(0) + 1, Spline::degree(1) + 1,
3742 Spline::degree(2) + 1>,
3743 typename Spline::template derived_self_type<
3744 typename Spline::value_type, Spline::geoDim(),
3745 Spline::degree(0) + 1, Spline::degree(1) + 1,
3746 Spline::degree(2) + 1>,
3747 typename Spline::template derived_self_type<
3748 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3749 Spline::degree(1), Spline::degree(2)>>> {
3753 typename Spline::template derived_self_type<
3754 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3755 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3756 typename Spline::template derived_self_type<
3757 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3758 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3759 typename Spline::template derived_self_type<
3760 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3761 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3762 typename Spline::template derived_self_type<
3763 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3764 Spline::degree(1), Spline::degree(2)>>>;
3768 explicit NE(
const std::array<int64_t, 3> &ncoeffs,
3772 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3773 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3774 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
3776 static_assert(Spline::is_nonuniform(),
3777 "NE function space requires non-uniform splines");
3778 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
3779 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
3780 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
3783 explicit NE(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3787 : Base(kv, kv, kv, kv,
init, options) {
3788 static_assert(Spline::is_nonuniform(),
3789 "NE function space requires non-uniform splines");
3790 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
3791 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
3792 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
3812template <
typename Spline>
3815 typename Spline::template derived_self_type<
3816 typename Spline::value_type, Spline::geoDim(),
3817 Spline::degree(0) + 1, Spline::degree(1) + 1,
3818 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3819 typename Spline::template derived_self_type<
3820 typename Spline::value_type, Spline::geoDim(),
3821 Spline::degree(0) + 1, Spline::degree(1) + 1,
3822 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3823 typename Spline::template derived_self_type<
3824 typename Spline::value_type, Spline::geoDim(),
3825 Spline::degree(0) + 1, Spline::degree(1) + 1,
3826 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3827 typename Spline::template derived_self_type<
3828 typename Spline::value_type, Spline::geoDim(),
3829 Spline::degree(0) + 1, Spline::degree(1) + 1,
3830 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3831 typename Spline::template derived_self_type<
3832 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3833 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3837 typename Spline::template derived_self_type<
3838 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3839 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3840 typename Spline::template derived_self_type<
3841 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3842 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3843 typename Spline::template derived_self_type<
3844 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3845 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3846 typename Spline::template derived_self_type<
3847 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3848 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3849 typename Spline::template derived_self_type<
3850 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3851 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
3855 explicit NE(
const std::array<int64_t, 4> &ncoeffs,
3859 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3860 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3861 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3862 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64), ncoeffs,
3864 static_assert(Spline::is_nonuniform(),
3865 "NE function space requires non-uniform splines");
3866 Base::template space<0>()
3867 .reduce_continuity(1, 1)
3868 .reduce_continuity(1, 2)
3869 .reduce_continuity(1, 3);
3870 Base::template space<1>()
3871 .reduce_continuity(1, 0)
3872 .reduce_continuity(1, 2)
3873 .reduce_continuity(1, 3);
3874 Base::template space<2>()
3875 .reduce_continuity(1, 0)
3876 .reduce_continuity(1, 1)
3877 .reduce_continuity(1, 3);
3878 Base::template space<3>()
3879 .reduce_continuity(1, 0)
3880 .reduce_continuity(1, 1)
3881 .reduce_continuity(1, 2);
3884 explicit NE(
const std::array<std::vector<typename Spline::value_type>,
3885 Spline::parDim()> &kv,
3889 : Base(kv, kv, kv, kv, kv,
init, options) {
3890 static_assert(Spline::is_nonuniform(),
3891 "NE function space requires non-uniform splines");
3892 Base::template space<0>()
3893 .reduce_continuity(1, 1)
3894 .reduce_continuity(1, 2)
3895 .reduce_continuity(1, 3);
3896 Base::template space<1>()
3897 .reduce_continuity(1, 0)
3898 .reduce_continuity(1, 2)
3899 .reduce_continuity(1, 3);
3900 Base::template space<2>()
3901 .reduce_continuity(1, 0)
3902 .reduce_continuity(1, 1)
3903 .reduce_continuity(1, 3);
3904 Base::template space<3>()
3905 .reduce_continuity(1, 0)
3906 .reduce_continuity(1, 1)
3907 .reduce_continuity(1, 2);
3915template <
typename Spline,
short_t = Spline::parDim()>
class RT;
3926template <
typename Spline>
3929 std::tuple<typename Spline::template derived_self_type<
3930 typename Spline::value_type, Spline::geoDim(),
3931 Spline::degree(0) + 1>,
3932 typename Spline::template derived_self_type<
3933 typename Spline::value_type, Spline::geoDim(),
3934 Spline::degree(0)>>> {
3938 typename Spline::template derived_self_type<
3939 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3940 typename Spline::template derived_self_type<
3941 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3945 explicit RT(
const std::array<int64_t, 1> &ncoeffs,
3949 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
3951 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3955 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}}, kv,
init,
3957 static_assert(Spline::is_nonuniform(),
3958 "Constructor only available for non-uniform splines");
3976template <
typename Spline>
3979 std::tuple<typename Spline::template derived_self_type<
3980 typename Spline::value_type, Spline::geoDim(),
3981 Spline::degree(0) + 1, Spline::degree(1)>,
3982 typename Spline::template derived_self_type<
3983 typename Spline::value_type, Spline::geoDim(),
3984 Spline::degree(0), Spline::degree(1) + 1>,
3985 typename Spline::template derived_self_type<
3986 typename Spline::value_type, Spline::geoDim(),
3987 Spline::degree(0), Spline::degree(1)>>> {
3990 std::tuple<
typename Spline::template derived_self_type<
3991 typename Spline::value_type, Spline::geoDim(),
3992 Spline::degree(0) + 1, Spline::degree(1)>,
3993 typename Spline::template derived_self_type<
3994 typename Spline::value_type, Spline::geoDim(),
3995 Spline::degree(0), Spline::degree(1) + 1>,
3996 typename Spline::template derived_self_type<
3997 typename Spline::value_type, Spline::geoDim(),
3998 Spline::degree(0), Spline::degree(1)>>>;
4002 explicit RT(
const std::array<int64_t, 2> &ncoeffs,
4006 : Base(ncoeffs + utils::to_array(1_i64, 0_i64),
4007 ncoeffs + utils::to_array(0_i64, 1_i64), ncoeffs,
init, options) {}
4009 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
4013 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}},
4014 {{kv[0], kv[1].front() + kv[1] + kv[1].back()}}, kv,
init,
4016 static_assert(Spline::is_nonuniform(),
4017 "Constructor only available for non-uniform splines");
4035template <
typename Spline>
4038 typename Spline::template derived_self_type<
4039 typename Spline::value_type, Spline::geoDim(),
4040 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2)>,
4041 typename Spline::template derived_self_type<
4042 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4043 Spline::degree(1) + 1, Spline::degree(2)>,
4044 typename Spline::template derived_self_type<
4045 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4046 Spline::degree(1), Spline::degree(2) + 1>,
4047 typename Spline::template derived_self_type<
4048 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4049 Spline::degree(1), Spline::degree(2)>>> {
4053 typename Spline::template derived_self_type<
4054 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4055 Spline::degree(1), Spline::degree(2)>,
4056 typename Spline::template derived_self_type<
4057 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4058 Spline::degree(1) + 1, Spline::degree(2)>,
4059 typename Spline::template derived_self_type<
4060 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4061 Spline::degree(1), Spline::degree(2) + 1>,
4062 typename Spline::template derived_self_type<
4063 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4064 Spline::degree(1), Spline::degree(2)>>>;
4068 explicit RT(
const std::array<int64_t, 3> &ncoeffs,
4072 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4073 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4074 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64), ncoeffs,
init,
4077 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4081 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4082 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4083 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}}, kv,
init,
4085 static_assert(Spline::is_nonuniform(),
4086 "Constructor only available for non-uniform splines");
4106template <
typename Spline>
4109 typename Spline::template derived_self_type<
4110 typename Spline::value_type, Spline::geoDim(),
4111 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2),
4113 typename Spline::template derived_self_type<
4114 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4115 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
4116 typename Spline::template derived_self_type<
4117 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4118 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
4119 typename Spline::template derived_self_type<
4120 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4121 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
4122 typename Spline::template derived_self_type<
4123 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4124 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
4128 typename Spline::template derived_self_type<
4129 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4130 Spline::degree(1), Spline::degree(2), Spline::degree(3)>,
4131 typename Spline::template derived_self_type<
4132 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4133 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
4134 typename Spline::template derived_self_type<
4135 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4136 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
4137 typename Spline::template derived_self_type<
4138 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4139 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
4140 typename Spline::template derived_self_type<
4141 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4142 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
4146 explicit RT(
const std::array<int64_t, 4> &ncoeffs,
4150 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64, 0_i64),
4151 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64, 0_i64),
4152 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64, 0_i64),
4153 ncoeffs + utils::to_array(0_i64, 0_i64, 0_i64, 1_i64), ncoeffs,
4156 explicit RT(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
4160 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2], kv[3]}},
4161 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2], kv[3]}},
4162 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back(), kv[3]}},
4163 {{kv[0], kv[1], kv[2], kv[3].front() + kv[3] + kv[3].back()}}, kv,
4165 static_assert(Spline::is_nonuniform(),
4166 "Constructor only available for non-uniform splines");
4174template <
typename Spline,
short_t = Spline::parDim()>
class Hcurl;
4187template <
typename Spline>
4190 typename Spline::template derived_self_type<
4191 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4192 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4193 typename Spline::template derived_self_type<
4194 typename Spline::value_type, Spline::geoDim(),
4195 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2) + 1>,
4196 typename Spline::template derived_self_type<
4197 typename Spline::value_type, Spline::geoDim(),
4198 Spline::degree(0) + 1, Spline::degree(1) + 1,
4199 Spline::degree(2)>>> {
4204 typename Spline::template derived_self_type<
4205 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
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) + 1,
4209 Spline::degree(1), Spline::degree(2) + 1>,
4210 typename Spline::template derived_self_type<
4211 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4212 Spline::degree(1) + 1, Spline::degree(2)>>>;
4216 explicit Hcurl(
const std::array<int64_t, 3> &ncoeffs,
4220 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4221 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4222 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64),
init, options) {}
4225 const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4229 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4230 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4231 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}},
init,
4233 static_assert(Spline::is_nonuniform(),
4234 "Constructor only available for non-uniform splines");
4241template <
typename Spline,
short_t = Spline::parDim()>
class NE_RT_DG;
4258template <
typename Spline>
4262 typename Spline::template derived_self_type<
4263 typename Spline::value_type, Spline::geoDim(),
4264 Spline::degree(0) + 1, Spline::degree(1) + 1>,
4266 typename Spline::template derived_self_type<
4267 typename Spline::value_type, Spline::geoDim(),
4268 Spline::degree(0) + 1, Spline::degree(1)>,
4269 typename Spline::template derived_self_type<
4270 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4271 Spline::degree(1) + 1>,
4273 typename Spline::template derived_self_type<
4274 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4275 Spline::degree(1)>>> {
4281 typename Spline::template derived_self_type<
4282 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4283 Spline::degree(1) + 1>,
4285 typename Spline::template derived_self_type<
4286 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4288 typename Spline::template derived_self_type<
4289 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4290 Spline::degree(1) + 1>,
4292 typename Spline::template derived_self_type<
4293 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4294 Spline::degree(1)>>>;
4298 explicit NE_RT_DG(
const std::array<int64_t, 2> &ncoeffs,
4302 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
4303 ncoeffs + utils::to_array(1_i64, 0_i64),
4304 ncoeffs + utils::to_array(0_i64, 1_i64), ncoeffs,
init, options) {}
4307 const std::array<std::vector<typename Spline::value_type>, 2> &kv,
4311 : Base({{kv[0].front() + kv[0] + kv[0].back(),
4312 kv[1].front() + kv[1] + kv[1].back()}},
4313 {{kv[0].front() + kv[0] + kv[0].back(), kv[1]}},
4314 {{kv[0], kv[1].front() + kv[1] + kv[1].back()}}, {{kv[0], kv[1]}},
4316 static_assert(Spline::is_nonuniform(),
4317 "Constructor only available for non-uniform splines");
4339template <
typename Spline>
4343 typename Spline::template derived_self_type<
4344 typename Spline::value_type, Spline::geoDim(),
4345 Spline::degree(0) + 1, Spline::degree(1) + 1,
4346 Spline::degree(2) + 1>,
4348 typename Spline::template derived_self_type<
4349 typename Spline::value_type, Spline::geoDim(),
4350 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2)>,
4351 typename Spline::template derived_self_type<
4352 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4353 Spline::degree(1) + 1, Spline::degree(2)>,
4354 typename Spline::template derived_self_type<
4355 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4356 Spline::degree(1), Spline::degree(2) + 1>,
4358 typename Spline::template derived_self_type<
4359 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4360 Spline::degree(1), Spline::degree(2)>>> {
4366 typename Spline::template derived_self_type<
4367 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4368 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4370 typename Spline::template derived_self_type<
4371 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4372 Spline::degree(1), Spline::degree(2)>,
4373 typename Spline::template derived_self_type<
4374 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4375 Spline::degree(1) + 1, Spline::degree(2)>,
4376 typename Spline::template derived_self_type<
4377 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4378 Spline::degree(1), Spline::degree(2) + 1>,
4380 typename Spline::template derived_self_type<
4381 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4382 Spline::degree(1), Spline::degree(2)>>>;
4386 explicit NE_RT_DG(
const std::array<int64_t, 3> &ncoeffs,
4390 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
4391 ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4392 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4393 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64), ncoeffs,
init,
4397 const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4401 : Base({{kv[0].front() + kv[0] + kv[0].back(),
4402 kv[1].front() + kv[1] + kv[1].back(),
4403 kv[2].front() + kv[2] + kv[2].back()}},
4404 {{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4405 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4406 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}},
4407 {{kv[0], kv[1], kv[2]}},
init, options) {
4408 static_assert(Spline::is_nonuniform(),
4409 "Constructor only available for non-uniform splines");
4415#undef IGANET_FUNCTIONSPACE_DEFAULT_OPS
#define GENERATE_IEXPR_MACRO(r, data, name)
Auto-generated functions.
Definition boundary.hpp:1797
#define GENERATE_EXPR_MACRO(r, data, name)
Definition boundary.hpp:1751
#define GENERATE_EXPR_SEQ
Sequence of expression (parametric coordinates)
Definition bspline.hpp:40
#define GENERATE_IEXPR_SEQ
Sequence of expression (physical coordinates)
Definition bspline.hpp:46
Boundary (common high-level functionality)
Definition boundary.hpp:1143
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Returns the knot indicies of knot spans containing xi
Definition boundary.hpp:1369
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:1331
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:1620
auto to(Options< real_t > options) const
Returns a copy of the boundary object with settings from options.
Definition boundary.hpp:1940
auto & from_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor.
Definition boundary.hpp:1221
torch::Tensor as_tensor() const
Returns all coefficients of all spline objects as a single tensor.
Definition boundary.hpp:1166
auto & uniform_refine(int numRefine=1, int dim=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition boundary.hpp:1451
int64_t as_tensor_size() const
Returns the size of the single tensor representation of all spline objects.
Definition boundary.hpp:1187
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:1589
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:4212
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:4216
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 >{})
Constructor.
Definition functionspace.hpp:4224
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:3633
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:3637
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 >{})
Constructor.
Definition functionspace.hpp:3643
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:3693
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:3689
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 >{})
Constructor.
Definition functionspace.hpp:3705
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:3768
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 >{})
Constructor.
Definition functionspace.hpp:3783
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:3764
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:3855
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 >{})
Constructor.
Definition functionspace.hpp:3884
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:3851
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:4298
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:4294
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 >{})
Constructor.
Definition functionspace.hpp:4306
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 >{})
Constructor.
Definition functionspace.hpp:4396
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:4386
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:4382
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:104
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:3941
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:3945
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 >{})
Constructor.
Definition functionspace.hpp:3951
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:3998
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:4002
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 >{})
Constructor.
Definition functionspace.hpp:4009
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:4064
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:4068
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 >{})
Constructor.
Definition functionspace.hpp:4077
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:4142
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:4146
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 >{})
Constructor.
Definition functionspace.hpp:4156
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:3319
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 >{})
Constructor.
Definition functionspace.hpp:3329
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:3315
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 >{})
Constructor.
Definition functionspace.hpp:3393
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:3377
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:3381
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:3460
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:3456
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 >{})
Constructor.
Definition functionspace.hpp:3475
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 >{})
Constructor.
Definition functionspace.hpp:3573
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:3556
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:3552
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:889
auto find_knot_indices(const utils::TensorArray< nspaces()> &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:711
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:730
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:660
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:318
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:1503
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:494
auto jac(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Returns a block-tensor with the Jacobian of the function space object in the points xi with respect t...
Definition functionspace.hpp:1930
static constexpr short_t geoDim() noexcept
Returns the geometric dimensions of the index-th space.
Definition functionspace.hpp:93
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:869
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:965
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:1039
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:309
auto & boundary() noexcept
Returns a non-constant reference to the index-th boundary object.
Definition functionspace.hpp:222
auto boundingBox() const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:989
FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:228
auto div(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Returns a block-tensor with the divergence of the function space object with respect to the parametri...
Definition functionspace.hpp:1214
auto curl(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Returns a block-tensor with the curl of the function space object with respect to the parametric vari...
Definition functionspace.hpp:1095
static constexpr std::size_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:186
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:838
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
Returns a block-tensor with the Jacobian of the function space object in the points xi with respect t...
Definition functionspace.hpp:1977
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:1916
static constexpr const auto & degrees() noexcept
Returns a constant reference to the array of degrees of the index-th space.
Definition functionspace.hpp:108
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:254
torch::Tensor boundary_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:264
auto & space() noexcept
Returns a non-constant reference to the index-th space.
Definition functionspace.hpp:209
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:816
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:941
std::tuple< Boundaries... > boundary_type
Boundary type.
Definition functionspace.hpp:86
FunctionSpace(std::tuple< Splines... > &&spline, std::tuple< Boundaries... > &&boundary)
Constructor.
Definition functionspace.hpp:175
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:638
virtual FunctionSpace & from_tensor(const torch::Tensor &tensor)
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:410
auto clone() const noexcept
Returns a clone of a subset of the function space.
Definition functionspace.hpp:231
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:1208
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:958
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:827
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:371
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:766
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
Returns a block-tensor with the Hessian of the function space object in the points xi with respect to...
Definition functionspace.hpp:1674
spline_type spline_
Splines.
Definition functionspace.hpp:123
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:383
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:553
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:1081
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
Returns a block-tensor with the Laplacian of the function space object in the points xi with respect ...
Definition functionspace.hpp:2135
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:392
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:807
auto scale_(std::index_sequence< Is... >, value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:898
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:746
pugi::xml_node & to_xml_(std::index_sequence< Is... >, pugi::xml_node &root, int id=0, std::string label="") const
Returns the function space object as XML node.
Definition functionspace.hpp:421
auto boundingBox_(std::index_sequence< Is... >) const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:983
std::tuple< typename Boundaries::eval_type... > boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:89
FunctionSpace & from_xml(const pugi::xml_node &root, int id=0, std::string label="")
Updates the function space object from XML node.
Definition functionspace.hpp:466
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
Returns a block-tensor with the gradient of the function space object in the points xi with respect t...
Definition functionspace.hpp:1379
auto eval(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:598
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:923
auto lapl(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Returns a block-tensor with the Laplacian of the function space object in the points xi with respect ...
Definition functionspace.hpp:2116
auto eval(const std::tuple< Xi... > &xi) const
Returns the values of the spline objects in the points xi
Definition functionspace.hpp:575
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
Returns a block-tensor with the curl of the function space object with respect to the parametric vari...
Definition functionspace.hpp:1163
auto lapl(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Returns a block-tensor with the Laplacian of the function space object in the points xi with respect ...
Definition functionspace.hpp:2108
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
Returns a block-tensor with the Hessian of the function space object in the points xi with respect to...
Definition functionspace.hpp:1536
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
Returns a block-tensor with the divergence of the function space object with respect to the parametri...
Definition functionspace.hpp:1264
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 >{})
Constructor.
Definition functionspace.hpp:149
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:850
FunctionSpace(std::tuple< Splines... > &&spline)
Constructor.
Definition functionspace.hpp:167
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:1346
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:290
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:860
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
Returns a block-tensor with the Hessian of the function space object in the points xi with respect to...
Definition functionspace.hpp:1509
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:620
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:878
nlohmann::json to_json_(std::index_sequence< Is... >) const
Serialization to JSON.
Definition functionspace.hpp:475
auto eval_basfunc(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:775
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:299
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:976
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
Returns a block-tensor with the divergence of the function space object with respect to the parametri...
Definition functionspace.hpp:1241
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:789
constexpr auto & boundaries() noexcept
Returns a non-constant reference to the tuple of boundary object.
Definition functionspace.hpp:200
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
Returns a block-tensor with the Laplacian of the function space object in the points xi with respect ...
Definition functionspace.hpp:2158
const auto & boundary() const noexcept
Returns a constant reference to the index-th boundary object.
Definition functionspace.hpp:215
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:140
pugi::xml_node & to_xml(pugi::xml_node &root, int id=0, std::string label="") const
Returns the function space object as XML node.
Definition functionspace.hpp:441
auto jac(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Returns a block-tensor with the Jacobian of the function space object in the points xi with respect t...
Definition functionspace.hpp:1922
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:1109
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:281
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
Returns a block-tensor with the Jacobian of the function space object in the points xi with respect t...
Definition functionspace.hpp:1949
boundary_type boundary_
Boundaries.
Definition functionspace.hpp:126
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
Returns a block-tensor with the divergence of the function space object with respect to the parametri...
Definition functionspace.hpp:1294
constexpr const auto & boundaries() const noexcept
Returns a constant reference to the tuple of boundary object.
Definition functionspace.hpp:197
auto hess(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Returns a block-tensor with the Hessian of the function space object in the points xi with respect to...
Definition functionspace.hpp:1517
constexpr const auto & spaces() const noexcept
Returns a constant reference to the tuple of function spaces.
Definition functionspace.hpp:191
void pretty_print(std::ostream &os) const noexcept override
Returns a string representation of the function space object.
Definition functionspace.hpp:1046
const auto & space() const noexcept
Returns a constant reference to the index-th function space.
Definition functionspace.hpp:203
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
Returns a block-tensor with the Jacobian of the function space object in the points xi with respect t...
Definition functionspace.hpp:2021
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:460
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:116
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:1013
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:537
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:717
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
Returns a block-tensor with the gradient of the function space object in the points xi with respect t...
Definition functionspace.hpp:1432
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:335
FunctionSpace & from_xml_(std::index_sequence< Is... >, const pugi::xml_node &root, int id=0, std::string label="")
Updates the function space object from XML object.
Definition functionspace.hpp:450
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:906
auto find_knot_indices_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:696
bool operator==(const FunctionSpace< SplinesOther, BoundariesOther > &other) const
Returns true if both function space objects are the same.
Definition functionspace.hpp:501
auto eval(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:585
auto div(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Returns a block-tensor with the divergence of the function space object with respect to the parametri...
Definition functionspace.hpp:1222
FunctionSpace(const std::tuple< Splines... > &spline)
Constructor.
Definition functionspace.hpp:162
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:1024
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &tensor)
Sets the tuple of boundaries from a single-tensor representation.
Definition functionspace.hpp:404
torch::Tensor spaces_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of spaces.
Definition functionspace.hpp:247
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &tensor)
Sets the tuple of spaces from a single-tensor representation.
Definition functionspace.hpp:362
auto curl(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Returns a block-tensor with the curl of the function space object with respect to the parametric vari...
Definition functionspace.hpp:1087
static constexpr short_t parDim() noexcept
Returns the parametric dimensions of the index-th space.
Definition functionspace.hpp:100
auto scale_(std::index_sequence< Is... >, std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:913
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
Returns a block-tensor with the Hessian of the function space object in the points xi with respect to...
Definition functionspace.hpp:1576
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:2102
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:1131
constexpr auto & spaces() noexcept
Returns a non-constant reference to the tuple of function spaces.
Definition functionspace.hpp:194
auto translate_(std::index_sequence< Is... >, std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:930
auto find_knot_indices_(std::index_sequence< Is... >, const utils::TensorArray< nspaces()> &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:686
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:522
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
Returns a block-tensor with the Laplacian of the function space object in the points xi with respect ...
Definition functionspace.hpp:2188
FunctionSpace(const std::tuple< Splines... > &spline, const std::tuple< Boundaries... > &boundary)
Constructor.
Definition functionspace.hpp:171
auto grad(const utils::TensorArray1 &xi, const std::tuple< utils::TensorArray1 > &knot_indices, const std::tuple< torch::Tensor > &coeff_indices) const
Returns a block-tensor with the gradient of the function space object in the points xi with respect t...
Definition functionspace.hpp:1360
auto rotate_(std::index_sequence< Is... >, value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:948
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:271
auto grad(const utils::TensorArray< nspaces()> &xi, const std::tuple< TensorArrays... > &knot_indices) const
Returns a block-tensor with the gradient of the function space object in the points xi with respect t...
Definition functionspace.hpp:1352
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:998
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
Returns a block-tensor with the gradient of the function space object in the points xi with respect t...
Definition functionspace.hpp:1402
static constexpr std::size_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:181
auto eval_from_precomputed(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:672
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:328
pugi::xml_document to_xml(int id=0, const std::string &label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:431
Function space.
Definition functionspace.hpp:2478
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:2943
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:2921
FunctionSpace(const Spline &spline)
Constructor.
Definition functionspace.hpp:2564
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:2980
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:2545
auto eval_basfunc(const Args &...args) const
Returns the values of the spline objects' basis functions in the points xi
Definition functionspace.hpp:2893
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:2681
bool operator==(const FunctionSpace< SplinesOther, BoundariesOther > &other) const
Returns true if both function space objects are the same.
Definition functionspace.hpp:2754
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:2906
constexpr const boundary_type & boundary() const noexcept
Returns a constant reference to the index-th boundary object.
Definition functionspace.hpp:2611
virtual torch::Tensor spaces_as_tensor() const noexcept
Returns a single-tensor representation of the space.
Definition functionspace.hpp:2646
pugi::xml_document to_xml(int id=0, const std::string &label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:2715
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:3020
virtual int64_t boundary_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the boundary.
Definition functionspace.hpp:2672
static constexpr short_t geoDim() noexcept
Returns the geometric dimensions of the index-th space.
Definition functionspace.hpp:2498
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:2770
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the boundary.
Definition functionspace.hpp:2651
constexpr boundary_type & boundary() noexcept
Returns a non-constant reference to the index-th boundary object.
Definition functionspace.hpp:2619
static constexpr short_t parDim() noexcept
Returns the parametric dimensions of the index-th space.
Definition functionspace.hpp:2505
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:2973
Spline spline_type
Spline type.
Definition functionspace.hpp:2485
void pretty_print(std::ostream &os) const noexcept override
Returns a string representation of the function space object.
Definition functionspace.hpp:3028
virtual int64_t spaces_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the space.
Definition functionspace.hpp:2666
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:2731
auto find_knot_indices(const Xi &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:2872
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:2785
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:3010
FunctionSpace(Spline &&spline)
Constructor.
Definition functionspace.hpp:2570
Boundary::eval_type boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:2494
constexpr spline_type & space() noexcept
Returns a non-constant reference to the index-th function space.
Definition functionspace.hpp:2604
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:2960
auto eval(const Arg &arg, const Args &...args) const
Returns the values of the spline object in the points xi
Definition functionspace.hpp:2831
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:2812
FunctionSpace & from_xml(const pugi::xml_node &root, int id=0, std::string label="")
Updates the function space object from XML node.
Definition functionspace.hpp:2737
constexpr auto & spaces() noexcept
Returns a non-constant reference to the tuple of function spaces.
Definition functionspace.hpp:2587
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:3001
pugi::xml_node & to_xml(pugi::xml_node &root, int id=0, std::string label="") const
Returns the function space object as XML node.
Definition functionspace.hpp:2725
static constexpr std::size_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:2578
constexpr FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:2625
auto find_knot_indices_(std::index_sequence< Is... >, const Xi &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:2861
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:2994
static constexpr std::size_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:2581
static constexpr const auto & degrees() noexcept
Returns a constant reference to the array of degrees of the index-th space.
Definition functionspace.hpp:2513
constexpr const auto & spaces() const noexcept
Returns a constant reference to the tuple of function spaces.
Definition functionspace.hpp:2584
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:2987
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:2521
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:2951
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:2798
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:2695
constexpr auto & boundaries() noexcept
Returns a non-constant reference to the tuple of boundary object.
Definition functionspace.hpp:2593
FunctionSpace(FunctionSpace &&)=default
Move constructor.
boundary_type boundary_
Boundary.
Definition functionspace.hpp:2531
Boundary boundary_type
Boundary type.
Definition functionspace.hpp:2491
utils::TensorArray< Spline::parDim()> eval_type
Spline evaluation type.
Definition functionspace.hpp:2488
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &coeffs) noexcept
Sets the space from a single-tensor representation.
Definition functionspace.hpp:2687
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &coeffs) noexcept
Sets the boundary from a single-tensor representation.
Definition functionspace.hpp:2702
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:2660
constexpr const auto & boundaries() const noexcept
Returns a constant reference to the tuple of boundary object.
Definition functionspace.hpp:2590
FunctionSpace(const FunctionSpace &)=default
Copy constructor.
spline_type spline_
Spline.
Definition functionspace.hpp:2528
Spline::value_type value_type
Value type.
Definition functionspace.hpp:2482
auto eval_from_precomputed(const Args &...args) const
Returns the value of the spline object from precomputed basis function.
Definition functionspace.hpp:2850
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:2744
FunctionSpace & from_tensor(const torch::Tensor &coeffs) noexcept
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:2708
FunctionSpace(std::array< std::vector< value_type >, Spline::parDim()> kv, enum init init=init::greville, Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition functionspace.hpp:2554
constexpr const spline_type & space() const noexcept
Returns a constant reference to the index-th function space.
Definition functionspace.hpp:2597
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:2965
constexpr auto clone() const noexcept
Returns a subset of the tuple of function spaces.
Definition functionspace.hpp:2630
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:3255
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:3238
FunctionSpace_trait< utils::tuple_cat_t< Splines... >, utils::tuple_cat_t< Boundaries... > >::type type
Definition functionspace.hpp:3247
std::ostream & operator<<(std::ostream &os, const FunctionSpace< Splines... > &obj)
Print (as string) a function space object.
Definition functionspace.hpp:2464
Forward declaration.
Definition functionspace.hpp:3206
TensorArray< 4 > TensorArray4
Definition tensorarray.hpp:32
std::array< torch::Tensor, N > TensorArray
Definition tensorarray.hpp:26
auto zip(T &&...seqs)
Definition zip.hpp:97
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:71
TensorArray< 2 > TensorArray2
Definition tensorarray.hpp:30
Forward declaration of BlockTensor.
Definition blocktensor.hpp:43
deriv
Enumerator for specifying the derivative of B-spline evaluation.
Definition bspline.hpp:72
BoundaryCommon< BoundaryCore< Spline, Spline::parDim()> > Boundary
Boundary.
Definition boundary.hpp:1978
detail::FunctionSpace_trait< Args... >::type FunctionSpace
Function space alias.
Definition functionspace.hpp:3259
std::ostream & operator<<(std::ostream &os, const MemoryDebugger< id > &obj)
Print (as string) a memory debugger object.
Definition memory.hpp:125
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:55
FunctionSpace< Spline > S
Spline function space .
Definition functionspace.hpp:3286
functionspace
Enumerator for the function space component.
Definition functionspace.hpp:31
@ none
Definition boundary.hpp:38
short int short_t
Definition core.hpp:74
H(curl) function space.
Definition functionspace.hpp:4174
Nedelec like function space.
Definition functionspace.hpp:3607
Nedelec-Raviart-Thomas-$P$ triple function space.
Definition functionspace.hpp:4241
Raviart-Thomas like function space.
Definition functionspace.hpp:3915
Taylor-Hood like function space.
Definition functionspace.hpp:3289
Serialization prototype.
Definition serialize.hpp:29