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;
47 template <
typename Spline,
typename Boundary>
55 template <
typename... Splines,
typename... Boundaries>
62 using value_type = std::common_type_t<
typename Splines::value_type...>;
104 Splines::parDim()> &...kv,
110 static_assert((Splines::is_nonuniform() && ... &&
true),
111 "Constructor is only available for non-uniform splines");
126 const std::tuple<Boundaries...> &
boundary)
131 std::tuple<Boundaries...> &&
boundary)
138 return sizeof...(Splines);
143 return sizeof...(Boundaries);
147 template <
short_t s>
inline const auto &
space() const noexcept {
148 static_assert(s >= 0 && s <
nspaces());
153 template <
short_t s>
inline auto &
space() noexcept {
154 static_assert(s >= 0 && s <
nspaces());
159 template <
short_t s>
inline const auto &
boundary() const noexcept {
166 template <
short_t s>
inline auto &
boundary() noexcept {
177 static_assert(((s >= 0 && s <
nspaces()) && ... &&
true));
180 std::tuple<std::tuple_element_t<s, boundary_type>...>>(
181 std::make_tuple(std::get<s>(
spline_)...), std::make_tuple(std::get<s>(
boundary_)...));
187 template <std::size_t... Is>
190 return torch::cat({std::get<Is>(
spline_).as_tensor()...});
197 return spaces_as_tensor_(
198 std::make_index_sequence<FunctionSpace::nspaces()>{});
204 template <std::size_t... Is>
207 return torch::cat({std::get<Is>(
boundary_).as_tensor()...});
214 return boundary_as_tensor_(
215 std::make_index_sequence<FunctionSpace::nboundaries()>{});
223 virtual inline torch::Tensor
as_tensor() const noexcept {
230 template <std::size_t... Is>
234 [](
auto... v) {
return (v + ...); },
242 return spaces_as_tensor_size_(
243 std::make_index_sequence<FunctionSpace::nspaces()>{});
249 template <std::size_t... Is>
253 [](
auto... v) {
return (v + ...); },
261 return boundary_as_tensor_size_(
262 std::make_index_sequence<FunctionSpace::nboundaries()>{});
276 template <std::size_t... Is>
278 const torch::Tensor &tensor) {
281 std::array<int64_t,
sizeof...(Is)> partialSums{0};
282 auto partial_sums = [&partialSums,
283 this]<std::size_t... Js>(std::index_sequence<Js...>) {
284 ((std::get<Js + 1>(partialSums) =
285 std::get<Js>(partialSums) + std::get<Js>(
spline_).as_tensor_size()),
288 partial_sums(std::make_index_sequence<FunctionSpace::nspaces() - 1>{});
291 ((std::get<Is>(
spline_).from_tensor(tensor.index(
292 {torch::indexing::Slice(partialSums[Is],
294 std::get<Is>(spline_).as_tensor_size()),
305 return spaces_from_tensor_(
306 std::make_index_sequence<FunctionSpace::nspaces()>{}, tensor);
312 template <std::size_t... Is>
314 const torch::Tensor &tensor) {
326 return boundary_from_tensor_(
327 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
332 template <std::size_t... Is>
335 const torch::Tensor &tensor) {
336 (std::get<Is>(
boundary_).from_full_tensor(
347 return boundary_from_full_tensor_(
348 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
353 spaces_from_tensor_(std::make_index_sequence<FunctionSpace::nspaces()>{},
355 boundary_from_full_tensor_(
356 std::make_index_sequence<FunctionSpace::nboundaries()>{}, tensor);
362 template <std::size_t... Is>
363 inline pugi::xml_node &
to_xml_(std::index_sequence<Is...>,
364 pugi::xml_node &root,
int id = 0,
365 std::string label =
"")
const {
367 (std::get<Is>(
spline_).to_xml(root,
id, label, Is), ...);
373 inline pugi::xml_document
to_xml(
int id = 0, std::string label =
"")
const {
374 pugi::xml_document doc;
375 pugi::xml_node root = doc.append_child(
"xml");
382 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
383 std::string label =
"")
const {
384 return to_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
390 template <std::size_t... Is>
392 const pugi::xml_node &root,
int id = 0,
393 std::string label =
"") {
395 (std::get<Is>(
spline_).from_xml(root,
id, label, Is), ...);
402 std::string label =
"") {
403 return from_xml(doc.child(
"xml"),
id, label);
408 std::string label =
"") {
409 return from_xml_(std::make_index_sequence<FunctionSpace::nspaces()>{}, root,
415 template <std::size_t... Is>
416 nlohmann::json
to_json_(std::index_sequence<Is...>)
const {
417 auto json_this = nlohmann::json::array();
418 auto json_boundary = nlohmann::json::array();
420 (json_boundary.push_back(std::get<Is>(
boundary_).to_json()), ...);
422 auto json = nlohmann::json::array();
423 for (
auto [t, b] :
utils::zip(json_this, json_boundary)) {
424 auto json_inner = nlohmann::json::array();
425 json_inner.push_back(t);
426 json_inner.push_back(b);
427 json.push_back(json_inner);
436 return to_json_(std::make_index_sequence<FunctionSpace::nspaces()>{});
444 std::size_t... Is,
typename... Xi>
445 inline auto eval_(std::index_sequence<Is...>,
446 const std::tuple<Xi...> &xi)
const {
449 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
450 std::get<Is>(xi))...);
453 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
454 std::get<Is>(xi))...);
459 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
460 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
461 const std::tuple<Knot_Indices...> &knot_indices)
const {
464 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
465 std::get<Is>(xi), std::get<Is>(knot_indices))...);
468 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
469 std::get<Is>(xi), std::get<Is>(knot_indices))...);
474 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
475 typename... Coeff_Indices>
476 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
477 const std::tuple<Knot_Indices...> &knot_indices,
478 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
481 std::get<Is>(
spline_).template eval<deriv, memory_optimized>(
482 std::get<Is>(xi), std::get<Is>(knot_indices),
483 std::get<Is>(coeff_indices))...);
486 std::get<Is>(
boundary_).template eval<deriv, memory_optimized>(
487 std::get<Is>(xi), std::get<Is>(knot_indices),
488 std::get<Is>(coeff_indices))...);
498 inline auto eval(
const std::tuple<Xi...> &xi)
const {
499 static_assert(FunctionSpace::nspaces() ==
sizeof...(Xi),
500 "Size of Xi mismatches functionspace dimension");
501 return eval_<comp, deriv, memory_optimized>(
502 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
507 typename... Xi,
typename... Knot_Indices>
508 inline auto eval(
const std::tuple<Xi...> &xi,
509 const std::tuple<Knot_Indices...> &knot_indices)
const {
511 (FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
512 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)),
513 "Sizes of Xi and Knot_Indices mismatch functionspace dimension");
514 return eval_<comp, deriv, memory_optimized>(
515 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
520 typename... Xi,
typename... Knot_Indices,
typename... Coeff_Indices>
521 inline auto eval(
const std::tuple<Xi...> &xi,
522 const std::tuple<Knot_Indices...> &knot_indices,
523 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
524 static_assert((FunctionSpace::nspaces() ==
sizeof...(Xi)) &&
525 (FunctionSpace::nspaces() ==
sizeof...(Knot_Indices)) &&
526 (FunctionSpace::nspaces() ==
sizeof...(Coeff_Indices)),
527 "Sizes of Xi, Knot_Indices and Coeff_Indices mismatch "
528 "functionspace dimension");
529 return eval_<comp, deriv, memory_optimized>(
530 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices,
540 typename... Basfunc,
typename... Coeff_Indices,
typename... Numeval,
544 const std::tuple<Basfunc...> &basfunc,
545 const std::tuple<Coeff_Indices...> &coeff_indices,
546 const std::tuple<Numeval...> &numeval,
547 const std::tuple<Sizes...> &sizes)
const {
549 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
550 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
551 std::get<Is>(numeval), std::get<Is>(sizes))...);
553 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
554 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
555 std::get<Is>(numeval), std::get<Is>(sizes))...);
559 typename... Basfunc,
typename... Coeff_Indices,
typename... Xi>
562 const std::tuple<Basfunc...> &basfunc,
563 const std::tuple<Coeff_Indices...> &coeff_indices,
564 const std::tuple<Xi...> &xi)
const {
566 return std::tuple(std::get<Is>(
spline_).eval_from_precomputed(
567 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
568 std::get<Is>(xi)[0].numel(), std::get<Is>(xi)[0].sizes())...);
570 return std::tuple(std::get<Is>(
boundary_).eval_from_precomputed(
571 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
572 std::get<Is>(xi))...);
581 typename... Coeff_Indices,
typename... Numeval,
typename... Sizes>
584 const std::tuple<Coeff_Indices...> &coeff_indices,
585 const std::tuple<Numeval...> &numeval,
586 const std::tuple<Sizes...> &sizes)
const {
587 return eval_from_precomputed_<comp>(
588 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
589 coeff_indices, numeval, sizes);
593 typename... Coeff_Indices,
typename... Xi>
596 const std::tuple<Coeff_Indices...> &coeff_indices,
597 const std::tuple<Xi...> &xi)
const {
598 return eval_from_precomputed_<comp>(
599 std::make_index_sequence<FunctionSpace::nspaces()>{}, basfunc,
612 std::get<Is>(
spline_).find_knot_indices(xi)...);
615 std::get<Is>(
boundary_).find_knot_indices(xi)...);
621 const std::tuple<Xi...> &xi)
const {
624 std::get<Is>(
spline_).find_knot_indices(std::get<Is>(xi))...);
627 std::get<Is>(
boundary_).find_knot_indices(std::get<Is>(xi))...);
634 template <functionspace comp = functionspace::
interior>
636 return find_knot_indices_<comp>(
637 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
642 return find_knot_indices_<comp>(
643 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
653 std::size_t... Is,
typename... Xi>
655 const std::tuple<Xi...> &xi)
const {
658 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
659 std::get<Is>(xi))...);
661 return std::tuple(std::get<Is>(
boundary_)
662 .template eval_basfunc<deriv, memory_optimized>(
663 std::get<Is>(xi))...);
668 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
671 const std::tuple<Knot_Indices...> &knot_indices)
const {
674 std::get<Is>(
spline_).template eval_basfunc<deriv, memory_optimized>(
675 std::get<Is>(xi), std::get<Is>(knot_indices))...);
679 .template eval_basfunc<deriv, memory_optimized>(
680 std::get<Is>(xi), std::get<Is>(knot_indices))...);
691 return eval_basfunc_<comp, deriv, memory_optimized>(
692 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi);
697 typename... Xi,
typename... Knot_Indices>
700 const std::tuple<Knot_Indices...> &knot_indices)
const {
701 return eval_basfunc_<comp, deriv, memory_optimized>(
702 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, knot_indices);
710 bool memory_optimized =
false, std::size_t... Is,
711 typename... Knot_Indices>
714 const std::tuple<Knot_Indices...> &knot_indices)
const {
717 std::get<Is>(
spline_).template find_coeff_indices<memory_optimized>(
718 std::get<Is>(knot_indices))...);
721 std::get<Is>(
boundary_).template find_coeff_indices<memory_optimized>(
722 std::get<Is>(knot_indices))...);
729 bool memory_optimized =
false,
typename... Knot_Indices>
732 return find_coeff_indices_<comp, memory_optimized>(
733 std::make_index_sequence<FunctionSpace::nspaces()>{}, knot_indices);
739 template <std::size_t... Is, std::size_t... Js>
741 std::index_sequence<Js...>,
int numRefine = 1,
742 int dimRefine = -1) {
743 (std::get<Is>(
spline_).uniform_refine(numRefine, dimRefine), ...);
744 (std::get<Js>(
boundary_).uniform_refine(numRefine, dimRefine), ...);
752 return uniform_refine_(
753 std::make_index_sequence<FunctionSpace::nspaces()>{},
754 std::make_index_sequence<FunctionSpace::nboundaries()>{}, numRefine,
761 template <
typename real_t, std::size_t... Is, std::size_t... Js>
762 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
765 typename Splines::template real_derived_self_type<real_t>...,
766 typename Boundaries::template real_derived_self_type<real_t>...>(
767 std::get<Is>(
spline_).to(options)...,
775 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
776 std::make_index_sequence<FunctionSpace::nboundaries()>{},
783 template <std::size_t... Is, std::size_t... Js>
784 inline auto to_(std::index_sequence<Is...>, std::index_sequence<Js...>,
785 torch::Device device)
const {
793 inline auto to(torch::Device device)
const {
794 return to_(std::make_index_sequence<FunctionSpace::nspaces()>{},
795 std::make_index_sequence<FunctionSpace::nboundaries()>{},
801 template <
typename real_t, std::size_t... Is, std::size_t... Js>
802 inline auto to_(std::index_sequence<Is...>,
803 std::index_sequence<Js...>)
const {
805 typename Splines::template real_derived_self_type<real_t>...,
806 typename Boundaries::template real_derived_self_type<real_t>...>(
807 std::get<Is>(
spline_).template to<real_t>()...,
808 std::get<Js>(
boundary_).template to<real_t>()...);
813 template <
typename real_t>
inline auto to()
const {
815 std::make_index_sequence<FunctionSpace::nspaces()>{},
816 std::make_index_sequence<FunctionSpace::nboundaries()>{});
821 template <std::size_t... Is>
823 (std::get<Is>(
spline_).scale(s, dim), ...);
831 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, s, dim);
836 template <std::size_t N, std::size_t... Is>
837 inline auto scale_(std::index_sequence<Is...>, std::array<value_type, N> v) {
838 (std::get<Is>(
spline_).scale(v), ...);
839 (std::get<Is>(
boundary_).from_full_tensor(
847 template <
size_t N>
inline auto scale(std::array<value_type, N> v) {
848 return scale_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
853 template <std::size_t N, std::size_t... Is>
855 std::array<value_type, N> v) {
856 (std::get<Is>(
spline_).translate(v), ...);
857 (std::get<Is>(
boundary_).from_full_tensor(
865 template <
size_t N>
inline auto translate(std::array<value_type, N> v) {
866 return translate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, v);
871 template <std::size_t... Is>
873 (std::get<Is>(
spline_).rotate(angle), ...);
874 (std::get<Is>(
boundary_).from_full_tensor(
883 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
888 template <std::size_t... Is>
889 inline auto rotate_(std::index_sequence<Is...>,
890 std::array<value_type, 3> angle) {
891 (std::get<Is>(
spline_).rotate(angle), ...);
892 (std::get<Is>(
boundary_).from_full_tensor(
900 inline auto rotate(std::array<value_type, 3> angle) {
901 return rotate_(std::make_index_sequence<FunctionSpace::nspaces()>{}, angle);
906 template <std::size_t... Is>
908 return std::tuple(std::get<Is>(
spline_).boundingBox()...);
914 return boundingBox_(std::make_index_sequence<FunctionSpace::nspaces()>{});
920 template <std::size_t... Is>
921 inline torch::serialize::OutputArchive &
922 write_(std::index_sequence<Is...>, torch::serialize::OutputArchive &archive,
923 const std::string &key =
"functionspace")
const {
925 archive, key +
".fspace[" + std::to_string(Is) +
"].interior"),
928 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
936 inline torch::serialize::OutputArchive &
937 write(torch::serialize::OutputArchive &archive,
938 const std::string &key =
"functionspace")
const {
939 write_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
946 template <std::size_t... Is>
947 inline torch::serialize::InputArchive &
948 read_(std::index_sequence<Is...>, torch::serialize::InputArchive &archive,
949 const std::string &key =
"functionspace") {
950 (std::get<Is>(
spline_).read(archive, key +
".fspace[" + std::to_string(Is) +
954 archive, key +
".fspace[" + std::to_string(Is) +
"].boundary"),
962 inline torch::serialize::InputArchive &
963 read(torch::serialize::InputArchive &archive,
964 const std::string &key =
"functionspace") {
965 read_(std::make_index_sequence<FunctionSpace::nspaces()>{}, archive, key);
973 auto pretty_print_ = [
this,
974 &os]<std::size_t... Is>(std::index_sequence<Is...>) {
975 ((os <<
"\ninterior = ", std::get<Is>(
spline_).pretty_print(os),
976 os <<
"\nboundary = ", std::get<Is>(
boundary_).pretty_print(os)),
980 pretty_print_(std::make_index_sequence<
nspaces()>{});
1005 bool memory_optimized =
false>
1007 return curl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1011 bool memory_optimized =
false,
1012 typename... TensorArrays>
1014 const std::tuple<TensorArrays...> &knot_indices)
const {
1015 return curl<comp, memory_optimized>(xi, knot_indices,
1016 find_coeff_indices<comp>(knot_indices));
1020 bool memory_optimized =
false>
1022 const std::tuple<utils::TensorArray1> &knot_indices,
1023 const std::tuple<torch::Tensor> &coeff_indices)
const {
1025 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1027 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1033 bool memory_optimized =
false>
1036 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1037 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1039 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1040 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1041 xi[0].sizes() == xi[1].sizes());
1049 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1050 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1051 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1052 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1056 bool memory_optimized =
false>
1060 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1061 &coeff_indices)
const {
1063 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1064 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1065 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1066 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1072 *std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1073 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] -
1074 *std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1075 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1076 *std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1077 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] -
1078 *std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1079 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1080 *std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1081 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] -
1082 *std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1083 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1087 bool memory_optimized =
false>
1092 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1093 torch::Tensor> &coeff_indices)
const {
1095 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1096 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1097 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1098 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1099 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1100 xi[2].sizes() == xi[3].sizes());
1102 throw std::runtime_error(
"Unsupported parametric/geometric dimension");
1133 bool memory_optimized =
false>
1135 return div<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1139 bool memory_optimized =
false,
1140 typename... TensorArrays>
1142 const std::tuple<TensorArrays...> &knot_indices)
const {
1143 return div<comp, memory_optimized>(xi, knot_indices,
1144 find_coeff_indices<comp>(knot_indices));
1148 bool memory_optimized =
false>
1150 const std::tuple<utils::TensorArray1> &knot_indices,
1151 const std::tuple<torch::Tensor> &coeff_indices)
const {
1153 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1156 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1157 "div(.) for vector-valued spaces requires 1D variables");
1160 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1161 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1166 bool memory_optimized =
false>
1169 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1170 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1172 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1173 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1174 xi[0].sizes() == xi[1].sizes());
1177 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1178 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1179 "div(.) for vector-valued spaces requires 1D variables");
1182 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1183 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1184 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1185 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1190 bool memory_optimized =
false>
1194 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1195 &coeff_indices)
const {
1197 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1198 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1199 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1200 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1203 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1204 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1205 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1206 "div(.) for vector-valued spaces requires 1D variables");
1209 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1210 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1211 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1212 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1213 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1214 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1219 bool memory_optimized =
false>
1224 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1225 torch::Tensor> &coeff_indices)
const {
1227 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1228 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1229 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1230 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1231 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1232 xi[2].sizes() == xi[3].sizes());
1235 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1236 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1237 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1238 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1239 "div(.) for vector-valued spaces requires 1D variables");
1242 *std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1243 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
1244 *std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1245 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
1246 *std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1247 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
1248 *std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1249 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1272 bool memory_optimized =
false>
1274 return grad<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1278 bool memory_optimized =
false,
1279 typename... TensorArrays>
1281 const std::tuple<TensorArrays...> &knot_indices)
const {
1282 return grad<comp, memory_optimized>(xi, knot_indices,
1283 find_coeff_indices<comp>(knot_indices));
1287 bool memory_optimized =
false>
1289 const std::tuple<utils::TensorArray1> &knot_indices,
1290 const std::tuple<torch::Tensor> &coeff_indices)
const {
1292 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1295 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1296 "grad(.) for vector-valued spaces requires 1D variables");
1299 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1300 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1305 bool memory_optimized =
false>
1308 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1309 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1311 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1312 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1313 xi[0].sizes() == xi[1].sizes());
1316 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1317 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1318 "grad(.) for vector-valued spaces requires 1D variables");
1321 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1322 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1323 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1324 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1329 bool memory_optimized =
false>
1333 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1334 &coeff_indices)
const {
1336 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1337 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1338 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1339 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1342 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1343 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1344 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1345 "div(.) for vector-valued spaces requires 1D variables");
1348 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1349 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1350 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1351 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1352 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1353 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1358 bool memory_optimized =
false>
1363 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1364 torch::Tensor> &coeff_indices)
const {
1366 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1367 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1368 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1369 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1370 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1371 xi[2].sizes() == xi[3].sizes());
1374 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1375 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1376 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1377 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1378 "grad(.) for vector-valued spaces requires 1D variables");
1381 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1382 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1383 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1384 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1385 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1386 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1387 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
1388 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
1430 bool memory_optimized =
false>
1432 return hess<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1436 bool memory_optimized =
false,
1437 typename... TensorArrays>
1439 const std::tuple<TensorArrays...> &knot_indices)
const {
1440 return hess<comp, memory_optimized>(xi, knot_indices,
1441 find_coeff_indices<comp>(knot_indices));
1445 bool memory_optimized =
false>
1447 const std::tuple<utils::TensorArray1> &knot_indices,
1448 const std::tuple<torch::Tensor> &coeff_indices)
const {
1450 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1453 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1454 "hess(.) for vector-valued spaces requires 1D variables");
1457 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1458 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)));
1463 bool memory_optimized =
false>
1466 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1467 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1469 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1470 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1471 xi[0].sizes() == xi[1].sizes());
1474 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1475 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1476 "hess(.) for vector-valued spaces requires 1D variables");
1479 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1480 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1482 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1483 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1485 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1486 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1487 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1488 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1490 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1491 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1493 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1494 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1496 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1497 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1498 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1499 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)));
1504 bool memory_optimized =
false>
1508 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1509 &coeff_indices)
const {
1511 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1512 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1513 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1514 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1517 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1518 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1519 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1520 "hess(.) for vector-valued spaces requires 1D variables");
1523 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1524 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1526 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1527 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1529 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1530 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1532 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1533 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1534 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1535 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1537 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1538 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1540 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1541 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1543 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1544 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1545 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1546 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1548 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1549 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1551 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1552 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1554 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1555 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1557 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1558 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1559 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1560 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1562 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1563 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1565 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1566 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1568 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1569 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1570 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1571 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1573 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1574 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1576 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1577 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1579 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1580 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1582 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1583 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1584 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1585 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1587 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1588 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1590 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1591 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1593 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1594 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1595 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1596 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)));
1601 bool memory_optimized =
false>
1606 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1607 torch::Tensor> &coeff_indices)
const {
1609 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1610 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1611 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1612 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1613 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1614 xi[2].sizes() == xi[3].sizes());
1617 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1618 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1619 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
1620 std::tuple_element_t<3, spline_type>::geoDim() == 1,
1621 "hess(.) for vector-valued spaces requires 1D variables");
1624 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1625 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1627 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1628 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1630 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1631 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1633 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1634 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1636 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1637 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1638 std::get<0>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1639 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1641 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1642 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1644 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1645 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1647 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1648 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1650 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1651 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1652 std::get<0>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1653 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1655 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1656 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1658 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1659 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1661 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1662 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1664 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1665 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1666 std::get<0>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1667 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices)),
1669 std::get<1>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1670 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1672 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1673 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1675 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1676 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1678 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1679 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1681 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1682 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1683 std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1684 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1686 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1687 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1689 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1690 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1692 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1693 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1695 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1696 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1697 std::get<1>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1698 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1700 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1701 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1703 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1704 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1706 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1707 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1709 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1710 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1711 std::get<1>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1712 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices)),
1714 std::get<2>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1715 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1717 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1718 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1720 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1721 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1723 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1724 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1726 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1727 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1728 std::get<2>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1729 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1731 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1732 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1734 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1735 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1737 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1738 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1740 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1741 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1742 std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1743 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1745 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1746 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1748 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1749 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1751 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1752 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1754 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1755 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1756 std::get<2>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1757 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices)),
1759 std::get<3>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
1760 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1762 .
template eval<deriv::dx + deriv::dy, memory_optimized>(
1763 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1765 .
template eval<deriv::dx + deriv::dz, memory_optimized>(
1766 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1768 .
template eval<deriv::dx + deriv::dt, memory_optimized>(
1769 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1771 .
template eval<deriv::dy + deriv::dx, memory_optimized>(
1772 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1773 std::get<3>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
1774 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1776 .
template eval<deriv::dy + deriv::dz, memory_optimized>(
1777 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1779 .
template eval<deriv::dy + deriv::dt, memory_optimized>(
1780 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1782 .
template eval<deriv::dz + deriv::dx, memory_optimized>(
1783 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1785 .
template eval<deriv::dz + deriv::dy, memory_optimized>(
1786 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1787 std::get<3>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
1788 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1790 .
template eval<deriv::dz + deriv::dt, memory_optimized>(
1791 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1793 .
template eval<deriv::dt + deriv::dx, memory_optimized>(
1794 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1796 .
template eval<deriv::dt + deriv::dy, memory_optimized>(
1797 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1799 .
template eval<deriv::dt + deriv::dz, memory_optimized>(
1800 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)),
1801 std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
1802 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices)));
1844 bool memory_optimized =
false>
1846 return jac<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
1850 bool memory_optimized =
false,
1851 typename... TensorArrays>
1853 const std::tuple<TensorArrays...> &knot_indices)
const {
1854 return jac<comp, memory_optimized>(xi, knot_indices,
1855 find_coeff_indices<comp>(knot_indices));
1859 bool memory_optimized =
false>
1861 const std::tuple<utils::TensorArray1> &knot_indices,
1862 const std::tuple<torch::Tensor> &coeff_indices)
const {
1864 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
1867 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
1868 "jac(.) for vector-valued spaces requires 1D variables");
1871 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1872 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
1877 bool memory_optimized =
false>
1880 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
1881 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
1883 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1884 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1885 xi[0].sizes() == xi[1].sizes());
1888 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1889 std::tuple_element_t<1, spline_type>::geoDim() == 1,
1890 "jac(.) for vector-valued spaces requires 1D variables");
1893 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1894 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1895 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1896 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1898 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1899 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1900 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1901 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
1906 bool memory_optimized =
false>
1910 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
1911 &coeff_indices)
const {
1913 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1914 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1915 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1916 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
1919 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1920 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1921 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1922 "jac(.) for vector-valued spaces requires 1D variables");
1925 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1926 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1927 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1928 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1929 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1930 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1932 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1933 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1934 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1935 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1936 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1937 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1939 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1940 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1941 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1942 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1943 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1944 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
1949 bool memory_optimized =
false>
1954 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
1955 torch::Tensor> &coeff_indices)
const {
1957 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
1958 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
1959 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
1960 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
1961 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
1962 xi[2].sizes() == xi[3].sizes());
1965 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
1966 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
1967 std::tuple_element_t<2, spline_type>::geoDim() == 1,
1968 "jac(.) for vector-valued spaces requires 1D variables");
1971 std::get<0>(
spline_).
template eval<deriv::dx, memory_optimized>(
1972 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1973 std::get<0>(
spline_).
template eval<deriv::dy, memory_optimized>(
1974 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1975 std::get<0>(
spline_).
template eval<deriv::dz, memory_optimized>(
1976 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1977 std::get<0>(
spline_).
template eval<deriv::dt, memory_optimized>(
1978 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0],
1980 std::get<1>(
spline_).
template eval<deriv::dx, memory_optimized>(
1981 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1982 std::get<1>(
spline_).
template eval<deriv::dy, memory_optimized>(
1983 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1984 std::get<1>(
spline_).
template eval<deriv::dz, memory_optimized>(
1985 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1986 std::get<1>(
spline_).
template eval<deriv::dt, memory_optimized>(
1987 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0],
1989 std::get<2>(
spline_).
template eval<deriv::dx, memory_optimized>(
1990 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1991 std::get<2>(
spline_).
template eval<deriv::dy, memory_optimized>(
1992 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1993 std::get<2>(
spline_).
template eval<deriv::dz, memory_optimized>(
1994 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1995 std::get<2>(
spline_).
template eval<deriv::dt, memory_optimized>(
1996 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0],
1998 std::get<3>(
spline_).
template eval<deriv::dx, memory_optimized>(
1999 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2000 std::get<3>(
spline_).
template eval<deriv::dy, memory_optimized>(
2001 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2002 std::get<3>(
spline_).
template eval<deriv::dz, memory_optimized>(
2003 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0],
2004 std::get<3>(
spline_).
template eval<deriv::dt, memory_optimized>(
2005 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2031 bool memory_optimized =
false>
2033 return lapl<comp, memory_optimized>(xi, find_knot_indices<comp>(xi));
2037 bool memory_optimized =
false,
2038 typename... TensorArrays>
2040 const std::tuple<TensorArrays...> &knot_indices)
const {
2041 return lapl<comp, memory_optimized>(xi, knot_indices,
2042 find_coeff_indices<comp>(knot_indices));
2046 bool memory_optimized =
false>
2048 const std::tuple<utils::TensorArray1> &knot_indices,
2049 const std::tuple<torch::Tensor> &coeff_indices)
const {
2051 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes());
2054 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1,
2055 "lapl(.) for vector-valued spaces requires 1D variables");
2058 std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2059 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0]);
2064 bool memory_optimized =
false>
2067 const std::tuple<utils::TensorArray2, utils::TensorArray2> &knot_indices,
2068 const std::tuple<torch::Tensor, torch::Tensor> &coeff_indices)
const {
2070 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2071 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2072 xi[0].sizes() == xi[1].sizes());
2075 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2076 std::tuple_element_t<1, spline_type>::geoDim() == 1,
2077 "lapl(.) for vector-valued spaces requires 1D variables");
2080 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2081 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2082 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2083 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0]);
2088 bool memory_optimized =
false>
2092 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor>
2093 &coeff_indices)
const {
2095 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2096 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2097 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2098 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes());
2101 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2102 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2103 std::tuple_element_t<2, spline_type>::geoDim() == 1,
2104 "div(.) for vector-valued spaces requires 1D variables");
2107 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2108 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2109 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2110 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2111 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2112 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0]);
2117 bool memory_optimized =
false>
2122 const std::tuple<torch::Tensor, torch::Tensor, torch::Tensor,
2123 torch::Tensor> &coeff_indices)
const {
2125 assert(xi[0].sizes() == std::get<0>(knot_indices)[0].sizes() &&
2126 xi[1].sizes() == std::get<1>(knot_indices)[0].sizes() &&
2127 xi[2].sizes() == std::get<2>(knot_indices)[0].sizes() &&
2128 xi[3].sizes() == std::get<3>(knot_indices)[0].sizes() &&
2129 xi[0].sizes() == xi[1].sizes() && xi[1].sizes() == xi[2].sizes() &&
2130 xi[2].sizes() == xi[3].sizes());
2133 static_assert(std::tuple_element_t<0, spline_type>::geoDim() == 1 &&
2134 std::tuple_element_t<1, spline_type>::geoDim() == 1 &&
2135 std::tuple_element_t<2, spline_type>::geoDim() == 1 &&
2136 std::tuple_element_t<3, spline_type>::geoDim() == 1,
2137 "div(.) for vector-valued spaces requires 1D variables");
2140 *std::get<0>(
spline_).
template eval<deriv::dx ^ 2, memory_optimized>(
2141 xi, std::get<0>(knot_indices), std::get<0>(coeff_indices))[0] +
2142 *std::get<1>(
spline_).
template eval<deriv::dy ^ 2, memory_optimized>(
2143 xi, std::get<1>(knot_indices), std::get<1>(coeff_indices))[0] +
2144 *std::get<2>(
spline_).
template eval<deriv::dz ^ 2, memory_optimized>(
2145 xi, std::get<2>(knot_indices), std::get<2>(coeff_indices))[0] +
2146 *std::get<3>(
spline_).
template eval<deriv::dt ^ 2, memory_optimized>(
2147 xi, std::get<3>(knot_indices), std::get<3>(coeff_indices))[0]);
2152#define GENERATE_EXPR_MACRO(r, data, name) \
2154 template <functionspace comp = functionspace::interior, \
2155 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
2156 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2157 const std::tuple<Xi...> &xi) const { \
2158 if constexpr (comp == functionspace::interior) \
2159 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2160 std::get<Is>(xi))...); \
2161 else if constexpr (comp == functionspace::boundary) \
2162 return std::tuple( \
2163 std::get<Is>(boundary_).template name<memory_optimized>( \
2164 std::get<Is>(xi))...); \
2167 template <functionspace comp = functionspace::interior, \
2168 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2169 typename... Knot_Indices> \
2170 inline auto BOOST_PP_CAT(name, _all_)( \
2171 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2172 const std::tuple<Knot_Indices...> &knot_indices) const { \
2173 if constexpr (comp == functionspace::interior) \
2174 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2175 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2176 else if constexpr (comp == functionspace::boundary) \
2177 return std::tuple( \
2178 std::get<Is>(boundary_).template name<memory_optimized>( \
2179 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2182 template <functionspace comp = functionspace::interior, \
2183 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2184 typename... Knot_Indices, typename... Coeff_Indices> \
2185 inline auto BOOST_PP_CAT(name, _all_)( \
2186 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2187 const std::tuple<Knot_Indices...> &knot_indices, \
2188 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
2189 if constexpr (comp == functionspace::interior) \
2190 return std::tuple(std::get<Is>(spline_).template name<memory_optimized>( \
2191 std::get<Is>(xi), std::get<Is>(knot_indices), \
2192 std::get<Is>(coeff_indices))...); \
2193 else if constexpr (comp == functionspace::boundary) \
2194 return std::tuple( \
2195 std::get<Is>(boundary_).template name<memory_optimized>( \
2196 std::get<Is>(xi), std::get<Is>(knot_indices), \
2197 std::get<Is>(coeff_indices))...); \
2200 template <functionspace comp = functionspace::interior, \
2201 bool memory_optimized = false, std::size_t... Is, std::size_t N> \
2202 inline auto BOOST_PP_CAT(name, _)(std::index_sequence<Is...>, \
2203 const utils::TensorArray<N> &xi) const { \
2204 if constexpr (comp == functionspace::interior) \
2205 return name<comp, memory_optimized>( \
2206 xi, std::tuple(std::get<Is>(spline_).find_knot_indices(xi)...)); \
2207 else if constexpr (comp == functionspace::boundary) \
2208 return name<comp, memory_optimized>( \
2209 xi, std::tuple(std::get<Is>(boundary_).find_knot_indices(xi)...)); \
2212 template <functionspace comp = functionspace::interior, \
2213 bool memory_optimized = false, std::size_t... Is, std::size_t N, \
2214 typename... Knot_Indices> \
2215 inline auto BOOST_PP_CAT(name, _)( \
2216 std::index_sequence<Is...>, const utils::TensorArray<N> &xi, \
2217 const std::tuple<Knot_Indices...> &knot_indices) const { \
2218 if constexpr (comp == functionspace::interior) \
2219 return name<comp, memory_optimized>( \
2221 std::tuple(std::get<Is>(spline_).find_coeff_indices( \
2222 std::get<Is>(knot_indices))...)); \
2223 else if constexpr (comp == functionspace::boundary) \
2224 return name<comp, memory_optimized>( \
2226 std::tuple(std::get<Is>(boundary_).find_coeff_indices( \
2227 std::get<Is>(knot_indices))...)); \
2231 template <functionspace comp = functionspace::interior, \
2232 bool memory_optimized = false, typename... Args> \
2233 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2234 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2235 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2238 template <functionspace comp = functionspace::interior, \
2239 bool memory_optimized = false> \
2240 inline auto name(const torch::Tensor &xi) const { \
2241 return name<comp, memory_optimized>(utils::TensorArray1({xi})); \
2244 template <functionspace comp = functionspace::interior, \
2245 bool memory_optimized = false, std::size_t N> \
2246 inline auto name(const utils::TensorArray<N> &xi) const { \
2247 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2248 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi); \
2251 template <functionspace comp = functionspace::interior, \
2252 bool memory_optimized = false, std::size_t N, \
2253 typename... Knot_Indices> \
2254 inline auto name(const utils::TensorArray<N> &xi, \
2255 const std::tuple<Knot_Indices...> &knot_indices) const { \
2256 return BOOST_PP_CAT(name, _)<comp, memory_optimized>( \
2257 std::make_index_sequence<FunctionSpace::nspaces()>{}, xi, \
2265#undef GENERATE_EXPR_MACRO
2267#define GENERATE_IEXPR_MACRO(r, data, name) \
2269 template <functionspace comp = functionspace::interior, \
2270 bool memory_optimized = false, std::size_t... Is, \
2271 typename Geometry, typename... Xi> \
2272 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2273 const Geometry &G, \
2274 const std::tuple<Xi...> &xi) const { \
2275 if constexpr (comp == functionspace::interior) { \
2276 if constexpr (Geometry::nspaces() == 1) \
2277 return std::tuple( \
2278 std::get<Is>(spline_).template name<memory_optimized>( \
2279 G.space(), std::get<Is>(xi))...); \
2280 else if constexpr (Geometry::nspaces() == nspaces()) \
2281 return std::tuple( \
2282 std::get<Is>(spline_).template name<memory_optimized>( \
2283 G.template space<Is>(), std::get<Is>(xi))...); \
2284 } else if constexpr (comp == functionspace::boundary) { \
2285 if constexpr (Geometry::nboundaries() == 1) \
2286 return std::tuple( \
2287 std::get<Is>(boundary_).template name<memory_optimized>( \
2288 static_cast<typename Geometry::boundary_type::boundary_type>( \
2289 G.boundary().coeffs()), \
2290 std::get<Is>(xi))...); \
2291 else if constexpr (Geometry::nboundaries() == nboundaries()) \
2292 return std::tuple( \
2293 std::get<Is>(boundary_).template name<memory_optimized>( \
2294 G.template boundary<Is>().coeffs(), std::get<Is>(xi))...); \
2298 template <functionspace comp = functionspace::interior, \
2299 bool memory_optimized = false, std::size_t... Is, \
2300 typename Geometry, typename... Xi, typename... Knot_Indices, \
2301 typename... Knot_Indices_G> \
2302 inline auto BOOST_PP_CAT(name, _all_)( \
2303 std::index_sequence<Is...>, const Geometry &G, \
2304 const std::tuple<Xi...> &xi, \
2305 const std::tuple<Knot_Indices...> &knot_indices, \
2306 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
2307 if constexpr (comp == functionspace::interior) { \
2308 if constexpr (Geometry::nspaces() == 1) \
2309 return std::tuple( \
2310 std::get<Is>(spline_).template name<memory_optimized>( \
2311 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2312 std::get<Is>(knot_indices_G))...); \
2314 return std::tuple( \
2315 std::get<Is>(spline_).template name<memory_optimized>( \
2316 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2317 std::get<Is>(knot_indices_G))...); \
2318 } else if constexpr (comp == functionspace::boundary) { \
2319 if constexpr (Geometry::nspaces() == 1) \
2320 return std::tuple( \
2321 std::get<Is>(boundary_).template name<memory_optimized>( \
2322 static_cast<typename Geometry::boundary_type::boundary_type>( \
2323 G.boundary().coeffs()), \
2324 std::get<Is>(xi), std::get<Is>(knot_indices), \
2325 std::get<Is>(knot_indices_G))...); \
2327 return std::tuple( \
2328 std::get<Is>(boundary_).template name<memory_optimized>( \
2329 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2330 std::get<Is>(knot_indices), std::get<Is>(knot_indices_G))...); \
2334 template <functionspace comp = functionspace::interior, \
2335 bool memory_optimized = false, std::size_t... Is, \
2336 typename Geometry, typename... Xi, typename... Knot_Indices, \
2337 typename... Coeff_Indices, typename... Knot_Indices_G, \
2338 typename... Coeff_Indices_G> \
2339 inline auto BOOST_PP_CAT(name, _all_)( \
2340 std::index_sequence<Is...>, const Geometry &G, \
2341 const std::tuple<Xi...> &xi, \
2342 const std::tuple<Knot_Indices...> &knot_indices, \
2343 const std::tuple<Coeff_Indices...> &coeff_indices, \
2344 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
2345 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
2346 if constexpr (comp == functionspace::interior) { \
2347 if constexpr (Geometry::nspaces() == 1) \
2348 return std::tuple( \
2349 std::get<Is>(spline_).template name<memory_optimized>( \
2350 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
2351 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2352 std::get<Is>(coeff_indices_G))...); \
2354 return std::tuple( \
2355 std::get<Is>(spline_).template name<memory_optimized>( \
2356 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(knot_indices), \
2357 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2358 std::get<Is>(coeff_indices_G))...); \
2359 } else if constexpr (comp == functionspace::boundary) { \
2360 if constexpr (Geometry::nspaces() == 1) \
2361 return std::tuple( \
2362 std::get<Is>(boundary_).template name<memory_optimized>( \
2363 static_cast<typename Geometry::boundary_type::boundary_type>( \
2364 G.boundary().coeffs()), \
2365 std::get<Is>(xi), std::get<Is>(knot_indices), \
2366 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
2367 std::get<Is>(coeff_indices_G))...); \
2369 return std::tuple( \
2370 std::get<Is>(boundary_).template name<memory_optimized>( \
2371 std::get<Is>(G).boundary().coeffs(), std::get<Is>(xi), \
2372 std::get<Is>(knot_indices), std::get<Is>(coeff_indices), \
2373 std::get<Is>(knot_indices_G), \
2374 std::get<Is>(coeff_indices_G))...); \
2379 template <functionspace comp = functionspace::interior, \
2380 bool memory_optimized = false, typename... Args> \
2381 inline auto BOOST_PP_CAT(name, _all)(const Args &...args) const { \
2382 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2383 std::make_index_sequence<FunctionSpace::nspaces()>{}, args...); \
2390#undef GENERATE_IEXPR_MACRO
2394template <
typename... Splines>
2405 template <
typename Spline,
typename Boundary>
2458 static_assert(Spline::is_nonuniform(),
2459 "Constructor is only available for non-uniform splines");
2483 template <
short_t s = 0>
2485 static_assert(s >= 0 && s <
nspaces());
2491 static_assert(s >= 0 && s <
nspaces());
2496 template <
short_t s = 0>
2517 static_assert(((s >= 0 && s <
nspaces()) && ... &&
true));
2519 if constexpr (
sizeof...(s) == 1)
2523 std::tuple<std::tuple_element_t<s, std::tuple<spline_type>>...>,
2524 std::tuple<std::tuple_element_t<s, std::tuple<boundary_type>>...>>(
2525 std::get<s>(std::make_tuple(
spline_))...,
2526 std::get<s>(std::make_tuple(
boundary_))...);
2551 return spline_.as_tensor_size();
2599 inline pugi::xml_document
to_xml(
int id = 0, std::string label =
"")
const {
2600 pugi::xml_document doc;
2601 pugi::xml_node root = doc.append_child(
"xml");
2608 inline pugi::xml_node &
to_xml(pugi::xml_node &root,
int id = 0,
2609 std::string label =
"")
const {
2610 return spline_.to_xml(root,
id, label);
2615 std::string label =
"") {
2616 return from_xml(doc.child(
"xml"),
id, label);
2621 std::string label =
"") {
2628 auto json = nlohmann::json::array();
2629 json.push_back(
spline_.to_json());
2636 const std::function<std::array<
typename Spline::value_type,
2638 const std::array<
typename Spline::value_type, Spline::parDim()> &)>
2649 std::size_t... Is,
typename... Xi>
2650 inline auto eval_(std::index_sequence<Is...>,
2651 const std::tuple<Xi...> &xi)
const {
2654 spline_.template eval<deriv, memory_optimized>(std::get<Is>(xi))...);
2656 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2657 std::get<Is>(xi))...);
2662 std::size_t... Is,
typename... Xi,
typename... Knot_Indices>
2663 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
2664 const std::tuple<Knot_Indices...> &knot_indices)
const {
2666 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
2667 std::get<Is>(xi), std::get<Is>(knot_indices))...);
2669 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2670 std::get<Is>(xi), std::get<Is>(knot_indices))...);
2675 std::size_t... Is,
typename... Xi,
typename... Knot_Indices,
2676 typename... Coeff_Indices>
2677 inline auto eval_(std::index_sequence<Is...>,
const std::tuple<Xi...> &xi,
2678 const std::tuple<Knot_Indices...> &knot_indices,
2679 const std::tuple<Coeff_Indices...> &coeff_indices)
const {
2681 return std::tuple(
spline_.template eval<deriv, memory_optimized>(
2682 std::get<Is>(xi), std::get<Is>(knot_indices),
2683 std::get<Is>(coeff_indices))...);
2685 return std::tuple(
boundary_.template eval<deriv, memory_optimized>(
2686 std::get<Is>(xi), std::get<Is>(knot_indices),
2687 std::get<Is>(coeff_indices))...);
2695 typename Arg,
typename... Args>
2696 inline auto eval(
const Arg &arg,
const Args &...args)
const {
2698 if constexpr (utils::is_tuple_v<Arg>)
2699 return eval_<comp, deriv, memory_optimized>(
2700 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
2702 return spline_.template eval<deriv, memory_optimized>(arg, args...);
2704 if constexpr (utils::is_tuple_of_tuples_v<Arg>)
2705 return eval_<comp, deriv, memory_optimized>(
2706 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...);
2708 return boundary_.template eval<deriv, memory_optimized>(arg, args...);
2717 return spline_.eval_from_precomputed(args...);
2727 const Xi &xi)
const {
2729 return std::tuple(
spline_.find_knot_indices(std::get<Is>(xi))...);
2736 template <functionspace comp = functionspace::
interior,
typename Xi>
2739 if constexpr (utils::is_tuple_v<Xi>)
2740 return find_knot_indices_<comp>(
2741 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
2743 return spline_.find_knot_indices(xi);
2745 if constexpr (utils::is_tuple_of_tuples_v<Xi>)
2746 return find_knot_indices_<comp>(
2747 std::make_index_sequence<std::tuple_size_v<Xi>>{}, xi);
2760 return spline_.template eval_basfunc<deriv, memory_optimized>(args...);
2762 return boundary_.template eval_basfunc<deriv, memory_optimized>(args...);
2769 bool memory_optimized =
false, std::size_t... Is,
2770 typename Knot_Indices>
2772 const Knot_Indices &knot_indices)
const {
2774 return std::tuple(
spline_.template find_coeff_indices<memory_optimized>(
2775 std::get<Is>(knot_indices))...);
2777 return std::tuple(
boundary_.template find_coeff_indices<memory_optimized>(
2778 std::get<Is>(knot_indices))...);
2785 bool memory_optimized =
false,
typename Knot_Indices>
2788 if constexpr (utils::is_tuple_v<Knot_Indices>)
2789 return find_coeff_indices_<comp, memory_optimized>(
2790 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
2793 return spline_.template find_coeff_indices<memory_optimized>(
2796 if constexpr (utils::is_tuple_of_tuples_v<Knot_Indices>)
2797 return find_coeff_indices_<comp, memory_optimized>(
2798 std::make_index_sequence<std::tuple_size_v<Knot_Indices>>{},
2801 return boundary_.template find_coeff_indices<memory_optimized>(
2809 spline_.uniform_refine(numRefine, dimRefine);
2818 typename spline_type::template real_derived_self_type<real_t>,
2819 typename boundary_type::template real_derived_self_type<real_t>>(
2825 inline auto to(torch::Device device)
const {
2830 template <
typename real_t>
inline auto to()
const {
2832 typename spline_type::template real_derived_self_type<real_t>,
2833 typename boundary_type::template real_derived_self_type<real_t>>(
2845 template <
size_t N>
inline auto scale(std::array<value_type, N> v) {
2852 template <
size_t N>
inline auto translate(std::array<value_type, N> v) {
2866 inline auto rotate(std::array<value_type, 3> angle) {
2874 inline torch::serialize::OutputArchive &
2875 write(torch::serialize::OutputArchive &archive,
2876 const std::string &key =
"functionspace")
const {
2884 inline torch::serialize::InputArchive &
2885 read(torch::serialize::InputArchive &archive,
2886 const std::string &key =
"functionspace") {
2895 os <<
name() <<
"(\nspline = ";
2897 os <<
"\nboundary = ";
2902#define GENERATE_EXPR_MACRO(r, data, name) \
2904 template <functionspace comp = functionspace::interior, \
2905 bool memory_optimized = false, std::size_t... Is, typename... Xi> \
2906 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2907 const std::tuple<Xi...> &xi) const { \
2908 if constexpr (comp == functionspace::interior) \
2909 return std::tuple( \
2910 spline_.template name<memory_optimized>(std::get<Is>(xi))...); \
2911 else if constexpr (comp == functionspace::boundary) \
2912 return std::tuple( \
2913 boundary_.template name<memory_optimized>(std::get<Is>(xi))...); \
2916 template <functionspace comp = functionspace::interior, \
2917 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2918 typename... Knot_Indices> \
2919 inline auto BOOST_PP_CAT(name, _all_)( \
2920 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2921 const std::tuple<Knot_Indices...> &knot_indices) const { \
2922 if constexpr (comp == functionspace::interior) \
2923 return std::tuple(spline_.template name<memory_optimized>( \
2924 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2925 else if constexpr (comp == functionspace::boundary) \
2926 return std::tuple(boundary_.template name<memory_optimized>( \
2927 std::get<Is>(xi), std::get<Is>(knot_indices))...); \
2930 template <functionspace comp = functionspace::interior, \
2931 bool memory_optimized = false, std::size_t... Is, typename... Xi, \
2932 typename... Knot_Indices, typename... Coeff_Indices> \
2933 inline auto BOOST_PP_CAT(name, _all_)( \
2934 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
2935 const std::tuple<Knot_Indices...> &knot_indices, \
2936 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
2937 if constexpr (comp == functionspace::interior) \
2938 return std::tuple(spline_.template name<memory_optimized>( \
2939 std::get<Is>(xi), std::get<Is>(knot_indices), \
2940 std::get<Is>(coeff_indices))...); \
2941 else if constexpr (comp == functionspace::boundary) \
2942 return std::tuple(boundary_.template name<memory_optimized>( \
2943 std::get<Is>(xi), std::get<Is>(knot_indices), \
2944 std::get<Is>(coeff_indices))...); \
2948 template <functionspace comp = functionspace::interior, \
2949 bool memory_optimized = false, typename Arg, typename... Args> \
2950 inline auto name(const Arg &arg, const Args &...args) const { \
2951 if constexpr (comp == functionspace::interior) \
2952 if constexpr (utils::is_tuple_v<Arg>) \
2953 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2954 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
2956 return spline_.template name<memory_optimized>(arg, args...); \
2957 else if constexpr (comp == functionspace::boundary) { \
2958 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
2959 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
2960 std::make_index_sequence<std::tuple_size_v<Arg>>{}, arg, args...); \
2962 return boundary_.template name<memory_optimized>(arg, args...); \
2970#undef GENERATE_EXPR_MACRO
2972#define GENERATE_IEXPR_MACRO(r, data, name) \
2974 template <functionspace comp = functionspace::interior, \
2975 bool memory_optimized = false, std::size_t... Is, \
2976 typename Geometry, typename... Xi> \
2977 inline auto BOOST_PP_CAT(name, _all_)(std::index_sequence<Is...>, \
2978 const Geometry &G, \
2979 const std::tuple<Xi...> &xi) const { \
2980 if constexpr (comp == functionspace::interior) \
2981 return std::tuple(spline_.template name<memory_optimized>( \
2982 G.space(), std::get<Is>(xi))...); \
2983 else if constexpr (comp == functionspace::boundary) \
2984 return std::tuple(boundary_.template name<memory_optimized>( \
2985 static_cast<typename Geometry::boundary_type::boundary_type>( \
2986 G.boundary().coeffs()), \
2987 std::get<Is>(xi))...); \
2990 template <functionspace comp = functionspace::interior, \
2991 bool memory_optimized = false, std::size_t... Is, \
2992 typename Geometry, typename... Xi, typename... Knot_Indices, \
2993 typename... Knot_Indices_G> \
2994 inline auto BOOST_PP_CAT(name, _all_)( \
2995 std::index_sequence<Is...>, const Geometry &G, \
2996 const std::tuple<Xi...> &xi, \
2997 const std::tuple<Knot_Indices...> &knot_indices, \
2998 const std::tuple<Knot_Indices_G...> &knot_indices_G) const { \
2999 if constexpr (comp == functionspace::interior) \
3000 return std::tuple(spline_.template name<memory_optimized>( \
3001 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
3002 std::get<Is>(knot_indices_G))...); \
3003 else if constexpr (comp == functionspace::boundary) \
3004 return std::tuple(boundary_.template name<memory_optimized>( \
3005 static_cast<typename Geometry::boundary_type::boundary_type>( \
3006 G.boundary().coeffs()), \
3007 std::get<Is>(xi), std::get<Is>(knot_indices), \
3008 std::get<Is>(knot_indices_G))...); \
3011 template <functionspace comp = functionspace::interior, \
3012 bool memory_optimized = false, std::size_t... Is, \
3013 typename Geometry, typename... Xi, typename... Knot_Indices, \
3014 typename... Coeff_Indices, typename... Knot_Indices_G, \
3015 typename... Coeff_Indices_G> \
3016 inline auto BOOST_PP_CAT(name, _all_)( \
3017 std::index_sequence<Is...>, const Geometry &G, \
3018 const std::tuple<Xi...> &xi, \
3019 const std::tuple<Knot_Indices...> &knot_indices, \
3020 const std::tuple<Coeff_Indices...> &coeff_indices, \
3021 const std::tuple<Knot_Indices_G...> &knot_indices_G, \
3022 const std::tuple<Coeff_Indices_G...> &coeff_indices_G) const { \
3023 if constexpr (comp == functionspace::interior) \
3024 return std::tuple(spline_.template name<memory_optimized>( \
3025 G.space(), std::get<Is>(xi), std::get<Is>(knot_indices), \
3026 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3027 std::get<Is>(coeff_indices_G))...); \
3028 else if constexpr (comp == functionspace::boundary) \
3029 return std::tuple(boundary_.template name<memory_optimized>( \
3030 static_cast<typename Geometry::boundary_type::boundary_type>( \
3031 G.boundary().coeffs()), \
3032 std::get<Is>(xi), std::get<Is>(knot_indices), \
3033 std::get<Is>(coeff_indices), std::get<Is>(knot_indices_G), \
3034 std::get<Is>(coeff_indices_G))...); \
3038 template <functionspace comp = functionspace::interior, \
3039 bool memory_optimized = false, typename Geometry, typename Arg, \
3041 inline auto name(const Geometry &G, const Arg &arg, const Args &...args) \
3043 if constexpr (comp == functionspace::interior) { \
3044 if constexpr (utils::is_tuple_v<Arg>) \
3045 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3046 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3049 return spline_.template name<memory_optimized>(G.space(), arg, \
3051 } else if constexpr (comp == functionspace::boundary) { \
3052 if constexpr (utils::is_tuple_of_tuples_v<Arg>) \
3053 return BOOST_PP_CAT(name, _all_)<comp, memory_optimized>( \
3054 std::make_index_sequence<std::tuple_size_v<Arg>>{}, G, arg, \
3057 return boundary_.template name<memory_optimized>( \
3058 static_cast<typename Geometry::boundary_type::boundary_type>( \
3059 G.boundary().coeffs()), \
3068#undef GENERATE_IEXPR_MACRO
3080template <
typename Spline,
typename Boundary>
3086template <
typename... Splines>
3093template <
typename... Splines,
typename... Boundaries>
3100template <
typename Spline,
typename Boundary>
3106template <
typename... Splines,
typename... Boundaries>
3116 template<
typename T>
3120template <
typename... Args>
3124template <
typename Splines,
typename Boundaries>
3127 obj.pretty_print(os);
3151template <
typename Spline,
short_t = Spline::parDim()>
class TH;
3162template <
typename Spline>
3165 std::tuple<typename Spline::template derived_self_type<
3166 typename Spline::value_type, Spline::geoDim(),
3167 Spline::degree(0) + 1>,
3168 typename Spline::template derived_self_type<
3169 typename Spline::value_type, Spline::geoDim(),
3170 Spline::degree(0)>>> {
3174 typename Spline::template derived_self_type<
3175 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3176 typename Spline::template derived_self_type<
3177 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3184 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {
3185 static_assert(Spline::is_nonuniform(),
3186 "TH function space requires non-uniform splines");
3187 Base::template space<0>().reduce_continuity();
3190 TH(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3194 : Base({{kv[0].front + kv[0] + kv[0].back(), kv[1]}}, kv,
init, options) {
3195 static_assert(Spline::is_nonuniform(),
3196 "TH function space requires non-uniform splines");
3197 Base::template space<0>().reduce_continuity();
3215template <
typename Spline>
3218 std::tuple<typename Spline::template derived_self_type<
3219 typename Spline::value_type, Spline::geoDim(),
3220 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3221 typename Spline::template derived_self_type<
3222 typename Spline::value_type, Spline::geoDim(),
3223 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3224 typename Spline::template derived_self_type<
3225 typename Spline::value_type, Spline::geoDim(),
3226 Spline::degree(0), Spline::degree(1)>>> {
3230 std::tuple<
typename Spline::template derived_self_type<
3231 typename Spline::value_type, Spline::geoDim(),
3232 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3233 typename Spline::template derived_self_type<
3234 typename Spline::value_type, Spline::geoDim(),
3235 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3236 typename Spline::template derived_self_type<
3237 typename Spline::value_type, Spline::geoDim(),
3238 Spline::degree(0), Spline::degree(1)>>>;
3245 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
3246 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
3247 static_assert(Spline::is_nonuniform(),
3248 "TH function space requires non-uniform splines");
3249 Base::template space<0>().reduce_continuity();
3250 Base::template space<1>().reduce_continuity();
3253 TH(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3257 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3258 kv[1].front() + kv[1] + kv[1].back()}},
3259 {{kv[0].front() + kv[0] + kv[0].back(),
3260 kv[1].front() + kv[1] + kv[1].back()}},
3261 kv,
init, options) {
3262 static_assert(Spline::is_nonuniform(),
3263 "TH function space requires non-uniform splines");
3264 Base::template space<0>().reduce_continuity();
3265 Base::template space<1>().reduce_continuity();
3284template <
typename Spline>
3287 typename Spline::template derived_self_type<
3288 typename Spline::value_type, Spline::geoDim(),
3289 Spline::degree(0) + 1, Spline::degree(1) + 1,
3290 Spline::degree(2) + 1>,
3291 typename Spline::template derived_self_type<
3292 typename Spline::value_type, Spline::geoDim(),
3293 Spline::degree(0) + 1, Spline::degree(1) + 1,
3294 Spline::degree(2) + 1>,
3295 typename Spline::template derived_self_type<
3296 typename Spline::value_type, Spline::geoDim(),
3297 Spline::degree(0) + 1, Spline::degree(1) + 1,
3298 Spline::degree(2) + 1>,
3299 typename Spline::template derived_self_type<
3300 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3301 Spline::degree(1), Spline::degree(2)>>> {
3305 typename Spline::template derived_self_type<
3306 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3307 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3308 typename Spline::template derived_self_type<
3309 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3310 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3311 typename Spline::template derived_self_type<
3312 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3313 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3314 typename Spline::template derived_self_type<
3315 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3316 Spline::degree(1), Spline::degree(2)>>>;
3323 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3324 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3325 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
3327 static_assert(Spline::is_nonuniform(),
3328 "TH function space requires non-uniform splines");
3329 Base::template space<0>().reduce_continuity();
3330 Base::template space<1>().reduce_continuity();
3331 Base::template space<2>().reduce_continuity();
3334 TH(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3338 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3339 kv[1].front() + kv[1] + kv[1].back(),
3340 kv[2].front() + kv[2] + kv[2].back()}},
3341 {{kv[0].front() + kv[0] + kv[0].back(),
3342 kv[1].front() + kv[1] + kv[1].back(),
3343 kv[2].front() + kv[2] + kv[2].back()}},
3344 {{kv[0].front() + kv[0] + kv[0].back(),
3345 kv[1].front() + kv[1] + kv[1].back(),
3346 kv[2].front() + kv[2] + kv[2].back()}},
3347 kv,
init, options) {
3348 static_assert(Spline::is_nonuniform(),
3349 "TH function space requires non-uniform splines");
3350 Base::template space<0>().reduce_continuity();
3351 Base::template space<1>().reduce_continuity();
3352 Base::template space<2>().reduce_continuity();
3372template <
typename Spline>
3375 typename Spline::template derived_self_type<
3376 typename Spline::value_type, Spline::geoDim(),
3377 Spline::degree(0) + 1, Spline::degree(1) + 1,
3378 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3379 typename Spline::template derived_self_type<
3380 typename Spline::value_type, Spline::geoDim(),
3381 Spline::degree(0) + 1, Spline::degree(1) + 1,
3382 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3383 typename Spline::template derived_self_type<
3384 typename Spline::value_type, Spline::geoDim(),
3385 Spline::degree(0) + 1, Spline::degree(1) + 1,
3386 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3387 typename Spline::template derived_self_type<
3388 typename Spline::value_type, Spline::geoDim(),
3389 Spline::degree(0) + 1, Spline::degree(1) + 1,
3390 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3391 typename Spline::template derived_self_type<
3392 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3393 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3397 typename Spline::template derived_self_type<
3398 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3399 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3400 typename Spline::template derived_self_type<
3401 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3402 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3403 typename Spline::template derived_self_type<
3404 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3405 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3406 typename Spline::template derived_self_type<
3407 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3408 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3409 typename Spline::template derived_self_type<
3410 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3411 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
3418 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3419 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), ncoeffs,
3423 static_assert(Spline::is_nonuniform(),
3424 "TH function space requires non-uniform splines");
3425 Base::template space<0>().reduce_continuity();
3426 Base::template space<1>().reduce_continuity();
3427 Base::template space<2>().reduce_continuity();
3428 Base::template space<3>().reduce_continuity();
3431 TH(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
3435 : Base({{kv[0].front() + kv[0] + kv[0].back(),
3436 kv[1].front() + kv[1] + kv[1].back(),
3437 kv[2].front() + kv[2] + kv[2].back(),
3438 kv[3].front() + kv[3] + kv[3].back()}},
3439 {{kv[0].front() + kv[0] + kv[0].back(),
3440 kv[1].front() + kv[1] + kv[1].back(),
3441 kv[2].front() + kv[2] + kv[2].back(),
3442 kv[3].front() + kv[3] + kv[3].back()}},
3443 {{kv[0].front() + kv[0] + kv[0].back(),
3444 kv[1].front() + kv[1] + kv[1].back(),
3445 kv[2].front() + kv[2] + kv[2].back(),
3446 kv[3].front() + kv[3] + kv[3].back()}},
3447 {{kv[0].front() + kv[0] + kv[0].back(),
3448 kv[1].front() + kv[1] + kv[1].back(),
3449 kv[2].front() + kv[2] + kv[2].back(),
3450 kv[3].front() + kv[3] + kv[3].back()}},
3451 kv,
init, options) {
3452 static_assert(Spline::is_nonuniform(),
3453 "TH function space requires non-uniform splines");
3454 Base::template space<0>().reduce_continuity();
3455 Base::template space<1>().reduce_continuity();
3456 Base::template space<2>().reduce_continuity();
3457 Base::template space<3>().reduce_continuity();
3467template <
typename Spline,
short_t = Spline::parDim()>
class NE;
3478template <
typename Spline>
3481 std::tuple<typename Spline::template derived_self_type<
3482 typename Spline::value_type, Spline::geoDim(),
3483 Spline::degree(0) + 1>,
3484 typename Spline::template derived_self_type<
3485 typename Spline::value_type, Spline::geoDim(),
3486 Spline::degree(0)>>> {
3490 typename Spline::template derived_self_type<
3491 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3492 typename Spline::template derived_self_type<
3493 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3500 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
3502 NE(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3506 : Base(kv, kv,
init, options) {
3507 static_assert(Spline::is_nonuniform(),
3508 "Constructor only available for non-uniform splines");
3525template <
typename Spline>
3528 std::tuple<typename Spline::template derived_self_type<
3529 typename Spline::value_type, Spline::geoDim(),
3530 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3531 typename Spline::template derived_self_type<
3532 typename Spline::value_type, Spline::geoDim(),
3533 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3534 typename Spline::template derived_self_type<
3535 typename Spline::value_type, Spline::geoDim(),
3536 Spline::degree(0), Spline::degree(1)>>> {
3540 std::tuple<
typename Spline::template derived_self_type<
3541 typename Spline::value_type, Spline::geoDim(),
3542 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3543 typename Spline::template derived_self_type<
3544 typename Spline::value_type, Spline::geoDim(),
3545 Spline::degree(0) + 1, Spline::degree(1) + 1>,
3546 typename Spline::template derived_self_type<
3547 typename Spline::value_type, Spline::geoDim(),
3548 Spline::degree(0), Spline::degree(1)>>>;
3555 : Base(ncoeffs + utils::to_array(1_i64, 1_i64),
3556 ncoeffs + utils::to_array(1_i64, 1_i64), ncoeffs,
init, options) {
3557 static_assert(Spline::is_nonuniform(),
3558 "NE function space requires non-uniform splines");
3559 Base::template space<0>().reduce_continuity(1, 1);
3560 Base::template space<1>().reduce_continuity(1, 0);
3563 NE(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3567 : Base(kv, kv, kv,
init, options) {
3568 static_assert(Spline::is_nonuniform(),
3569 "NE function space requires non-uniform splines");
3570 Base::template space<0>().reduce_continuity(1, 1);
3571 Base::template space<1>().reduce_continuity(1, 0);
3590template <
typename Spline>
3593 typename Spline::template derived_self_type<
3594 typename Spline::value_type, Spline::geoDim(),
3595 Spline::degree(0) + 1, Spline::degree(1) + 1,
3596 Spline::degree(2) + 1>,
3597 typename Spline::template derived_self_type<
3598 typename Spline::value_type, Spline::geoDim(),
3599 Spline::degree(0) + 1, Spline::degree(1) + 1,
3600 Spline::degree(2) + 1>,
3601 typename Spline::template derived_self_type<
3602 typename Spline::value_type, Spline::geoDim(),
3603 Spline::degree(0) + 1, Spline::degree(1) + 1,
3604 Spline::degree(2) + 1>,
3605 typename Spline::template derived_self_type<
3606 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3607 Spline::degree(1), Spline::degree(2)>>> {
3611 typename Spline::template derived_self_type<
3612 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3613 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3614 typename Spline::template derived_self_type<
3615 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3616 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3617 typename Spline::template derived_self_type<
3618 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3619 Spline::degree(1) + 1, Spline::degree(2) + 1>,
3620 typename Spline::template derived_self_type<
3621 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3622 Spline::degree(1), Spline::degree(2)>>>;
3629 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3630 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64),
3631 ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64), ncoeffs,
init,
3633 static_assert(Spline::is_nonuniform(),
3634 "NE function space requires non-uniform splines");
3635 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
3636 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
3637 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
3640 NE(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3644 : Base(kv, kv, kv, kv,
init, options) {
3645 static_assert(Spline::is_nonuniform(),
3646 "NE function space requires non-uniform splines");
3647 Base::template space<0>().reduce_continuity(1, 1).reduce_continuity(1, 2);
3648 Base::template space<1>().reduce_continuity(1, 0).reduce_continuity(1, 2);
3649 Base::template space<2>().reduce_continuity(1, 0).reduce_continuity(1, 1);
3669template <
typename Spline>
3672 typename Spline::template derived_self_type<
3673 typename Spline::value_type, Spline::geoDim(),
3674 Spline::degree(0) + 1, Spline::degree(1) + 1,
3675 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3676 typename Spline::template derived_self_type<
3677 typename Spline::value_type, Spline::geoDim(),
3678 Spline::degree(0) + 1, Spline::degree(1) + 1,
3679 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3680 typename Spline::template derived_self_type<
3681 typename Spline::value_type, Spline::geoDim(),
3682 Spline::degree(0) + 1, Spline::degree(1) + 1,
3683 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3684 typename Spline::template derived_self_type<
3685 typename Spline::value_type, Spline::geoDim(),
3686 Spline::degree(0) + 1, Spline::degree(1) + 1,
3687 Spline::degree(2) + 1, Spline::degree(3) + 1>,
3688 typename Spline::template derived_self_type<
3689 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3690 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3694 typename Spline::template derived_self_type<
3695 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3696 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3697 typename Spline::template derived_self_type<
3698 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3699 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3700 typename Spline::template derived_self_type<
3701 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3702 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3703 typename Spline::template derived_self_type<
3704 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3705 Spline::degree(1) + 1, Spline::degree(2) + 1, Spline::degree(3) + 1>,
3706 typename Spline::template derived_self_type<
3707 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3708 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
3715 : Base(ncoeffs + utils::to_array(1_i64, 1_i64, 1_i64, 1_i64),
3716 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), ncoeffs,
3720 static_assert(Spline::is_nonuniform(),
3721 "NE function space requires non-uniform splines");
3722 Base::template space<0>()
3723 .reduce_continuity(1, 1)
3724 .reduce_continuity(1, 2)
3725 .reduce_continuity(1, 3);
3726 Base::template space<1>()
3727 .reduce_continuity(1, 0)
3728 .reduce_continuity(1, 2)
3729 .reduce_continuity(1, 3);
3730 Base::template space<2>()
3731 .reduce_continuity(1, 0)
3732 .reduce_continuity(1, 1)
3733 .reduce_continuity(1, 3);
3734 Base::template space<3>()
3735 .reduce_continuity(1, 0)
3736 .reduce_continuity(1, 1)
3737 .reduce_continuity(1, 2);
3740 NE(
const std::array<std::vector<typename Spline::value_type>,
3741 Spline::parDim()> &kv,
3745 : Base(kv, kv, kv, kv, kv,
init, options) {
3746 static_assert(Spline::is_nonuniform(),
3747 "NE function space requires non-uniform splines");
3748 Base::template space<0>()
3749 .reduce_continuity(1, 1)
3750 .reduce_continuity(1, 2)
3751 .reduce_continuity(1, 3);
3752 Base::template space<1>()
3753 .reduce_continuity(1, 0)
3754 .reduce_continuity(1, 2)
3755 .reduce_continuity(1, 3);
3756 Base::template space<2>()
3757 .reduce_continuity(1, 0)
3758 .reduce_continuity(1, 1)
3759 .reduce_continuity(1, 3);
3760 Base::template space<3>()
3761 .reduce_continuity(1, 0)
3762 .reduce_continuity(1, 1)
3763 .reduce_continuity(1, 2);
3773template <
typename Spline,
short_t = Spline::parDim()>
class RT;
3784template <
typename Spline>
3787 std::tuple<typename Spline::template derived_self_type<
3788 typename Spline::value_type, Spline::geoDim(),
3789 Spline::degree(0) + 1>,
3790 typename Spline::template derived_self_type<
3791 typename Spline::value_type, Spline::geoDim(),
3792 Spline::degree(0)>>> {
3796 typename Spline::template derived_self_type<
3797 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1>,
3798 typename Spline::template derived_self_type<
3799 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>>;
3806 : Base(ncoeffs + utils::to_array(1_i64), ncoeffs,
init, options) {}
3808 RT(
const std::array<std::vector<typename Spline::value_type>, 1> &kv,
3812 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}}, kv,
init,
3814 static_assert(Spline::is_nonuniform(),
3815 "Constructor only available for non-uniform splines");
3833template <
typename Spline>
3836 std::tuple<typename Spline::template derived_self_type<
3837 typename Spline::value_type, Spline::geoDim(),
3838 Spline::degree(0) + 1, Spline::degree(1)>,
3839 typename Spline::template derived_self_type<
3840 typename Spline::value_type, Spline::geoDim(),
3841 Spline::degree(0), Spline::degree(1) + 1>,
3842 typename Spline::template derived_self_type<
3843 typename Spline::value_type, Spline::geoDim(),
3844 Spline::degree(0), Spline::degree(1)>>> {
3847 std::tuple<
typename Spline::template derived_self_type<
3848 typename Spline::value_type, Spline::geoDim(),
3849 Spline::degree(0) + 1, Spline::degree(1)>,
3850 typename Spline::template derived_self_type<
3851 typename Spline::value_type, Spline::geoDim(),
3852 Spline::degree(0), Spline::degree(1) + 1>,
3853 typename Spline::template derived_self_type<
3854 typename Spline::value_type, Spline::geoDim(),
3855 Spline::degree(0), Spline::degree(1)>>>;
3862 : Base(ncoeffs + utils::to_array(1_i64, 0_i64),
3863 ncoeffs + utils::to_array(0_i64, 1_i64), ncoeffs,
init, options) {}
3865 RT(
const std::array<std::vector<typename Spline::value_type>, 2> &kv,
3869 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1]}},
3870 {{kv[0], kv[1].front() + kv[1] + kv[1].back()}}, kv,
init,
3872 static_assert(Spline::is_nonuniform(),
3873 "Constructor only available for non-uniform splines");
3891template <
typename Spline>
3894 typename Spline::template derived_self_type<
3895 typename Spline::value_type, Spline::geoDim(),
3896 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2)>,
3897 typename Spline::template derived_self_type<
3898 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3899 Spline::degree(1) + 1, Spline::degree(2)>,
3900 typename Spline::template derived_self_type<
3901 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3902 Spline::degree(1), Spline::degree(2) + 1>,
3903 typename Spline::template derived_self_type<
3904 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3905 Spline::degree(1), Spline::degree(2)>>> {
3909 typename Spline::template derived_self_type<
3910 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3911 Spline::degree(1), Spline::degree(2)>,
3912 typename Spline::template derived_self_type<
3913 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3914 Spline::degree(1) + 1, Spline::degree(2)>,
3915 typename Spline::template derived_self_type<
3916 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3917 Spline::degree(1), Spline::degree(2) + 1>,
3918 typename Spline::template derived_self_type<
3919 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3920 Spline::degree(1), Spline::degree(2)>>>;
3927 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
3928 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
3929 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64), ncoeffs,
init,
3932 RT(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
3936 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
3937 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
3938 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}}, kv,
init,
3940 static_assert(Spline::is_nonuniform(),
3941 "Constructor only available for non-uniform splines");
3961template <
typename Spline>
3964 typename Spline::template derived_self_type<
3965 typename Spline::value_type, Spline::geoDim(),
3966 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2),
3968 typename Spline::template derived_self_type<
3969 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3970 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
3971 typename Spline::template derived_self_type<
3972 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3973 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
3974 typename Spline::template derived_self_type<
3975 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3976 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
3977 typename Spline::template derived_self_type<
3978 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3979 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>> {
3983 typename Spline::template derived_self_type<
3984 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
3985 Spline::degree(1), Spline::degree(2), Spline::degree(3)>,
3986 typename Spline::template derived_self_type<
3987 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3988 Spline::degree(1) + 1, Spline::degree(2), Spline::degree(3)>,
3989 typename Spline::template derived_self_type<
3990 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3991 Spline::degree(1), Spline::degree(2) + 1, Spline::degree(3)>,
3992 typename Spline::template derived_self_type<
3993 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3994 Spline::degree(1), Spline::degree(2), Spline::degree(3) + 1>,
3995 typename Spline::template derived_self_type<
3996 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
3997 Spline::degree(1), Spline::degree(2), Spline::degree(3)>>>;
4004 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64, 0_i64),
4005 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64, 0_i64),
4006 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64, 0_i64),
4007 ncoeffs + utils::to_array(0_i64, 0_i64, 0_i64, 1_i64), ncoeffs,
4010 RT(
const std::array<std::vector<typename Spline::value_type>, 4> &kv,
4014 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2], kv[3]}},
4015 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2], kv[3]}},
4016 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back(), kv[3]}},
4017 {{kv[0], kv[1], kv[2], kv[3].front() + kv[3] + kv[3].back()}}, kv,
4019 static_assert(Spline::is_nonuniform(),
4020 "Constructor only available for non-uniform splines");
4030template <
typename Spline,
short_t = Spline::parDim()>
class Hcurl;
4043template <
typename Spline>
4046 typename Spline::template derived_self_type<
4047 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4048 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4049 typename Spline::template derived_self_type<
4050 typename Spline::value_type, Spline::geoDim(),
4051 Spline::degree(0) + 1, Spline::degree(1), Spline::degree(2) + 1>,
4052 typename Spline::template derived_self_type<
4053 typename Spline::value_type, Spline::geoDim(),
4054 Spline::degree(0) + 1, Spline::degree(1) + 1,
4055 Spline::degree(2)>>> {
4060 typename Spline::template derived_self_type<
4061 typename Spline::value_type, Spline::geoDim(), Spline::degree(0),
4062 Spline::degree(1) + 1, Spline::degree(2) + 1>,
4063 typename Spline::template derived_self_type<
4064 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4065 Spline::degree(1), Spline::degree(2) + 1>,
4066 typename Spline::template derived_self_type<
4067 typename Spline::value_type, Spline::geoDim(), Spline::degree(0) + 1,
4068 Spline::degree(1) + 1, Spline::degree(2)>>>;
4075 : Base(ncoeffs + utils::to_array(1_i64, 0_i64, 0_i64),
4076 ncoeffs + utils::to_array(0_i64, 1_i64, 0_i64),
4077 ncoeffs + utils::to_array(0_i64, 0_i64, 1_i64),
init, options) {}
4079 Hcurl(
const std::array<std::vector<typename Spline::value_type>, 3> &kv,
4083 : Base({{kv[0].front() + kv[0] + kv[0].back(), kv[1], kv[2]}},
4084 {{kv[0], kv[1].front() + kv[1] + kv[1].back(), kv[2]}},
4085 {{kv[0], kv[1], kv[2].front() + kv[2] + kv[2].back()}},
init,
4087 static_assert(Spline::is_nonuniform(),
4088 "Constructor only available for non-uniform splines");
4097#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:4068
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:4072
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:4079
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:3493
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:3497
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:3502
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:3552
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:3548
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:3563
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:3626
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:3640
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:3622
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:3712
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:3740
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:3708
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:3799
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:3803
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:3808
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:3855
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:3859
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:3865
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:3920
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:3924
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:3932
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:3997
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:4001
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:4010
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:3181
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:3190
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:3177
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:3253
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:3238
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:3242
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:3320
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:3316
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:3334
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:3431
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:3415
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:3411
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:813
auto find_knot_indices(const utils::TensorArray< nspaces()> &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:635
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:654
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:583
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:260
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:1431
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:435
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:1860
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:793
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:889
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:963
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:251
pugi::xml_document to_xml(int id=0, std::string label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:373
auto & boundary() noexcept
Returns a non-constant reference to the -th boundary object.
Definition functionspace.hpp:166
auto boundingBox() const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:913
FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:172
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:1141
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:1021
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:762
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:1907
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:1845
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:196
torch::Tensor boundary_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:206
auto & space() noexcept
Returns a non-constant reference to the -th space.
Definition functionspace.hpp:153
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:740
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:865
std::tuple< Boundaries... > boundary_type
Boundary type.
Definition functionspace.hpp:71
FunctionSpace(std::tuple< Splines... > &&spline, std::tuple< Boundaries... > &&boundary)
Constructor.
Definition functionspace.hpp:130
std::common_type_t< typename Splines::value_type... > value_type
Value type.
Definition functionspace.hpp:62
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:561
virtual FunctionSpace & from_tensor(const torch::Tensor &tensor)
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:352
auto clone() const noexcept
Returns a clone of a subset of the function space.
Definition functionspace.hpp:175
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:1134
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:882
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:751
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:313
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:690
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:1603
spline_type spline_
Splines.
Definition functionspace.hpp:78
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:325
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:476
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:1006
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:2066
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:334
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:731
auto scale_(std::index_sequence< Is... >, value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:822
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:670
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:363
auto boundingBox_(std::index_sequence< Is... >) const
Computes the bounding boxes of the function space object.
Definition functionspace.hpp:907
std::tuple< typename Boundaries::eval_type... > boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:74
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:407
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:1307
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:521
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:847
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:2047
auto eval(const std::tuple< Xi... > &xi) const
Returns the values of the spline objects in the points xi
Definition functionspace.hpp:498
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:1089
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:2039
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:1465
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:1191
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:103
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:774
FunctionSpace(std::tuple< Splines... > &&spline)
Constructor.
Definition functionspace.hpp:120
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:1273
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:232
static constexpr short_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:142
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:784
std::tuple< utils::TensorArray< Splines::parDim()>... > eval_type
Spline evaluation type.
Definition functionspace.hpp:68
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:1438
static constexpr short_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:137
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:543
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:802
nlohmann::json to_json_(std::index_sequence< Is... >) const
Serialization to JSON.
Definition functionspace.hpp:416
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:699
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:241
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:900
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:1168
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:713
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:2089
const auto & boundary() const noexcept
Returns a constant reference to the -th boundary object.
Definition functionspace.hpp:159
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:95
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:382
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:1852
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:1035
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:223
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:1879
boundary_type boundary_
Boundaries.
Definition functionspace.hpp:81
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:1221
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:1446
const auto & space() const noexcept
Returns a constant reference to the -th function space.
Definition functionspace.hpp:147
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:1951
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:937
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:460
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:641
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:1360
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:277
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:391
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:830
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:620
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:508
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:1149
FunctionSpace(const std::tuple< Splines... > &spline)
Constructor.
Definition functionspace.hpp:115
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:948
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &tensor)
Sets the tuple of boundaries from a single-tensor representation.
Definition functionspace.hpp:346
torch::Tensor spaces_as_tensor_(std::index_sequence< Is... >) const noexcept
Returns a single-tensor representation of the tuple of spaces.
Definition functionspace.hpp:189
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &tensor)
Sets the tuple of spaces from a single-tensor representation.
Definition functionspace.hpp:304
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:1013
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:401
auto scale_(std::index_sequence< Is... >, std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:837
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:1505
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:2032
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:1057
auto translate_(std::index_sequence< Is... >, std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:854
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:608
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:445
std::tuple< Splines... > spline_type
Spline type.
Definition functionspace.hpp:65
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:2119
FunctionSpace(const std::tuple< Splines... > &spline, const std::tuple< Boundaries... > &boundary)
Constructor.
Definition functionspace.hpp:125
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:1288
auto rotate_(std::index_sequence< Is... >, value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:872
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the tuple of boundaries.
Definition functionspace.hpp:213
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:1280
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:922
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:1330
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:971
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:595
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:270
Function space.
Definition functionspace.hpp:2409
auto & uniform_refine(int numRefine=1, int dimRefine=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition functionspace.hpp:2808
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:2786
FunctionSpace(const Spline &spline)
Constructor.
Definition functionspace.hpp:2463
auto scale(std::array< value_type, N > v)
Scales the function space object by a vector.
Definition functionspace.hpp:2845
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:2446
auto eval_basfunc(const Args &...args) const
Returns the values of the spline objects' basis functions in the points xi
Definition functionspace.hpp:2758
static constexpr short_t nspaces() noexcept
Returns the number of function spaces.
Definition functionspace.hpp:2477
virtual int64_t as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the function space object.
Definition functionspace.hpp:2565
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:2771
constexpr const boundary_type & boundary() const noexcept
Returns a constant reference to the -th boundary object.
Definition functionspace.hpp:2497
virtual torch::Tensor spaces_as_tensor() const noexcept
Returns a single-tensor representation of the space.
Definition functionspace.hpp:2530
typename Boundary::eval_type boundary_eval_type
Boundary evaluation type.
Definition functionspace.hpp:2425
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:2885
virtual int64_t boundary_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the boundary.
Definition functionspace.hpp:2556
virtual torch::Tensor boundary_as_tensor() const noexcept
Returns a single-tensor representation of the boundary.
Definition functionspace.hpp:2535
constexpr boundary_type & boundary() noexcept
Returns a non-constant reference to the -th boundary object object.
Definition functionspace.hpp:2504
auto scale(value_type s, int dim=-1)
Scales the function space object by a scalar.
Definition functionspace.hpp:2838
Spline spline_type
Spline type.
Definition functionspace.hpp:2416
virtual int64_t spaces_as_tensor_size() const noexcept
Returns the size of the single-tensor representation of the space.
Definition functionspace.hpp:2550
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:2894
auto find_knot_indices(const Xi &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:2737
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:2650
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:2875
FunctionSpace(Spline &&spline)
Constructor.
Definition functionspace.hpp:2469
constexpr spline_type & space() noexcept
Returns a non-constant reference to the -th function space.
Definition functionspace.hpp:2490
auto to(torch::Device device) const
Returns a copy of the function space object with settings from device.
Definition functionspace.hpp:2825
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:2614
auto eval(const Arg &arg, const Args &...args) const
Returns the values of the spline object in the points xi
Definition functionspace.hpp:2696
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:2677
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:2620
auto rotate(std::array< value_type, 3 > angle)
Rotates the function space object by three angles in 3d.
Definition functionspace.hpp:2866
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:2608
constexpr FunctionSpace clone() const noexcept
Returns a clone of the function space.
Definition functionspace.hpp:2510
auto find_knot_indices_(std::index_sequence< Is... >, const Xi &xi) const
Returns the knot indicies of knot spans containing xi
Definition functionspace.hpp:2726
auto rotate(value_type angle)
Rotates the function space object by an angle in 2d.
Definition functionspace.hpp:2859
auto translate(std::array< value_type, N > v)
Translates the function space object by a vector.
Definition functionspace.hpp:2852
auto to(Options< real_t > options) const
Returns a copy of the function space object with settings from options.
Definition functionspace.hpp:2816
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:2663
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:2579
pugi::xml_document to_xml(int id=0, std::string label="") const
Returns the function space object as XML object.
Definition functionspace.hpp:2599
FunctionSpace(FunctionSpace &&)=default
Move constructor.
typename Spline::value_type value_type
Value type.
Definition functionspace.hpp:2413
boundary_type boundary_
Boundary.
Definition functionspace.hpp:2432
utils::TensorArray< Spline::parDim()> eval_type
Spline evaluation type.
Definition functionspace.hpp:2419
virtual FunctionSpace & spaces_from_tensor(const torch::Tensor &coeffs) noexcept
Sets the space from a single-tensor representation.
Definition functionspace.hpp:2571
virtual FunctionSpace & boundary_from_full_tensor(const torch::Tensor &coeffs) noexcept
Sets the boundary from a single-tensor representation.
Definition functionspace.hpp:2586
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:2635
virtual torch::Tensor as_tensor() const noexcept
Returns a single-tensor representation of the function space object.
Definition functionspace.hpp:2544
FunctionSpace(const FunctionSpace &)=default
Copy constructor.
spline_type spline_
Spline.
Definition functionspace.hpp:2429
static constexpr short_t nboundaries() noexcept
Returns the number of boundaries.
Definition functionspace.hpp:2480
auto eval_from_precomputed(const Args &...args) const
Returns the value of the spline object from precomputed basis function.
Definition functionspace.hpp:2715
nlohmann::json to_json() const override
Serialization to JSON.
Definition functionspace.hpp:2627
FunctionSpace & from_tensor(const torch::Tensor &coeffs) noexcept
Sets the function space object from a single-tensor representation.
Definition functionspace.hpp:2592
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:2454
constexpr const spline_type & space() const noexcept
Returns a constant reference to the -th function space.
Definition functionspace.hpp:2484
auto to() const
Returns a copy of the function space object with real_t type.
Definition functionspace.hpp:2830
constexpr auto clone() const noexcept
Returns a subset of the tuple of function spaces.
Definition functionspace.hpp:2515
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:3117
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:3110
typename FunctionSpace_trait< Spline, Boundary >::type type
Definition functionspace.hpp:3102
std::ostream & operator<<(std::ostream &os, const FunctionSpace< Splines... > &obj)
Print (as string) a function space object.
Definition functionspace.hpp:2395
Forward declaration.
Definition functionspace.hpp:3072
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:3148
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:3121
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:4030
IGANET_FUNCTIONSPACE_TUPLE_WRAPPER(TH);.
Definition functionspace.hpp:3467
IGANET_FUNCTIONSPACE_TUPLE_WRAPPER(NE);.
Definition functionspace.hpp:3773
Taylor-Hood like function space.
Definition functionspace.hpp:3151
Serialization prototype.
Definition serialize.hpp:31