17#include <boost/preprocessor/seq/for_each.hpp>
26using namespace literals;
27using utils::operator+;
36#define IGANET_FUNCTIONSPACE_DEFAULT_OPS(FunctionSpace) \
37 FunctionSpace() = default; \
38 FunctionSpace(FunctionSpace &&) = default; \
39 FunctionSpace(const FunctionSpace &) = default;
47template <
typename,
typename>
54template <
typename... Splines,
typename... Boundaries>
61 using value_type = std::common_type_t<
typename Splines::value_type...>;
103 Splines::parDim()> &...kv,
109 static_assert((Splines::is_nonuniform() && ... &&
true),
110 "Constructor is only available for non-uniform splines");
125 const std::tuple<Boundaries...> &
boundary)
129 std::tuple<Boundaries...> &&
boundary)
134 inline static constexpr std::size_t
nspaces() noexcept {
135 return sizeof...(Splines);
140 return sizeof...(Boundaries);
144 template <std::
size_t index>
inline const auto &
space() const noexcept {
145 static_assert(index >= 0 && index <
nspaces());
146 return std::get<index>(
spline_);
150 template <std::
size_t index>
inline auto &
space() noexcept {
151 static_assert(index >= 0 && index <
nspaces());
152 return std::get<index>(
spline_);
156 template <std::
size_t index>
inline const auto &
boundary() const noexcept {
157 static_assert(index >= 0 && index <
nboundaries());
163 template <std::
size_t index>
inline auto &
boundary() noexcept {
164 static_assert(index >= 0 && index <
nboundaries());
172 template <std::size_t... index>
inline auto clone() const noexcept {
174 static_assert(((index >= 0 && index <
nspaces()) && ... &&
true));
177 std::tuple<std::tuple_element_t<index, boundary_type>...>>(
178 std::make_tuple(std::get<index>(
spline_)...), std::make_tuple(std::get<index>(
boundary_)...));
184 template <std::size_t... Is>
187 return torch::cat({std::get<Is>(
spline_).as_tensor()...});
194 return spaces_as_tensor_(
195 std::make_index_sequence<FunctionSpace::nspaces()>{});
201 template <std::size_t... Is>
204 return torch::cat({std::get<Is>(
boundary_).as_tensor()...});
211 return boundary_as_tensor_(
212 std::make_index_sequence<FunctionSpace::nboundaries()>{});
220 virtual inline torch::Tensor
as_tensor() const noexcept {
227 template <std::size_t... Is>
231 [](
auto... v) {
return (v + ...); },
239 return spaces_as_tensor_size_(
240 std::make_index_sequence<FunctionSpace::nspaces()>{});
246 template <std::size_t... Is>
250 [](
auto... v) {
return (v + ...); },
258 return boundary_as_tensor_size_(
259 std::make_index_sequence<FunctionSpace::nboundaries()>{});
273 template <std::size_t... Is>
275 const torch::Tensor &tensor) {
278 std::array<int64_t,
sizeof...(Is)> partialSums{0};
279 auto partial_sums = [&partialSums,
280 this]<std::size_t... Js>(std::index_sequence<Js...>) {
281 ((std::get<Js + 1>(partialSums) =
282 std::get<Js>(partialSums) + std::get<Js>(
spline_).as_tensor_size()),
285 partial_sums(std::make_index_sequence<FunctionSpace::nspaces() - 1>{});
288 ((std::get<Is>(
spline_).from_tensor(tensor.index(
289 {torch::indexing::Slice(partialSums[Is],
291 std::get<Is>(spline_).as_tensor_size()),
302 return spaces_from_tensor_(
303 std::make_index_sequence<FunctionSpace::nspaces()>{}, tensor);
309 template <std::size_t... Is>
311 const torch::Tensor &tensor) {
323 return boundary_from_tensor_(
324 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
329 template <std::size_t... Is>
332 const torch::Tensor &tensor) {
333 (std::get<Is>(
boundary_).from_full_tensor(
344 return boundary_from_full_tensor_(
345 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
350 spaces_from_tensor_(std::make_index_sequence<FunctionSpace::nspaces()>{},
352 boundary_from_full_tensor_(
353 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
359 template <std::size_t... Is>
360 inline pugi::xml_node &
to_xml_(std::index_sequence<Is...>,
361 pugi::xml_node &root,
int id = 0,
362 std::string label =
"")
const {
364 (std::get<Is>(
spline_).to_xml(root,
id, label, Is), ...);
370 inline pugi::xml_document
to_xml(
int id = 0, std::string label =
"")
const {
371 pugi::xml_document doc;
372 pugi::xml_node root = doc.append_child(
"xml");
379 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
380 std::string label =
"")
const {
381 return to_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
387 template <std::size_t... Is>
389 const pugi::xml_node &root,
int id = 0,
390 std::string label =
"") {
392 (std::get<Is>(
spline_).from_xml(root,
id, label, Is), ...);
399 std::string label =
"") {
400 return from_xml(doc.child(
"xml"),
id, label);
405 std::string label =
"") {
406 return from_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
412 template <std::size_t... Is>
413 nlohmann::json
to_json_(std::index_sequence<Is...>)
const {
414 auto json_this = nlohmann::json::array();
415 auto json_boundary = nlohmann::json::array();
417 (json_boundary.push_back(std::get<Is>(
boundary_).to_json()), ...);
419 auto json = nlohmann::json::array();
420 for (
auto [t, b] :
utils::zip(json_this, json_boundary)) {
421 auto json_inner = nlohmann::json::array();
422 json_inner.push_back(t);
423 json_inner.push_back(b);
424 json.push_back(json_inner);
433 return to_json_(std::make_index_sequence<FunctionSpace::nspaces()>{});
441 std::size_t... Is,
typename... Xi>
442 inline auto eval_(std::index_sequence<Is...>,
443 const std::tuple<Xi...> &xi)
const {
446 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
447 std::get<Is>(xi))...);
450 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
451 std::get<Is>(xi))...);
456 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
457 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
458 const std::tuple<Knot_Indices...> &knot_indices)
const {
461 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
462 std::get<Is>(xi), std::get<Is>(knot_indices))...);
465 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
466 std::get<Is>(xi), std::get<Is>(knot_indices))...);
471 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
472 typename... Coeff_Indices>
473 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
474 const std::tuple<Knot_Indices...> &knot_indices,
475 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
478 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
479 std::get<Is>(xi), std::get<Is>(knot_indices),
480 std::get<Is>(coeff_indices))...);
483 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
484 std::get<Is>(xi), std::get<Is>(knot_indices),
485 std::get<Is>(coeff_indices))...);
495 inline auto eval(
const std::tuple<Xi...> &xi)
const {
496 static_assert(FunctionSpace::nspaces() ==
sizeof...(Xi),
497 "Size of Xi mismatches functionspace dimension");
498 return eval_<comp, deriv, memory_optimized>(
499 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
504 typename... Xi,
typename... Knot_Indices>
505 inline auto eval(
const std::tuple<Xi...> &xi,
506 const std::tuple<Knot_Indices...> &knot_indices)
const {
508 (FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
509 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)),
510 "Sizes of Xi and Knot_Indices mismatch functionspace dimension");
511 return eval_<comp, deriv, memory_optimized>(
512 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
517 typename... Xi,
typename... Knot_Indices,
typename... Coeff_Indices>
518 inline auto eval(
const std::tuple<Xi...> &xi,
519 const std::tuple<Knot_Indices...> &knot_indices,
520 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
521 static_assert((FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
522 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)) &&
523 (FunctionSpace::nspaces() ==
sizeof...(Coeff_Indices)),
524 "Sizes of Xi, Knot_Indices and Coeff_Indices mismatch "
525 "functionspace dimension");
526 return eval_<comp, deriv, memory_optimized>(
527 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices,
537 typename... Basfunc,
typename... Coeff_Indices,
typename... Numeval,
541 const std::tuple<Basfunc...> &basfunc,
542 const std::tuple<Coeff_Indices...> &coeff_indices,
543 const std::tuple<Numeval...> &numeval,
544 const std::tuple<Sizes...> &sizes)
const {
546 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
547 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
548 std::get<Is>(numeval), std::get<Is>(sizes))...);
550 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
551 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
552 std::get<Is>(numeval), std::get<Is>(sizes))...);
556 typename... Basfunc,
typename... Coeff_Indices,
typename... Xi>
559 const std::tuple<Basfunc...> &basfunc,
560 const std::tuple<Coeff_Indices...> &coeff_indices,
561 const std::tuple<Xi...> &xi)
const {
563 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
564 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
565 std::get<Is>(xi)[0].numel(), std::get<Is>(xi)[0].sizes())...);
567 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
568 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
569 std::get<Is>(xi))...);
578 typename... Coeff_Indices,
typename... Numeval,
typename... Sizes>
581 const std::tuple<Coeff_Indices...> &coeff_indices,
582 const std::tuple<Numeval...> &numeval,
583 const std::tuple<Sizes...> &sizes)
const {
584 return eval_from_precomputed_<comp>(
585 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
586 coeff_indices, numeval, sizes);
590 typename... Coeff_Indices,
typename... Xi>
593 const std::tuple<Coeff_Indices...> &coeff_indices,
594 const std::tuple<Xi...> &xi)
const {
595 return eval_from_precomputed_<comp>(
596 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
609 std::get<Is>(
spline_).find_knot_indices(xi)...);
612 std::get<Is>(
boundary_).find_knot_indices(xi)...);
618 const std::tuple<Xi...> &xi)
const {
621 std::get<Is>(
spline_).find_knot_indices(std::get<Is>(xi))...);
624 std::get<Is>(
boundary_).find_knot_indices(std::get<Is>(xi))...);
631 template <functionspace comp = functionspace::
interior>
633 return find_knot_indices_<comp>(
634 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
639 return find_knot_indices_<comp>(
640 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
650 std::size_t... Is,
typename... Xi>
652 const std::tuple<Xi...> &xi)
const {
655 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
656 std::get<Is>(xi))...);
658 return std::tuple(std::get<Is>(
boundary_)
659 .template eval_basfunc<deriv, memory_optimized>(
660 std::get<Is>(xi))...);
665 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
668 const std::tuple<Knot_Indices...> &knot_indices)
const {
671 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
672 std::get<Is>(xi), std::get<Is>(knot_indices))...);
676 .template eval_basfunc<deriv, memory_optimized>(
677 std::get<Is>(xi), std::get<Is>(knot_indices))...);
688 return eval_basfunc_<comp, deriv, memory_optimized>(
689 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
694 typename... Xi,
typename... Knot_Indices>
697 const std::tuple<Knot_Indices...> &knot_indices)
const {
698 return eval_basfunc_<comp, deriv, memory_optimized>(
699 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
707 bool memory_optimized =
false, std::size_t... Is,
708 typename... Knot_Indices>
711 const std::tuple<Knot_Indices...> &knot_indices)
const {
714 std::get<Is>(
spline_).template find_coeff_indices<memory_optimized>(
715 std::get<Is>(knot_indices))...);
718 std::get<Is>(
boundary_).template find_coeff_indices<memory_optimized>(
719 std::get<Is>(knot_indices))...);
726 bool memory_optimized =
false,
typename... Knot_Indices>
729 return find_coeff_indices_<comp, memory_optimized>(
730 std::make_index_sequence<FunctionSpace::nspaces()>{}, knot_indices);
736 template <std::size_t... Is, std::size_t... Js>
738 std::index_sequence<Js...>,
int numRefine = 1,
739 int dimRefine = -1) {
740 (std::get<Is>(
spline_).uniform_refine(numRefine, dimRefine), ...);
741 (std::get<Js>(
boundary_).uniform_refine(numRefine, dimRefine), ...);
749 return uniform_refine_(
750 std::make_index_sequence<FunctionSpace::nspaces()>{},
751 std::make_index_sequence<FunctionSpace::nboundaries()>{}, numRefine,
758 template <
typename real_t, std::size_t... Is, std::size_t... Js>
759 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
762 typename Splines::template real_derived_self_type<real_t>...,
763 typename Boundaries::template real_derived_self_type<real_t>...>(
764 std::get<Is>(
spline_).to(options)...,
772 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
773 std::make_index_sequence<FunctionSpace::nboundaries()>{},
780 template <std::size_t... Is, std::size_t... Js>
781 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
782 torch::Device device)
const {
790 inline auto to(torch::Device device)
const {
791 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
792 std::make_index_sequence<FunctionSpace::nboundaries()>{},
798 template <
typename real_t, std::size_t... Is, std::size_t... Js>
799 inline auto to_(std::index_sequence<Is...>,
800 std::index_sequence<Js...>)
const {
802 typename Splines::template real_derived_self_type<real_t>...,
803 typename Boundaries::template real_derived_self_type<real_t>...>(
804 std::get<Is>(
spline_).template to<real_t>()...,
805 std::get<Js>(
boundary_).template to<real_t>()...);
810 template <
typename real_t>
inline auto to()
const {
812 std::make_index_sequence<FunctionSpace::nspaces()>{},
813 std::make_index_sequence<FunctionSpace::nboundaries()>{});
818 template <std::size_t... Is>
820 (std::get<Is>(
spline_).scale(s, dim), ...);
828 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, s, dim);
833 template <std::size_t N, std::size_t... Is>
834 inline auto scale_(std::index_sequence<Is...>, std::array<value_type, N> v) {
835 (std::get<Is>(
spline_).scale(v), ...);
836 (std::get<Is>(
boundary_).from_full_tensor(
844 template <std::
size_t N>
inline auto scale(std::array<value_type, N> v) {
845 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
850 template <std::size_t N, std::size_t... Is>
852 std::array<value_type, N> v) {
853 (std::get<Is>(
spline_).translate(v), ...);
854 (std::get<Is>(
boundary_).from_full_tensor(
862 template <std::
size_t N>
inline auto translate(std::array<value_type, N> v) {
863 return translate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
868 template <std::size_t... Is>
870 (std::get<Is>(
spline_).rotate(angle), ...);
871 (std::get<Is>(
boundary_).from_full_tensor(
880 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
885 template <std::size_t... Is>
886 inline auto rotate_(std::index_sequence<Is...>,
887 std::array<value_type, 3> angle) {
888 (std::get<Is>(
spline_).rotate(angle), ...);
889 (std::get<Is>(
boundary_).from_full_tensor(
897 inline auto rotate(std::array<value_type, 3> angle) {
898 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
903 template <std::size_t... Is>
905 return std::tuple(std::get<Is>(
spline_).boundingBox()...);
911 return boundingBox_(std::make_index_sequence<FunctionSpace::nspaces()>{});
917 template <std::size_t... Is>
918 inline torch::serialize::OutputArchive &
919 write_(std::index_sequence<Is...>, torch::serialize::OutputArchive &archive,
920 const std::string &key =
"functionspace")
const {
922 archive, key +
".fspace[" + std::to_string(Is) +
"].interior"),
925 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
933 inline torch::serialize::OutputArchive &
934 write(torch::serialize::OutputArchive &archive,
935 const std::string &key =
"functionspace")
const {
936 write_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
943 template <std::size_t... Is>
944 inline torch::serialize::InputArchive &
945 read_(std::index_sequence<Is...>, torch::serialize::InputArchive &archive,
946 const std::string &key =
"functionspace") {
947 (std::get<Is>(
spline_).read(archive, key +
".fspace[" + std::to_string(Is) +
951 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
959 inline torch::serialize::InputArchive &
960 read(torch::serialize::InputArchive &archive,
961 const std::string &key =
"functionspace") {
962 read_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
970 auto pretty_print_ = [
this,
971 &os]<std::size_t... Is>(std::index_sequence<Is...>) {
972 ((os <<
"\ninterior = ", std::get<Is>(
spline_).pretty_print(os),
973 os <<
"\nboundary = ", std::get<Is>(
boundary_).pretty_print(os)),
977 pretty_print_(std::make_index_sequence<
nspaces()>{});
1002 bool memory_optimized =
false>
1004 return curl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1008 bool memory_optimized =
false,
1009 typename... TensorArrays>
1011 const std::tuple<TensorArrays...> &knot_indices)
const {
1012 return curl<comp, memory_optimized>(xi, knot_indices,
1013 find_coeff_indices<comp>(knot_indices));
1017 bool memory_optimized =
false>
1019 const std::tuple<utils::TensorArray1> &knot_indices,
1020 const std::tuple<torch::Tensor> &coeff_indices)
const {
1022 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1024 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1030 bool memory_optimized =
false>
1033 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1034 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1036 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1037 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1038 xi[0].sizes() == xi[1].sizes());
1046 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1047 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1048 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1049 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1053 bool memory_optimized =
false>
1057 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1058 &coeff_indices)
const {
1060 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1061 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1062 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1063 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1069 *std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1070 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] -
1071 *std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1072 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1073 *std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1074 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] -
1075 *std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1076 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1077 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1078 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1079 *std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1080 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1084 bool memory_optimized =
false>
1089 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1090 torch::Tensor> &coeff_indices)
const {
1092 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1093 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1094 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1095 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1096 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1097 xi[2].sizes() == xi[3].sizes());
1099 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1130 bool memory_optimized =
false>
1132 return div<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1136 bool memory_optimized =
false,
1137 typename... TensorArrays>
1139 const std::tuple<TensorArrays...> &knot_indices)
const {
1140 return div<comp, memory_optimized>(xi, knot_indices,
1141 find_coeff_indices<comp>(knot_indices));
1145 bool memory_optimized =
false>
1147 const std::tuple<utils::TensorArray1> &knot_indices,
1148 const std::tuple<torch::Tensor> &coeff_indices)
const {
1150 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1153 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1154 "div(.) for vector-valued spaces requires 1D variables");
1157 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1158 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1163 bool memory_optimized =
false>
1166 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1167 const std::tuple<torch::Tensor, 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[0].sizes() == xi[1].sizes());
1174 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1175 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1176 "div(.) for vector-valued spaces requires 1D variables");
1179 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1180 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1181 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1182 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1187 bool memory_optimized =
false>
1191 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1192 &coeff_indices)
const {
1194 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1195 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1196 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1197 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1200 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1201 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1202 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1203 "div(.) for vector-valued spaces requires 1D variables");
1206 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1207 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1208 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1209 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1210 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1211 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1216 bool memory_optimized =
false>
1221 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1222 torch::Tensor> &coeff_indices)
const {
1224 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1225 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1226 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1227 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1228 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1229 xi[2].sizes() == xi[3].sizes());
1232 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1233 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1234 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1235 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1236 "div(.) for vector-valued spaces requires 1D variables");
1239 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1240 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1241 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1242 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1243 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1244 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
1245 *std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1246 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1269 bool memory_optimized =
false>
1271 return grad<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1275 bool memory_optimized =
false,
1276 typename... TensorArrays>
1278 const std::tuple<TensorArrays...> &knot_indices)
const {
1279 return grad<comp, memory_optimized>(xi, knot_indices,
1280 find_coeff_indices<comp>(knot_indices));
1284 bool memory_optimized =
false>
1286 const std::tuple<utils::TensorArray1> &knot_indices,
1287 const std::tuple<torch::Tensor> &coeff_indices)
const {
1289 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1292 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1293 "grad(.) for vector-valued spaces requires 1D variables");
1296 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1297 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1302 bool memory_optimized =
false>
1305 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1306 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1308 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1309 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1310 xi[0].sizes() == xi[1].sizes());
1313 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1314 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1315 "grad(.) for vector-valued spaces requires 1D variables");
1318 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1319 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1320 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1321 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1326 bool memory_optimized =
false>
1330 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1331 &coeff_indices)
const {
1333 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1334 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1335 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1336 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1339 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1340 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1341 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1342 "div(.) for vector-valued spaces requires 1D variables");
1345 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1346 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1347 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1348 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1349 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1350 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1355 bool memory_optimized =
false>
1360 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1361 torch::Tensor> &coeff_indices)
const {
1363 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1364 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1365 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1366 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1367 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1368 xi[2].sizes() == xi[3].sizes());
1371 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1372 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1373 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1374 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1375 "grad(.) for vector-valued spaces requires 1D variables");
1378 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1379 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1380 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1381 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1382 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1383 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1384 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1385 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1427 bool memory_optimized =
false>
1429 return hess<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1433 bool memory_optimized =
false,
1434 typename... TensorArrays>
1436 const std::tuple<TensorArrays...> &knot_indices)
const {
1437 return hess<comp, memory_optimized>(xi, knot_indices,
1438 find_coeff_indices<comp>(knot_indices));
1442 bool memory_optimized =
false>
1444 const std::tuple<utils::TensorArray1> &knot_indices,
1445 const std::tuple<torch::Tensor> &coeff_indices)
const {
1447 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1450 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1451 "hess(.) for vector-valued spaces requires 1D variables");
1454 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1455 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)));
1460 bool memory_optimized =
false>
1463 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1464 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1466 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1467 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1468 xi[0].sizes() == xi[1].sizes());
1471 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1472 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1473 "hess(.) for vector-valued spaces requires 1D variables");
1476 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1477 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1479 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1480 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1482 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1483 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1484 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1485 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1487 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1488 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1490 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1491 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1493 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1494 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1495 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1496 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)));
1501 bool memory_optimized =
false>
1505 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1506 &coeff_indices)
const {
1508 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1509 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1510 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1511 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1514 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1515 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1516 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1517 "hess(.) for vector-valued spaces requires 1D variables");
1520 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1521 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1523 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1524 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1526 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1527 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1529 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1530 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1531 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1532 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1534 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1535 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1537 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1538 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1540 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1541 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1542 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1543 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1545 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1546 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1548 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1549 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1551 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1552 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1554 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1555 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1556 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1557 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1559 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1560 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1562 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1563 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1565 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1566 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1567 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1568 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1570 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1571 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1573 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1574 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1576 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1577 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1579 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1580 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1581 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1582 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1584 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1585 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1587 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1588 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1590 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1591 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1592 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1593 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)));
1598 bool memory_optimized =
false>
1603 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1604 torch::Tensor> &coeff_indices)
const {
1606 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1607 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1608 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1609 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1610 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1611 xi[2].sizes() == xi[3].sizes());
1614 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1615 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1616 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1617 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1618 "hess(.) for vector-valued spaces requires 1D variables");
1621 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1622 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1624 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1625 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1627 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1628 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1630 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1631 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1633 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1634 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1635 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1636 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1638 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1639 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1641 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1642 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1644 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1645 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1647 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1648 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1649 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1650 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1652 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1653 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1655 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1656 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1658 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1659 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1661 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1662 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1663 std::get<0>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1664 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1666 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1667 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1669 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1670 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1672 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1673 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1675 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1676 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1678 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1679 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1680 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1681 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1683 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1684 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1686 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1687 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1689 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1690 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1692 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1693 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1694 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1695 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1697 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1698 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1700 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1701 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1703 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1704 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1706 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1707 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1708 std::get<1>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1709 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1711 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1712 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1714 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1715 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1717 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1718 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1720 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1721 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1723 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1724 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1725 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1726 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1728 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1729 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1731 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1732 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1734 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1735 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1737 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1738 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1739 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1740 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1742 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1743 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1745 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1746 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1748 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1749 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1751 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1752 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1753 std::get<2>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1754 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1756 std::get<3>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1757 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1759 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1760 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1762 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1763 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1765 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1766 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1768 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1769 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1770 std::get<3>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1771 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1773 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1774 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1776 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1777 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1779 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1780 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1782 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1783 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1784 std::get<3>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1785 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1787 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1788 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1790 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1791 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1793 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1794 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1796 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1797 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1798 std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1799 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)));
1841 bool memory_optimized =
false>
1843 return jac<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1847 bool memory_optimized =
false,
1848 typename... TensorArrays>
1850 const std::tuple<TensorArrays...> &knot_indices)
const {
1851 return jac<comp, memory_optimized>(xi, knot_indices,
1852 find_coeff_indices<comp>(knot_indices));
1856 bool memory_optimized =
false>
1858 const std::tuple<utils::TensorArray1> &knot_indices,
1859 const std::tuple<torch::Tensor> &coeff_indices)
const {
1861 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1864 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1865 "jac(.) for vector-valued spaces requires 1D variables");
1868 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1869 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1874 bool memory_optimized =
false>
1877 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1878 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1880 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1881 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1882 xi[0].sizes() == xi[1].sizes());
1885 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1886 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1887 "jac(.) for vector-valued spaces requires 1D variables");
1890 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1891 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1892 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1893 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1895 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1896 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1897 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1898 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1903 bool memory_optimized =
false>
1907 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1908 &coeff_indices)
const {
1910 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1911 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1912 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1913 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1916 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1917 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1918 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1919 "jac(.) for vector-valued spaces requires 1D variables");
1922 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1923 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1924 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1925 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1926 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1927 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1929 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1930 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1931 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1932 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1933 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1934 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1936 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1937 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1938 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1939 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1940 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1941 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1946 bool memory_optimized =
false>
1951 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1952 torch::Tensor> &coeff_indices)
const {
1954 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1955 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1956 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1957 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1958 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1959 xi[2].sizes() == xi[3].sizes());
1962 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1963 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1964 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1965 "jac(.) for vector-valued spaces requires 1D variables");
1968 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1969 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1970 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1971 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1972 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1973 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1974 std::get<0>(
spline_).
template eval<deriv::dt, memory_optimized>(
1975 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1977 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1978 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1979 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1980 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1981 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1982 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1983 std::get<1>(
spline_).
template eval<deriv::dt, memory_optimized>(
1984 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1986 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1987 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1988 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1989 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1990 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1991 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1992 std::get<2>(
spline_).
template eval<deriv::dt, memory_optimized>(
1993 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1995 std::get<3>(
spline_).
template eval<deriv::dx, memory_optimized>(
1996 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
1997 std::get<3>(
spline_).
template eval<deriv::dy, memory_optimized>(
1998 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
1999 std::get<3>(
spline_).
template eval<deriv::dz, memory_optimized>(
2000 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2001 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
2002 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2028 bool memory_optimized =
false>
2030 return lapl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
2034 bool memory_optimized =
false,
2035 typename... TensorArrays>
2037 const std::tuple<TensorArrays...> &knot_indices)
const {
2038 return lapl<comp, memory_optimized>(xi, knot_indices,
2039 find_coeff_indices<comp>(knot_indices));
2043 bool memory_optimized =
false>
2045 const std::tuple<utils::TensorArray1> &knot_indices,
2046 const std::tuple<torch::Tensor> &coeff_indices)
const {
2048 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
2051 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
2052 "lapl(.) for vector-valued spaces requires 1D variables");
2055 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2056 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
2061 bool memory_optimized =
false>
2064 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
2065 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
2067 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2068 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2069 xi[0].sizes() == xi[1].sizes());
2072 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2073 std::tuple_element_t<1, spline_type>::geoDim() == 1,
2074 "lapl(.) for vector-valued spaces requires 1D variables");
2077 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2078 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2079 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2080 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
2085 bool memory_optimized =
false>
2089 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
2090 &coeff_indices)
const {
2092 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2093 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2094 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2095 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
2098 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2099 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2100 std::tuple_element_t<2, spline_type>::geoDim() == 1,
2101 "div(.) for vector-valued spaces requires 1D variables");
2104 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2105 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2106 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2107 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2108 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2109 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
2114 bool memory_optimized =
false>
2119 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
2120 torch::Tensor> &coeff_indices)
const {
2122 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2123 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2124 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2125 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
2126 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
2127 xi[2].sizes() == xi[3].sizes());
2130 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2131 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2132 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
2133 std::tuple_element_t<3, spline_type>::geoDim() == 1,
2134 "div(.) for vector-valued spaces requires 1D variables");
2137 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2138 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2139 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2140 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2141 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2142 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
2143 *std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
2144 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2149#define GENERATE_EXPR_MACRO(r, data, name) \
2151 template <functionspace comp = functionspace::interior, \
2152 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
2153 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2154 const std::tuple<Xi...> &xi) const { \
2155 if constexpr (comp == functionspace::interior) \
2156 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2157 std::get<Is>(xi))...); \
2158 else if constexpr (comp == functionspace::boundary) \
2159 return std::tuple( \
2160 std::get<Is>(boundary_).template name<memory_optimized>( \
2161 std::get<Is>(xi))...); \
2164 template <functionspace comp = functionspace::interior, \
2165 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2166 typename... Knot_Indices> \
2167 inline auto BOOST_PP_CAT(name, _all_)( \
2168 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2169 const std::tuple<Knot_Indices...> &knot_indices) const { \
2170 if constexpr (comp == functionspace::interior) \
2171 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2172 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2173 else if constexpr (comp == functionspace::boundary) \
2174 return std::tuple( \
2175 std::get<Is>(boundary_).template name<memory_optimized>( \
2176 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2179 template <functionspace comp = functionspace::interior, \
2180 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2181 typename... Knot_Indices, typename... Coeff_Indices> \
2182 inline auto BOOST_PP_CAT(name, _all_)( \
2183 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2184 const std::tuple<Knot_Indices...> &knot_indices, \
2185 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
2186 if constexpr (comp == functionspace::interior) \
2187 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2188 std::get<Is>(xi), std::get<Is>(knot_indices), \
2189 std::get<Is>(coeff_indices))...); \
2190 else if constexpr (comp == functionspace::boundary) \
2191 return std::tuple( \
2192 std::get<Is>(boundary_).template name<memory_optimized>( \
2193 std::get<Is>(xi), std::get<Is>(knot_indices), \
2194 std::get<Is>(coeff_indices))...); \
2197 template <functionspace comp = functionspace::interior, \
2198 bool memory_optimized = false, std::size_t... Is, std::size_t N> \
2199 inline auto BOOST_PP_CAT(name, _)(std::index_sequence<Is...>, \
2200 const utils::TensorArray<N> &xi) const { \
2201 if constexpr (comp == functionspace::interior) \
2202 return name<comp, memory_optimized>( \
2203 xi, std::tuple(std::get<Is>(spline_).find_knot_indices(xi)...)); \
2204 else if constexpr (comp == functionspace::boundary) \
2205 return name<comp, memory_optimized>( \
2206 xi, std::tuple(std::get<Is>(boundary_).find_knot_indices(xi)...)); \
2209 template <functionspace comp = functionspace::interior, \
2210 bool memory_optimized = false, std::size_t... Is, std::size_t N, \
2211 typename... Knot_Indices> \
2212 inline auto BOOST_PP_CAT(name, _)( \
2213 std::index_sequence<Is...>, const utils::TensorArray<N> &xi, \
2214 const std::tuple<Knot_Indices...> &knot_indices) const { \
2215 if constexpr (comp == functionspace::interior) \
2216 return name<comp, memory_optimized>( \
2218 std::tuple(std::get<Is>(spline_).find_coeff_indices( \
2219 std::get<Is>(knot_indices))...)); \
2220 else if constexpr (comp == functionspace::boundary) \
2221 return name<comp, memory_optimized>( \
2223 std::tuple(std::get<Is>(boundary_).find_coeff_indices( \
2224 std::get<Is>(knot_indices))...)); \
2228 template <functionspace comp = functionspace::interior, \
2229 bool memory_optimized = false, typename... Args> \
2230 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2231 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2232 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2235 template <functionspace comp = functionspace::interior, \
2236 bool memory_optimized = false> \
2237 inline auto name(const torch::Tensor &xi) const { \
2238 return name<comp, memory_optimized>(utils::TensorArray1({xi})); \
2241 template <functionspace comp = functionspace::interior, \
2242 bool memory_optimized = false, std::size_t N> \
2243 inline auto name(const utils::TensorArray<N> &xi) const { \
2244 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2245 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi); \
2248 template <functionspace comp = functionspace::interior, \
2249 bool memory_optimized = false, std::size_t N, \
2250 typename... Knot_Indices> \
2251 inline auto name(const utils::TensorArray<N> &xi, \
2252 const std::tuple<Knot_Indices...> &knot_indices) const { \
2253 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2254 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, \
2262#undef GENERATE_EXPR_MACRO
2264#define GENERATE_IEXPR_MACRO(r, data, name) \
2266 template <functionspace comp = functionspace::interior, \
2267 bool memory_optimized = false, std::size_t... Is, \
2268 typename Geometry, typename... Xi> \
2269 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2270 const Geometry &G, \
2271 const std::tuple<Xi...> &xi) const { \
2272 if constexpr (comp == functionspace::interior) { \
2273 if constexpr (Geometry::nspaces() == 1) \
2274 return std::tuple( \
2275 std::get<Is>(spline_).template name<memory_optimized>( \
2276 G.space(), std::get<Is>(xi))...); \
2277 else if constexpr (Geometry::nspaces() == nspaces()) \
2278 return std::tuple( \
2279 std::get<Is>(spline_).template name<memory_optimized>( \
2280 G.template space<Is>(), std::get<Is>(xi))...); \
2281 } else if constexpr (comp == functionspace::boundary) { \
2282 if constexpr (Geometry::nboundaries() == 1) \
2283 return std::tuple( \
2284 std::get<Is>(boundary_).template name<memory_optimized>( \
2285 static_cast<typename Geometry::boundary_type::boundary_type>( \
2286 G.boundary().coeffs()), \
2287 std::get<Is>(xi))...); \
2288 else if constexpr (Geometry::nboundaries() == nboundaries()) \
2289 return std::tuple( \
2290 std::get<Is>(boundary_).template name<memory_optimized>( \
2291 G.template boundary<Is>().coeffs(), std::get<Is>(xi))...); \
2295 template <functionspace comp = functionspace::interior, \
2296 bool memory_optimized = false, std::size_t... Is, \
2297 typename Geometry, typename... Xi, typename... Knot_Indices, \
2298 typename... Knot_Indices_G> \
2299 inline auto BOOST_PP_CAT(name, _all_)( \
2300 std::index_sequence<Is...>, const Geometry &G, \
2301 const std::tuple<Xi...> &xi, \
2302 const std::tuple<Knot_Indices...> &knot_indices, \
2303 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
2304 if constexpr (comp == functionspace::interior) { \
2305 if constexpr (Geometry::nspaces() == 1) \
2306 return std::tuple( \
2307 std::get<Is>(spline_).template name<memory_optimized>( \
2308 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2309 std::get<Is>(knot_indices_G))...); \
2311 return std::tuple( \
2312 std::get<Is>(spline_).template name<memory_optimized>( \
2313 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2314 std::get<Is>(knot_indices_G))...); \
2315 } else if constexpr (comp == functionspace::boundary) { \
2316 if constexpr (Geometry::nspaces() == 1) \
2317 return std::tuple( \
2318 std::get<Is>(boundary_).template name<memory_optimized>( \
2319 static_cast<typename Geometry::boundary_type::boundary_type>( \
2320 G.boundary().coeffs()), \
2321 std::get<Is>(xi), std::get<Is>(knot_indices), \
2322 std::get<Is>(knot_indices_G))...); \
2324 return std::tuple( \
2325 std::get<Is>(boundary_).template name<memory_optimized>( \
2326 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2327 std::get<Is>(knot_indices), std::get<Is>(knot_indices_G))...); \
2331 template <functionspace comp = functionspace::interior, \
2332 bool memory_optimized = false, std::size_t... Is, \
2333 typename Geometry, typename... Xi, typename... Knot_Indices, \
2334 typename... Coeff_Indices, typename... Knot_Indices_G, \
2335 typename... Coeff_Indices_G> \
2336 inline auto BOOST_PP_CAT(name, _all_)( \
2337 std::index_sequence<Is...>, const Geometry &G, \
2338 const std::tuple<Xi...> &xi, \
2339 const std::tuple<Knot_Indices...> &knot_indices, \
2340 const std::tuple<Coeff_Indices...> &coeff_indices, \
2341 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
2342 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
2343 if constexpr (comp == functionspace::interior) { \
2344 if constexpr (Geometry::nspaces() == 1) \
2345 return std::tuple( \
2346 std::get<Is>(spline_).template name<memory_optimized>( \
2347 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2348 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2349 std::get<Is>(coeff_indices_G))...); \
2351 return std::tuple( \
2352 std::get<Is>(spline_).template name<memory_optimized>( \
2353 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2354 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2355 std::get<Is>(coeff_indices_G))...); \
2356 } else if constexpr (comp == functionspace::boundary) { \
2357 if constexpr (Geometry::nspaces() == 1) \
2358 return std::tuple( \
2359 std::get<Is>(boundary_).template name<memory_optimized>( \
2360 static_cast<typename Geometry::boundary_type::boundary_type>( \
2361 G.boundary().coeffs()), \
2362 std::get<Is>(xi), std::get<Is>(knot_indices), \
2363 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2364 std::get<Is>(coeff_indices_G))...); \
2366 return std::tuple( \
2367 std::get<Is>(boundary_).template name<memory_optimized>( \
2368 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2369 std::get<Is>(knot_indices), std::get<Is>(coeff_indices), \
2370 std::get<Is>(knot_indices_G), \
2371 std::get<Is>(coeff_indices_G))...); \
2376 template <functionspace comp = functionspace::interior, \
2377 bool memory_optimized = false, typename... Args> \
2378 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2379 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2380 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2387#undef GENERATE_IEXPR_MACRO
2391template <
typename... Splines>
2402template <
typename Spline,
typename Boundary>
2455 static_assert(Spline::is_nonuniform(),
2456 "Constructor is only available for non-uniform splines");
2474 inline static constexpr std::size_t
nspaces() noexcept {
return 1; }
2477 inline static constexpr std::size_t
nboundaries() noexcept {
return 1; }
2480 template <std::
size_t index = 0>
2482 static_assert(index >= 0 && index <
nspaces());
2488 static_assert(index >= 0 && index <
nspaces());
2493 template <std::
size_t index = 0>
2495 static_assert(index >= 0 && index <
nboundaries());
2502 static_assert(index >= 0 && index <
nboundaries());
2512 template <std::size_t... index>
inline constexpr auto clone() const noexcept {
2514 static_assert(((index >= 0 && index <
nspaces()) && ... &&
true));
2516 if constexpr (
sizeof...(index) == 1)
2520 std::tuple<std::tuple_element_t<index, std::tuple<spline_type>>...>,
2521 std::tuple<std::tuple_element_t<index, std::tuple<boundary_type>>...>>(
2522 std::get<index>(std::make_tuple(
spline_))...,
2523 std::get<index>(std::make_tuple(
boundary_))...);
2548 return spline_.as_tensor_size();
2596 inline pugi::xml_document
to_xml(
int id = 0, std::string label =
"")
const {
2597 pugi::xml_document doc;
2598 pugi::xml_node root = doc.append_child(
"xml");
2605 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
2606 std::string label =
"")
const {
2607 return spline_.to_xml(root,
id, label);
2612 std::string label =
"") {
2613 return from_xml(doc.child(
"xml"),
id, label);
2618 std::string label =
"") {
2625 auto json = nlohmann::json::array();
2626 json.push_back(
spline_.to_json());
2633 const std::function<std::array<
typename Spline::value_type,
2635 const std::array<
typename Spline::value_type, Spline::parDim()> &)>
2646 std::size_t... Is,
typename... Xi>
2647 inline auto eval_(std::index_sequence<Is...>,
2648 const std::tuple<Xi...> &xi)
const {
2651 spline_.template eval<deriv, memory_optimized>(std::get<Is>(xi))...);
2653 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2654 std::get<Is>(xi))...);
2659 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
2660 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
2661 const std::tuple<Knot_Indices...> &knot_indices)
const {
2663 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
2664 std::get<Is>(xi), std::get<Is>(knot_indices))...);
2666 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2667 std::get<Is>(xi), std::get<Is>(knot_indices))...);
2672 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
2673 typename... Coeff_Indices>
2674 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
2675 const std::tuple<Knot_Indices...> &knot_indices,
2676 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
2678 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
2679 std::get<Is>(xi), std::get<Is>(knot_indices),
2680 std::get<Is>(coeff_indices))...);
2682 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2683 std::get<Is>(xi), std::get<Is>(knot_indices),
2684 std::get<Is>(coeff_indices))...);
2692 typename Arg,
typename... Args>
2693 inline auto eval(
const Arg &arg,
const Args &...args)
const {
2695 if constexpr (utils::is_tuple_v<Arg>)
2696 return eval_<comp, deriv, memory_optimized>(
2697 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
2699 return spline_.template eval<deriv, memory_optimized>(arg, args...);
2701 if constexpr (utils::is_tuple_of_tuples_v<Arg>)
2702 return eval_<comp, deriv, memory_optimized>(
2703 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
2705 return boundary_.template eval<deriv, memory_optimized>(arg, args...);
2714 return spline_.eval_from_precomputed(args...);
2724 const Xi &xi)
const {
2726 return std::tuple(
spline_.find_knot_indices(std::get<Is>(xi))...);
2733 template <functionspace comp = functionspace::
interior,
typename Xi>
2736 if constexpr (utils::is_tuple_v<Xi>)
2737 return find_knot_indices_<comp>(
2738 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
2740 return spline_.find_knot_indices(xi);
2742 if constexpr (utils::is_tuple_of_tuples_v<Xi>)
2743 return find_knot_indices_<comp>(
2744 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
2757 return spline_.template eval_basfunc<deriv, memory_optimized>(args...);
2759 return boundary_.template eval_basfunc<deriv, memory_optimized>(args...);
2766 bool memory_optimized =
false, std::size_t... Is,
2767 typename Knot_Indices>
2769 const Knot_Indices &knot_indices)
const {
2771 return std::tuple(
spline_.template find_coeff_indices<memory_optimized>(
2772 std::get<Is>(knot_indices))...);
2774 return std::tuple(
boundary_.template find_coeff_indices<memory_optimized>(
2775 std::get<Is>(knot_indices))...);
2782 bool memory_optimized =
false,
typename Knot_Indices>
2785 if constexpr (utils::is_tuple_v<Knot_Indices>)
2786 return find_coeff_indices_<comp, memory_optimized>(
2787 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
2790 return spline_.template find_coeff_indices<memory_optimized>(
2793 if constexpr (utils::is_tuple_of_tuples_v<Knot_Indices>)
2794 return find_coeff_indices_<comp, memory_optimized>(
2795 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
2798 return boundary_.template find_coeff_indices<memory_optimized>(
2806 spline_.uniform_refine(numRefine, dimRefine);
2815 typename spline_type::template real_derived_self_type<real_t>,
2816 typename boundary_type::template real_derived_self_type<real_t>>(
2822 inline auto to(torch::Device device)
const {
2827 template <
typename real_t>
inline auto to()
const {
2829 typename spline_type::template real_derived_self_type<real_t>,
2830 typename boundary_type::template real_derived_self_type<real_t>>(
2842 template <std::
size_t N>
inline auto scale(std::array<value_type, N> v) {
2849 template <std::
size_t N>
inline auto translate(std::array<value_type, N> v) {
2863 inline auto rotate(std::array<value_type, 3> angle) {
2871 inline torch::serialize::OutputArchive &
2872 write(torch::serialize::OutputArchive &archive,
2873 const std::string &key =
"functionspace")
const {
2881 inline torch::serialize::InputArchive &
2882 read(torch::serialize::InputArchive &archive,
2883 const std::string &key =
"functionspace") {
2892 os <<
name() <<
"(\nspline = ";
2894 os <<
"\nboundary = ";
2899#define GENERATE_EXPR_MACRO(r, data, name) \
2901 template <functionspace comp = functionspace::interior, \
2902 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
2903 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2904 const std::tuple<Xi...> &xi) const { \
2905 if constexpr (comp == functionspace::interior) \
2906 return std::tuple( \
2907 spline_.template name<memory_optimized>(std::get<Is>(xi))...); \
2908 else if constexpr (comp == functionspace::boundary) \
2909 return std::tuple( \
2910 boundary_.template name<memory_optimized>(std::get<Is>(xi))...); \
2913 template <functionspace comp = functionspace::interior, \
2914 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2915 typename... Knot_Indices> \
2916 inline auto BOOST_PP_CAT(name, _all_)( \
2917 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2918 const std::tuple<Knot_Indices...> &knot_indices) const { \
2919 if constexpr (comp == functionspace::interior) \
2920 return std::tuple(spline_.template name<memory_optimized>( \
2921 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2922 else if constexpr (comp == functionspace::boundary) \
2923 return std::tuple(boundary_.template name<memory_optimized>( \
2924 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2927 template <functionspace comp = functionspace::interior, \
2928 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2929 typename... Knot_Indices, typename... Coeff_Indices> \
2930 inline auto BOOST_PP_CAT(name, _all_)( \
2931 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2932 const std::tuple<Knot_Indices...> &knot_indices, \
2933 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
2934 if constexpr (comp == functionspace::interior) \
2935 return std::tuple(spline_.template name<memory_optimized>( \
2936 std::get<Is>(xi), std::get<Is>(knot_indices), \
2937 std::get<Is>(coeff_indices))...); \
2938 else if constexpr (comp == functionspace::boundary) \
2939 return std::tuple(boundary_.template name<memory_optimized>( \
2940 std::get<Is>(xi), std::get<Is>(knot_indices), \
2941 std::get<Is>(coeff_indices))...); \
2945 template <functionspace comp = functionspace::interior, \
2946 bool memory_optimized = false, typename Arg, typename... Args> \
2947 inline auto name(const Arg &arg, const Args &...args) const { \
2948 if constexpr (comp == functionspace::interior) \
2949 if constexpr (utils::is_tuple_v<Arg>) \
2950 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2951 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
2953 return spline_.template name<memory_optimized>(arg, args...); \
2954 else if constexpr (comp == functionspace::boundary) { \
2955 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
2956 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2957 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
2959 return boundary_.template name<memory_optimized>(arg, args...); \
2967#undef GENERATE_EXPR_MACRO
2969#define GENERATE_IEXPR_MACRO(r, data, name) \
2971 template <functionspace comp = functionspace::interior, \
2972 bool memory_optimized = false, std::size_t... Is, \
2973 typename Geometry, typename... Xi> \
2974 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2975 const Geometry &G, \
2976 const std::tuple<Xi...> &xi) const { \
2977 if constexpr (comp == functionspace::interior) \
2978 return std::tuple(spline_.template name<memory_optimized>( \
2979 G.space(), std::get<Is>(xi))...); \
2980 else if constexpr (comp == functionspace::boundary) \
2981 return std::tuple(boundary_.template name<memory_optimized>( \
2982 static_cast<typename Geometry::boundary_type::boundary_type>( \
2983 G.boundary().coeffs()), \
2984 std::get<Is>(xi))...); \
2987 template <functionspace comp = functionspace::interior, \
2988 bool memory_optimized = false, std::size_t... Is, \
2989 typename Geometry, typename... Xi, typename... Knot_Indices, \
2990 typename... Knot_Indices_G> \
2991 inline auto BOOST_PP_CAT(name, _all_)( \
2992 std::index_sequence<Is...>, const Geometry &G, \
2993 const std::tuple<Xi...> &xi, \
2994 const std::tuple<Knot_Indices...> &knot_indices, \
2995 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
2996 if constexpr (comp == functionspace::interior) \
2997 return std::tuple(spline_.template name<memory_optimized>( \
2998 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2999 std::get<Is>(knot_indices_G))...); \
3000 else if constexpr (comp == functionspace::boundary) \
3001 return std::tuple(boundary_.template name<memory_optimized>( \
3002 static_cast<typename Geometry::boundary_type::boundary_type>( \
3003 G.boundary().coeffs()), \
3004 std::get<Is>(xi), std::get<Is>(knot_indices), \
3005 std::get<Is>(knot_indices_G))...); \
3008 template <functionspace comp = functionspace::interior, \
3009 bool memory_optimized = false, std::size_t... Is, \
3010 typename Geometry, typename... Xi, typename... Knot_Indices, \
3011 typename... Coeff_Indices, typename... Knot_Indices_G, \
3012 typename... Coeff_Indices_G> \
3013 inline auto BOOST_PP_CAT(name, _all_)( \
3014 std::index_sequence<Is...>, const Geometry &G, \
3015 const std::tuple<Xi...> &xi, \
3016 const std::tuple<Knot_Indices...> &knot_indices, \
3017 const std::tuple<Coeff_Indices...> &coeff_indices, \
3018 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
3019 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
3020 if constexpr (comp == functionspace::interior) \
3021 return std::tuple(spline_.template name<memory_optimized>( \
3022 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
3023 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3024 std::get<Is>(coeff_indices_G))...); \
3025 else if constexpr (comp == functionspace::boundary) \
3026 return std::tuple(boundary_.template name<memory_optimized>( \
3027 static_cast<typename Geometry::boundary_type::boundary_type>( \
3028 G.boundary().coeffs()), \
3029 std::get<Is>(xi), std::get<Is>(knot_indices), \
3030 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3031 std::get<Is>(coeff_indices_G))...); \
3035 template <functionspace comp = functionspace::interior, \
3036 bool memory_optimized = false, typename Geometry, typename Arg, \
3038 inline auto name(const Geometry &G, const Arg &arg, const Args &...args) \
3040 if constexpr (comp == functionspace::interior) { \
3041 if constexpr (utils::is_tuple_v<Arg>) \
3042 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3043 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3046 return spline_.template name<memory_optimized>(G.space(), arg, \
3048 } else if constexpr (comp == functionspace::boundary) { \
3049 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
3050 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3051 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3054 return boundary_.template name<memory_optimized>( \
3055 static_cast<typename Geometry::boundary_type::boundary_type>( \
3056 G.boundary().coeffs()), \
3065#undef GENERATE_IEXPR_MACRO
3077template <
typename Spline,
typename Boundary>
3083template <
typename... Splines>
3090template <
typename... Splines,
typename... Boundaries>
3099template <
typename Spline,
typename Boundary>
3107template <
typename... Splines,
typename... Boundaries>
3117 template<
typename T>
3121template <
typename... Args>
3125template <
typename Splines,
typename Boundaries>
3128 obj.pretty_print(os);
3152template <
typename Spline,
short_t = Spline::parDim()>
class TH;
3163template <
typename Spline>
3166 std::tuple<typename Spline::template derived_self_type<
3167 typename Spline::value_type, Spline::geoDim(),
3168 Spline::degree(0) + 1>,
3169 typename Spline::template derived_self_type<
3170 typename Spline::value_type, Spline::geoDim(),
3171 Spline::degree(0)>>> {
3175 typename Spline::template derived_self_type<
3176 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3177 typename Spline::template derived_self_type<
3178 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3185 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {
3186 static_assert(Spline::is_nonuniform(),
3187 "TH function space requires non-uniform splines");
3188 Base::template space<0>().reduce_continuity();
3191 TH(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3195 : Base({{kv[0].front + kv[0] + kv[0].back(), kv[1]}}, kv,
init, options) {
3196 static_assert(Spline::is_nonuniform(),
3197 "TH function space requires non-uniform splines");
3198 Base::template space<0>().reduce_continuity();
3216template <
typename Spline>
3219 std::tuple<typename Spline::template derived_self_type<
3220 typename Spline::value_type, Spline::geoDim(),
3221 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3222 typename Spline::template derived_self_type<
3223 typename Spline::value_type, Spline::geoDim(),
3224 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3225 typename Spline::template derived_self_type<
3226 typename Spline::value_type, Spline::geoDim(),
3227 Spline::degree(0), Spline::degree(1)>>> {
3231 std::tuple<
typename Spline::template derived_self_type<
3232 typename Spline::value_type, Spline::geoDim(),
3233 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3234 typename Spline::template derived_self_type<
3235 typename Spline::value_type, Spline::geoDim(),
3236 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3237 typename Spline::template derived_self_type<
3238 typename Spline::value_type, Spline::geoDim(),
3239 Spline::degree(0), Spline::degree(1)>>>;
3246 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
3247 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
3248 static_assert(Spline::is_nonuniform(),
3249 "TH function space requires non-uniform splines");
3250 Base::template space<0>().reduce_continuity();
3251 Base::template space<1>().reduce_continuity();
3254 TH(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3258 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3259 kv[1].front() + kv[1] + kv[1].back()}},
3260 {{kv[0].front() + kv[0] + kv[0].back(),
3261 kv[1].front() + kv[1] + kv[1].back()}},
3262 kv,
init, options) {
3263 static_assert(Spline::is_nonuniform(),
3264 "TH function space requires non-uniform splines");
3265 Base::template space<0>().reduce_continuity();
3266 Base::template space<1>().reduce_continuity();
3285template <
typename Spline>
3288 typename Spline::template derived_self_type<
3289 typename Spline::value_type, Spline::geoDim(),
3290 Spline::degree(0) + 1, Spline::degree(1) + 1,
3291 Spline::degree(2) + 1>,
3292 typename Spline::template derived_self_type<
3293 typename Spline::value_type, Spline::geoDim(),
3294 Spline::degree(0) + 1, Spline::degree(1) + 1,
3295 Spline::degree(2) + 1>,
3296 typename Spline::template derived_self_type<
3297 typename Spline::value_type, Spline::geoDim(),
3298 Spline::degree(0) + 1, Spline::degree(1) + 1,
3299 Spline::degree(2) + 1>,
3300 typename Spline::template derived_self_type<
3301 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3302 Spline::degree(1), Spline::degree(2)>>> {
3306 typename Spline::template derived_self_type<
3307 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3308 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3309 typename Spline::template derived_self_type<
3310 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3311 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3312 typename Spline::template derived_self_type<
3313 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3314 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3315 typename Spline::template derived_self_type<
3316 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3317 Spline::degree(1), Spline::degree(2)>>>;
3324 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3325 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3326 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
3328 static_assert(Spline::is_nonuniform(),
3329 "TH function space requires non-uniform splines");
3330 Base::template space<0>().reduce_continuity();
3331 Base::template space<1>().reduce_continuity();
3332 Base::template space<2>().reduce_continuity();
3335 TH(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3339 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3340 kv[1].front() + kv[1] + kv[1].back(),
3341 kv[2].front() + kv[2] + kv[2].back()}},
3342 {{kv[0].front() + kv[0] + kv[0].back(),
3343 kv[1].front() + kv[1] + kv[1].back(),
3344 kv[2].front() + kv[2] + kv[2].back()}},
3345 {{kv[0].front() + kv[0] + kv[0].back(),
3346 kv[1].front() + kv[1] + kv[1].back(),
3347 kv[2].front() + kv[2] + kv[2].back()}},
3348 kv,
init, options) {
3349 static_assert(Spline::is_nonuniform(),
3350 "TH function space requires non-uniform splines");
3351 Base::template space<0>().reduce_continuity();
3352 Base::template space<1>().reduce_continuity();
3353 Base::template space<2>().reduce_continuity();
3373template <
typename Spline>
3376 typename Spline::template derived_self_type<
3377 typename Spline::value_type, Spline::geoDim(),
3378 Spline::degree(0) + 1, Spline::degree(1) + 1,
3379 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3380 typename Spline::template derived_self_type<
3381 typename Spline::value_type, Spline::geoDim(),
3382 Spline::degree(0) + 1, Spline::degree(1) + 1,
3383 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3384 typename Spline::template derived_self_type<
3385 typename Spline::value_type, Spline::geoDim(),
3386 Spline::degree(0) + 1, Spline::degree(1) + 1,
3387 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3388 typename Spline::template derived_self_type<
3389 typename Spline::value_type, Spline::geoDim(),
3390 Spline::degree(0) + 1, Spline::degree(1) + 1,
3391 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3392 typename Spline::template derived_self_type<
3393 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3394 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3398 typename Spline::template derived_self_type<
3399 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3400 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3401 typename Spline::template derived_self_type<
3402 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3403 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3404 typename Spline::template derived_self_type<
3405 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3406 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3407 typename Spline::template derived_self_type<
3408 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3409 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3410 typename Spline::template derived_self_type<
3411 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3412 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
3419 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3420 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3421 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3422 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64), ncoeffs,
3424 static_assert(Spline::is_nonuniform(),
3425 "TH function space requires non-uniform splines");
3426 Base::template space<0>().reduce_continuity();
3427 Base::template space<1>().reduce_continuity();
3428 Base::template space<2>().reduce_continuity();
3429 Base::template space<3>().reduce_continuity();
3432 TH(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
3436 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3437 kv[1].front() + kv[1] + kv[1].back(),
3438 kv[2].front() + kv[2] + kv[2].back(),
3439 kv[3].front() + kv[3] + kv[3].back()}},
3440 {{kv[0].front() + kv[0] + kv[0].back(),
3441 kv[1].front() + kv[1] + kv[1].back(),
3442 kv[2].front() + kv[2] + kv[2].back(),
3443 kv[3].front() + kv[3] + kv[3].back()}},
3444 {{kv[0].front() + kv[0] + kv[0].back(),
3445 kv[1].front() + kv[1] + kv[1].back(),
3446 kv[2].front() + kv[2] + kv[2].back(),
3447 kv[3].front() + kv[3] + kv[3].back()}},
3448 {{kv[0].front() + kv[0] + kv[0].back(),
3449 kv[1].front() + kv[1] + kv[1].back(),
3450 kv[2].front() + kv[2] + kv[2].back(),
3451 kv[3].front() + kv[3] + kv[3].back()}},
3452 kv,
init, options) {
3453 static_assert(Spline::is_nonuniform(),
3454 "TH function space requires non-uniform splines");
3455 Base::template space<0>().reduce_continuity();
3456 Base::template space<1>().reduce_continuity();
3457 Base::template space<2>().reduce_continuity();
3458 Base::template space<3>().reduce_continuity();
3468template <
typename Spline,
short_t = Spline::parDim()>
class NE;
3479template <
typename Spline>
3482 std::tuple<typename Spline::template derived_self_type<
3483 typename Spline::value_type, Spline::geoDim(),
3484 Spline::degree(0) + 1>,
3485 typename Spline::template derived_self_type<
3486 typename Spline::value_type, Spline::geoDim(),
3487 Spline::degree(0)>>> {
3491 typename Spline::template derived_self_type<
3492 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3493 typename Spline::template derived_self_type<
3494 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3501 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
3503 NE(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3507 : Base(kv, kv,
init, options) {
3508 static_assert(Spline::is_nonuniform(),
3509 "Constructor only available for non-uniform splines");
3526template <
typename Spline>
3529 std::tuple<typename Spline::template derived_self_type<
3530 typename Spline::value_type, Spline::geoDim(),
3531 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3532 typename Spline::template derived_self_type<
3533 typename Spline::value_type, Spline::geoDim(),
3534 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3535 typename Spline::template derived_self_type<
3536 typename Spline::value_type, Spline::geoDim(),
3537 Spline::degree(0), Spline::degree(1)>>> {
3541 std::tuple<
typename Spline::template derived_self_type<
3542 typename Spline::value_type, Spline::geoDim(),
3543 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3544 typename Spline::template derived_self_type<
3545 typename Spline::value_type, Spline::geoDim(),
3546 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3547 typename Spline::template derived_self_type<
3548 typename Spline::value_type, Spline::geoDim(),
3549 Spline::degree(0), Spline::degree(1)>>>;
3556 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
3557 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
3558 static_assert(Spline::is_nonuniform(),
3559 "NE function space requires non-uniform splines");
3560 Base::template space<0>().reduce_continuity(1, 1);
3561 Base::template space<1>().reduce_continuity(1, 0);
3564 NE(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3568 : Base(kv, kv, kv,
init, options) {
3569 static_assert(Spline::is_nonuniform(),
3570 "NE function space requires non-uniform splines");
3571 Base::template space<0>().reduce_continuity(1, 1);
3572 Base::template space<1>().reduce_continuity(1, 0);
3591template <
typename Spline>
3594 typename Spline::template derived_self_type<
3595 typename Spline::value_type, Spline::geoDim(),
3596 Spline::degree(0) + 1, Spline::degree(1) + 1,
3597 Spline::degree(2) + 1>,
3598 typename Spline::template derived_self_type<
3599 typename Spline::value_type, Spline::geoDim(),
3600 Spline::degree(0) + 1, Spline::degree(1) + 1,
3601 Spline::degree(2) + 1>,
3602 typename Spline::template derived_self_type<
3603 typename Spline::value_type, Spline::geoDim(),
3604 Spline::degree(0) + 1, Spline::degree(1) + 1,
3605 Spline::degree(2) + 1>,
3606 typename Spline::template derived_self_type<
3607 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3608 Spline::degree(1), Spline::degree(2)>>> {
3612 typename Spline::template derived_self_type<
3613 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3614 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3615 typename Spline::template derived_self_type<
3616 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3617 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3618 typename Spline::template derived_self_type<
3619 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3620 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3621 typename Spline::template derived_self_type<
3622 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3623 Spline::degree(1), Spline::degree(2)>>>;
3630 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3631 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3632 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
3634 static_assert(Spline::is_nonuniform(),
3635 "NE function space requires non-uniform splines");
3636 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
3637 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
3638 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
3641 NE(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3645 : Base(kv, kv, kv, kv,
init, options) {
3646 static_assert(Spline::is_nonuniform(),
3647 "NE function space requires non-uniform splines");
3648 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
3649 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
3650 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
3670template <
typename Spline>
3673 typename Spline::template derived_self_type<
3674 typename Spline::value_type, Spline::geoDim(),
3675 Spline::degree(0) + 1, Spline::degree(1) + 1,
3676 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3677 typename Spline::template derived_self_type<
3678 typename Spline::value_type, Spline::geoDim(),
3679 Spline::degree(0) + 1, Spline::degree(1) + 1,
3680 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3681 typename Spline::template derived_self_type<
3682 typename Spline::value_type, Spline::geoDim(),
3683 Spline::degree(0) + 1, Spline::degree(1) + 1,
3684 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3685 typename Spline::template derived_self_type<
3686 typename Spline::value_type, Spline::geoDim(),
3687 Spline::degree(0) + 1, Spline::degree(1) + 1,
3688 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3689 typename Spline::template derived_self_type<
3690 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3691 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3695 typename Spline::template derived_self_type<
3696 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3697 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3698 typename Spline::template derived_self_type<
3699 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3700 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3701 typename Spline::template derived_self_type<
3702 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3703 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3704 typename Spline::template derived_self_type<
3705 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3706 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3707 typename Spline::template derived_self_type<
3708 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3709 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
3716 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3717 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3718 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3719 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64), ncoeffs,
3721 static_assert(Spline::is_nonuniform(),
3722 "NE function space requires non-uniform splines");
3723 Base::template space<0>()
3724 .reduce_continuity(1, 1)
3725 .reduce_continuity(1, 2)
3726 .reduce_continuity(1, 3);
3727 Base::template space<1>()
3728 .reduce_continuity(1, 0)
3729 .reduce_continuity(1, 2)
3730 .reduce_continuity(1, 3);
3731 Base::template space<2>()
3732 .reduce_continuity(1, 0)
3733 .reduce_continuity(1, 1)
3734 .reduce_continuity(1, 3);
3735 Base::template space<3>()
3736 .reduce_continuity(1, 0)
3737 .reduce_continuity(1, 1)
3738 .reduce_continuity(1, 2);
3741 NE(
const std::array<std::vector<typename Spline::value_type>,
3742 Spline::parDim()> &kv,
3746 : Base(kv, kv, kv, kv, kv,
init, options) {
3747 static_assert(Spline::is_nonuniform(),
3748 "NE function space requires non-uniform splines");
3749 Base::template space<0>()
3750 .reduce_continuity(1, 1)
3751 .reduce_continuity(1, 2)
3752 .reduce_continuity(1, 3);
3753 Base::template space<1>()
3754 .reduce_continuity(1, 0)
3755 .reduce_continuity(1, 2)
3756 .reduce_continuity(1, 3);
3757 Base::template space<2>()
3758 .reduce_continuity(1, 0)
3759 .reduce_continuity(1, 1)
3760 .reduce_continuity(1, 3);
3761 Base::template space<3>()
3762 .reduce_continuity(1, 0)
3763 .reduce_continuity(1, 1)
3764 .reduce_continuity(1, 2);
3774template <
typename Spline,
short_t = Spline::parDim()>
class RT;
3785template <
typename Spline>
3788 std::tuple<typename Spline::template derived_self_type<
3789 typename Spline::value_type, Spline::geoDim(),
3790 Spline::degree(0) + 1>,
3791 typename Spline::template derived_self_type<
3792 typename Spline::value_type, Spline::geoDim(),
3793 Spline::degree(0)>>> {
3797 typename Spline::template derived_self_type<
3798 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3799 typename Spline::template derived_self_type<
3800 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3807 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
3809 RT(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3813 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}}, kv,
init,
3815 static_assert(Spline::is_nonuniform(),
3816 "Constructor only available for non-uniform splines");
3834template <
typename Spline>
3837 std::tuple<typename Spline::template derived_self_type<
3838 typename Spline::value_type, Spline::geoDim(),
3839 Spline::degree(0) + 1, Spline::degree(1)>,
3840 typename Spline::template derived_self_type<
3841 typename Spline::value_type, Spline::geoDim(),
3842 Spline::degree(0), Spline::degree(1) + 1>,
3843 typename Spline::template derived_self_type<
3844 typename Spline::value_type, Spline::geoDim(),
3845 Spline::degree(0), Spline::degree(1)>>> {
3848 std::tuple<
typename Spline::template derived_self_type<
3849 typename Spline::value_type, Spline::geoDim(),
3850 Spline::degree(0) + 1, Spline::degree(1)>,
3851 typename Spline::template derived_self_type<
3852 typename Spline::value_type, Spline::geoDim(),
3853 Spline::degree(0), Spline::degree(1) + 1>,
3854 typename Spline::template derived_self_type<
3855 typename Spline::value_type, Spline::geoDim(),
3856 Spline::degree(0), Spline::degree(1)>>>;
3863 : Base(ncoeffs + utils::to_array(1_i64, 0_i64),
3864 ncoeffs + utils::to_array(0_i64, 1_i64), ncoeffs,
init, options) {}
3866 RT(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3870 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}},
3871 {{kv[0], kv[1].front() + kv[1] + kv[1].back()}}, kv,
init,
3873 static_assert(Spline::is_nonuniform(),
3874 "Constructor only available for non-uniform splines");
3892template <
typename Spline>
3895 typename Spline::template derived_self_type<
3896 typename Spline::value_type, Spline::geoDim(),
3897 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2)>,
3898 typename Spline::template derived_self_type<
3899 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3900 Spline::degree(1) + 1, Spline::degree(2)>,
3901 typename Spline::template derived_self_type<
3902 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3903 Spline::degree(1), Spline::degree(2) + 1>,
3904 typename Spline::template derived_self_type<
3905 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3906 Spline::degree(1), Spline::degree(2)>>> {
3910 typename Spline::template derived_self_type<
3911 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3912 Spline::degree(1), Spline::degree(2)>,
3913 typename Spline::template derived_self_type<
3914 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3915 Spline::degree(1) + 1, Spline::degree(2)>,
3916 typename Spline::template derived_self_type<
3917 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3918 Spline::degree(1), Spline::degree(2) + 1>,
3919 typename Spline::template derived_self_type<
3920 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3921 Spline::degree(1), Spline::degree(2)>>>;
3928 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
3929 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
3930 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64), ncoeffs,
init,
3933 RT(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3937 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
3938 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
3939 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}}, kv,
init,
3941 static_assert(Spline::is_nonuniform(),
3942 "Constructor only available for non-uniform splines");
3962template <
typename Spline>
3965 typename Spline::template derived_self_type<
3966 typename Spline::value_type, Spline::geoDim(),
3967 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2),
3969 typename Spline::template derived_self_type<
3970 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3971 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
3972 typename Spline::template derived_self_type<
3973 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3974 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
3975 typename Spline::template derived_self_type<
3976 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3977 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
3978 typename Spline::template derived_self_type<
3979 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3980 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3984 typename Spline::template derived_self_type<
3985 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3986 Spline::degree(1), Spline::degree(2), Spline::degree(3)>,
3987 typename Spline::template derived_self_type<
3988 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3989 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
3990 typename Spline::template derived_self_type<
3991 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3992 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
3993 typename Spline::template derived_self_type<
3994 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3995 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
3996 typename Spline::template derived_self_type<
3997 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3998 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
4005 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64, 0_i64),
4006 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64, 0_i64),
4007 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64, 0_i64),
4008 ncoeffs + utils::to_array(0_i64, 0_i64, 0_i64, 1_i64), ncoeffs,
4011 RT(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
4015 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2], kv[3]}},
4016 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2], kv[3]}},
4017 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back(), kv[3]}},
4018 {{kv[0], kv[1], kv[2], kv[3].front() + kv[3] + kv[3].back()}}, kv,
4020 static_assert(Spline::is_nonuniform(),
4021 "Constructor only available for non-uniform splines");
4031template <
typename Spline,
short_t = Spline::parDim()>
class Hcurl;
4044template <
typename Spline>
4047 typename Spline::template derived_self_type<
4048 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4049 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4050 typename Spline::template derived_self_type<
4051 typename Spline::value_type, Spline::geoDim(),
4052 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2) + 1>,
4053 typename Spline::template derived_self_type<
4054 typename Spline::value_type, Spline::geoDim(),
4055 Spline::degree(0) + 1, Spline::degree(1) + 1,
4056 Spline::degree(2)>>> {
4061 typename Spline::template derived_self_type<
4062 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4063 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4064 typename Spline::template derived_self_type<
4065 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4066 Spline::degree(1), Spline::degree(2) + 1>,
4067 typename Spline::template derived_self_type<
4068 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4069 Spline::degree(1) + 1, Spline::degree(2)>>>;
4076 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4077 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4078 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64),
init, options) {}
4080 Hcurl(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4084 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4085 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4086 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}},
init,
4088 static_assert(Spline::is_nonuniform(),
4089 "Constructor only available for non-uniform splines");
4098#undef IGANET_FUNCTIONSPACE_DEFAULT_OPS
#define GENERATE_IEXPR_MACRO(r, data, name)
Auto-generated functions.
Definition boundary.hpp:1777
#define GENERATE_EXPR_MACRO(r, data, name)
Definition boundary.hpp:1731
#define GENERATE_EXPR_SEQ
Sequence of expression (parametric coordinates)
Definition bspline.hpp:41
#define GENERATE_IEXPR_SEQ
Sequence of expression (physical coordinates)
Definition bspline.hpp:47
Boundary (common high-level functionality)
Definition boundary.hpp:1124
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Returns the knot indicies of knot spans containing xi
Definition boundary.hpp:1350
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:1312
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:1601
auto to(Options< real_t > options) const
Returns a copy of the boundary object with settings from options.
Definition boundary.hpp:1920
auto & from_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor.
Definition boundary.hpp:1202
torch::Tensor as_tensor() const
Returns all coefficients of all spline objects as a single tensor.
Definition boundary.hpp:1147
auto & uniform_refine(int numRefine=1, int dim=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition boundary.hpp:1432
int64_t as_tensor_size() const
Returns the size of the single tensor representation of all spline objects.
Definition boundary.hpp:1168
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:1570
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:4069
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:4073
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:4080
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:3494
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:3498
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:3503
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:3553
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:3549
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:3564
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:3627
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:3641
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:3623
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:3713
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:3741
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:3709
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:107
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:3800
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:3804
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:3809
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:3856
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:3860
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:3866
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:3921
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:3925
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:3933
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:3998
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:4002
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:4011
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:3182
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:3191
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:3178
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:3254
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:3239
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:3243
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:3321
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:3317
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:3335
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:3432
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:3416
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:3412
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:810
auto find_knot_indices(const utils::TensorArray< nspaces()> &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:632
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:651
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:580
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:257
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:1428
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:432
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:1857
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:790
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:886
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:960
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:248
pugi::xml_document to_xml(int id=0, std::string label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:370
auto & boundary() noexcept
Returns a non-constant reference to the index-th boundary object.
Definition functionspace.hpp:163
auto boundingBox() const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:910
FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:169
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:1138
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:1018
static constexpr std::size_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:139
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:759
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:1904
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:1842
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:193
torch::Tensor boundary_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:203
auto & space() noexcept
Returns a non-constant reference to the index-th space.
Definition functionspace.hpp:150
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:737
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:862
std::tuple< Boundaries... > boundary_type
Boundary type.
Definition functionspace.hpp:70
FunctionSpace(std::tuple< Splines... > &&spline, std::tuple< Boundaries... > &&boundary)
Constructor.
Definition functionspace.hpp:128
std::common_type_t< typename Splines::value_type... > value_type
Value type.
Definition functionspace.hpp:61
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:558
virtual FunctionSpace & from_tensor(const torch::Tensor &tensor)
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:349
auto clone() const noexcept
Returns a clone of a subset of the function space.
Definition functionspace.hpp:172
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:1131
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:879
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:748
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:310
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:687
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:1600
spline_type spline_
Splines.
Definition functionspace.hpp:77
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:322
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:473
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:1003
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:2063
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:331
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:728
auto scale_(std::index_sequence< Is... >, value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:819
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:667
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:360
auto boundingBox_(std::index_sequence< Is... >) const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:904
std::tuple< typename Boundaries::eval_type... > boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:73
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:404
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:1304
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:518
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:844
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:2044
auto eval(const std::tuple< Xi... > &xi) const
Returns the values of the spline objects in the points xi
Definition functionspace.hpp:495
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:1086
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:2036
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:1462
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:1188
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:102
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:771
FunctionSpace(std::tuple< Splines... > &&spline)
Constructor.
Definition functionspace.hpp:119
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:1270
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:229
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:781
std::tuple< utils::TensorArray< Splines::parDim()>... > eval_type
Spline evaluation type.
Definition functionspace.hpp:67
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:1435
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:540
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:799
nlohmann::json to_json_(std::index_sequence< Is... >) const
Serialization to JSON.
Definition functionspace.hpp:413
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:696
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:238
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:897
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:1165
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:710
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:2086
const auto & boundary() const noexcept
Returns a constant reference to the index-th boundary object.
Definition functionspace.hpp:156
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:94
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:379
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:1849
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:1032
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:220
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:1876
boundary_type boundary_
Boundaries.
Definition functionspace.hpp:80
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:1218
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:1443
const auto & space() const noexcept
Returns a constant reference to the index-th function space.
Definition functionspace.hpp:144
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:1948
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:934
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:457
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:638
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:1357
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:274
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:388
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:827
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:617
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:505
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:1146
FunctionSpace(const std::tuple< Splines... > &spline)
Constructor.
Definition functionspace.hpp:114
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:945
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &tensor)
Sets the tuple of boundaries from a single-tensor representation.
Definition functionspace.hpp:343
torch::Tensor spaces_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of spaces.
Definition functionspace.hpp:186
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &tensor)
Sets the tuple of spaces from a single-tensor representation.
Definition functionspace.hpp:301
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:1010
FunctionSpace & from_xml(const pugi::xml_document &doc, int id=0, std::string label="")
Updates the function space object from XML object.
Definition functionspace.hpp:398
auto scale_(std::index_sequence< Is... >, std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:834
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:1502
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:2029
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:1054
auto translate_(std::index_sequence< Is... >, std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:851
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:605
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:442
std::tuple< Splines... > spline_type
Spline type.
Definition functionspace.hpp:64
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:2116
FunctionSpace(const std::tuple< Splines... > &spline, const std::tuple< Boundaries... > &boundary)
Constructor.
Definition functionspace.hpp:124
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:1285
auto rotate_(std::index_sequence< Is... >, value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:869
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:210
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:1277
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:919
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:1327
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the function space object.
Definition functionspace.hpp:968
static constexpr std::size_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:134
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:592
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:267
Function space.
Definition functionspace.hpp:2406
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:2805
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:2783
FunctionSpace(const Spline &spline)
Constructor.
Definition functionspace.hpp:2460
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:2842
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:2443
auto eval_basfunc(const Args &...args) const
Returns the values of the spline objects' basis functions in the points xi
Definition functionspace.hpp:2755
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:2562
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:2768
constexpr const boundary_type & boundary() const noexcept
Returns a constant reference to the index-th boundary object.
Definition functionspace.hpp:2494
virtual torch::Tensor spaces_as_tensor() const noexcept
Returns a single-tensor representation of the space.
Definition functionspace.hpp:2527
typename Boundary::eval_type boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:2422
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:2882
virtual int64_t boundary_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the boundary.
Definition functionspace.hpp:2553
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the boundary.
Definition functionspace.hpp:2532
constexpr boundary_type & boundary() noexcept
Returns a non-constant reference to the index-th boundary object object.
Definition functionspace.hpp:2501
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:2835
Spline spline_type
Spline type.
Definition functionspace.hpp:2413
virtual int64_t spaces_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the space.
Definition functionspace.hpp:2547
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the function space object.
Definition functionspace.hpp:2891
auto find_knot_indices(const Xi &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:2734
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:2647
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:2872
FunctionSpace(Spline &&spline)
Constructor.
Definition functionspace.hpp:2466
constexpr spline_type & space() noexcept
Returns a non-constant reference to the index-th function space.
Definition functionspace.hpp:2487
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:2822
FunctionSpace & from_xml(const pugi::xml_document &doc, int id=0, std::string label="")
Updates the function space object from XML object.
Definition functionspace.hpp:2611
auto eval(const Arg &arg, const Args &...args) const
Returns the values of the spline object in the points xi
Definition functionspace.hpp:2693
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:2674
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:2617
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:2863
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:2605
static constexpr std::size_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:2474
constexpr FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:2507
auto find_knot_indices_(std::index_sequence< Is... >, const Xi &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:2723
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:2856
static constexpr std::size_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:2477
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:2849
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:2813
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:2660
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:2576
pugi::xml_document to_xml(int id=0, std::string label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:2596
FunctionSpace(FunctionSpace &&)=default
Move constructor.
typename Spline::value_type value_type
Value type.
Definition functionspace.hpp:2410
boundary_type boundary_
Boundary.
Definition functionspace.hpp:2429
utils::TensorArray< Spline::parDim()> eval_type
Spline evaluation type.
Definition functionspace.hpp:2416
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &coeffs) noexcept
Sets the space from a single-tensor representation.
Definition functionspace.hpp:2568
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &coeffs) noexcept
Sets the boundary from a single-tensor representation.
Definition functionspace.hpp:2583
FunctionSpace & transform(const std::function< std::array< typename Spline::value_type, Spline::geoDim()>(const std::array< typename Spline::value_type, Spline::parDim()> &)> transformation)
Transforms the coefficients based on the given mapping.
Definition functionspace.hpp:2632
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:2541
FunctionSpace(const FunctionSpace &)=default
Copy constructor.
spline_type spline_
Spline.
Definition functionspace.hpp:2426
auto eval_from_precomputed(const Args &...args) const
Returns the value of the spline object from precomputed basis function.
Definition functionspace.hpp:2712
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:2624
FunctionSpace & from_tensor(const torch::Tensor &coeffs) noexcept
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:2589
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:2451
constexpr const spline_type & space() const noexcept
Returns a constant reference to the index-th function space.
Definition functionspace.hpp:2481
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:2827
constexpr auto clone() const noexcept
Returns a subset of the tuple of function spaces.
Definition functionspace.hpp:2512
Full qualified name descriptor.
Definition fqn.hpp:26
virtual const std::string & name() const noexcept
Returns the full qualified name of the object.
Definition fqn.hpp:31
Concept to identify template parameters that are derived from iganet::details::FunctionSpaceType.
Definition functionspace.hpp:3118
Container utility functions.
#define IGANET_FUNCTIONSPACE_DEFAULT_OPS(FunctionSpace)
Macro: Implements the default methods of a function space.
Definition functionspace.hpp:36
typename FunctionSpace_trait< utils::tuple_cat_t< Splines... >, utils::tuple_cat_t< Boundaries... > >::type type
Definition functionspace.hpp:3111
typename FunctionSpace_trait< Spline, Boundary >::type type
Definition functionspace.hpp:3101
std::ostream & operator<<(std::ostream &os, const FunctionSpace< Splines... > &obj)
Print (as string) a function space object.
Definition functionspace.hpp:2392
Forward declaration.
Definition functionspace.hpp:3069
TensorArray< 4 > TensorArray4
Definition tensorarray.hpp:34
std::array< torch::Tensor, N > TensorArray
Definition tensorarray.hpp:28
auto zip(T &&...seqs)
Definition zip.hpp:97
TensorArray< 3 > TensorArray3
Definition tensorarray.hpp:33
typename tuple_cat< Tuples... >::type tuple_cat_t
Alias for tuple_cat::type.
Definition type_traits.hpp:72
TensorArray< 1 > TensorArray1
Definition tensorarray.hpp:31
TensorArray< 2 > TensorArray2
Definition tensorarray.hpp:32
Forward declaration of BlockTensor.
Definition blocktensor.hpp:46
Definition boundary.hpp:22
deriv
Enumerator for specifying the derivative of B-spline evaluation.
Definition bspline.hpp:74
BoundaryCommon< BoundaryCore< Spline, Spline::parDim()> > Boundary
Boundary.
Definition boundary.hpp:1958
struct iganet::@0 Log
Logger.
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:55
FunctionSpace< Spline > S
Spline function space .
Definition functionspace.hpp:3149
functionspace
Enumerator for the function space component.
Definition functionspace.hpp:30
@ none
Definition boundary.hpp:38
short int short_t
Definition core.hpp:74
typename detail::FunctionSpace_trait< Args... >::type FunctionSpace
Function space alias.
Definition functionspace.hpp:3122
std::ostream & operator<<(std::ostream &os, const Boundary< Spline > &obj)
Print (as string) a Boundary object.
Definition boundary.hpp:1963
IGANET_FUNCTIONSPACE_TUPLE_WRAPPER(RT);.
Definition functionspace.hpp:4031
IGANET_FUNCTIONSPACE_TUPLE_WRAPPER(TH);.
Definition functionspace.hpp:3468
IGANET_FUNCTIONSPACE_TUPLE_WRAPPER(NE);.
Definition functionspace.hpp:3774
Taylor-Hood like function space.
Definition functionspace.hpp:3152
Serialization prototype.
Definition serialize.hpp:31