IgANet
IgANets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
boundary.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <boost/preprocessor/cat.hpp>
18#include <boost/preprocessor/seq/for_each.hpp>
19
20#include <bspline.hpp>
21
22namespace iganet {
23
25enum side {
26 west = 1,
27 east = 2,
28 south = 3,
29 north = 4,
30 front = 5,
31 back = 6,
32 stime = 7,
33 etime = 8,
34 left = 1,
35 right = 2,
36 down = 3,
37 up = 4,
38 none = 0
39};
40
42template <typename Spline, short_t> class BoundaryCore;
43
49template <typename Spline>
50class BoundaryCore<Spline, /* parDim */ 1> : public utils::Serializable,
52
53 // Safeguard that template parameter is a valid SplineType
54 static_assert(is_SplineType_v<Spline>, "Spline must be a valid SplineType");
55
57 template <typename BoundaryCore> friend class BoundaryCommon;
58
59protected:
61 using spline_type = Spline;
62
65 typename Spline::template derived_self_type<typename Spline::value_type,
66 Spline::geoDim()>;
67
70 template <typename real_t>
72 typename Spline::template derived_self_type<real_t, Spline::geoDim()>;
73
75 std::tuple<boundary_spline_type, boundary_spline_type> bdr_;
76
77public:
79 using boundary_type = decltype(bdr_);
80
82 using eval_type = std::tuple<torch::Tensor, torch::Tensor>;
83
87 : bdr_({boundary_spline_type(options), boundary_spline_type(options)}) {}
88
90 BoundaryCore(const boundary_type &bdr_) : bdr_(bdr_) {}
91
93 BoundaryCore(boundary_type &&bdr_) : bdr_(bdr_) {}
94
96 BoundaryCore(const BoundaryCore &other, bool clone)
97 : bdr_(clone ? std::apply(
98 [](const auto &...bspline) {
99 return std::make_tuple(bspline.clone()...);
100 },
101 other.coeffs())
102 : other.coeffs()) {}
103
105 BoundaryCore(const std::array<int64_t, 1> &, enum init init = init::zeros,
108 : bdr_({boundary_spline_type(std::array<int64_t, 0>{}, init, options),
109 boundary_spline_type(std::array<int64_t, 0>{}, init, options)}) {}
110
112 BoundaryCore(const std::array<std::vector<typename Spline::value_type>, 1> &,
113 enum init init = init::zeros,
116 : bdr_({boundary_spline_type(std::array<int64_t, 0>{}, init, options),
117 boundary_spline_type(std::array<int64_t, 0>{}, init, options)}) {}
118
125 inline auto &from_full_tensor(const torch::Tensor &tensor) {
126
127 if (tensor.dim() > 1) {
128 auto tensor_view = tensor.view({Spline::geoDim(), -1, tensor.size(-1)});
129
130 side<west>().from_tensor(tensor_view.index({torch::indexing::Slice(), 0})
131 .reshape({-1, tensor.size(-1)}));
132 side<east>().from_tensor(tensor_view.index({torch::indexing::Slice(), -1})
133 .reshape({-1, tensor.size(-1)}));
134 } else {
135 auto tensor_view = tensor.view({Spline::geoDim(), -1});
136
137 side<west>().from_tensor(
138 tensor_view.index({torch::indexing::Slice(), 0}).flatten());
139 side<east>().from_tensor(
140 tensor_view.index({torch::indexing::Slice(), -1}).flatten());
141 }
142 return *this;
143 }
144
146 inline static constexpr short_t nsides() { return side::east; }
147
149 template <short_t s> inline constexpr auto &side() const {
150 static_assert(s > none && s <= nsides());
151 return std::get<s - 1>(bdr_);
152 }
153
155 template <short_t s> inline constexpr auto &side() {
156 static_assert(s > none && s <= nsides());
157 return std::get<s - 1>(bdr_);
158 }
159
162 inline constexpr auto &coeffs() const { return bdr_; }
163
166 inline constexpr auto &coeffs() { return bdr_; }
167
169 inline int64_t ncumcoeffs() const {
170 int64_t s = 0;
171 s += side<west>().ncumcoeffs();
172 s += side<east>().ncumcoeffs();
173
174 return s;
175 }
176
178 inline virtual void
179 pretty_print(std::ostream &os = Log(log::info)) const noexcept override {
180 os << name() << "(\n"
181 << "west = " << side<west>() << "\n"
182 << "east = " << side<east>() << "\n)";
183 }
184
186 inline nlohmann::json to_json() const override {
187 nlohmann::json json;
188 json["west"] = side<west>().to_json();
189 json["east"] = side<east>().to_json();
190
191 return json;
192 }
193
195 inline BoundaryCore &from_json(const nlohmann::json &json) {
196 side<west>().from_json(json["west"]);
197 side<east>().from_json(json["east"]);
198
199 return *this;
200 }
201
203 inline eval_type greville() const {
204 return eval_type{side<west>().greville(), side<east>().greville()};
205 }
206};
207
215template <typename Spline>
216class BoundaryCore<Spline, /* parDim */ 2> : public utils::Serializable,
218
219 // Safeguard that template parameter is a valid SplineType
220 static_assert(is_SplineType_v<Spline>, "Spline must be a valid SplineType");
221
223 template <typename BoundaryCore> friend class BoundaryCommon;
224
225protected:
227 using spline_type = Spline;
228
230 using boundary_spline_type = std::tuple<
231 typename Spline::template derived_self_type<
232 typename Spline::value_type, Spline::geoDim(), Spline::degree(1)>,
233 typename Spline::template derived_self_type<
234 typename Spline::value_type, Spline::geoDim(), Spline::degree(0)>>;
235
238 template <typename real_t>
240 std::tuple<typename Spline::template derived_self_type<
241 real_t, Spline::geoDim(), Spline::degree(1)>,
242 typename Spline::template derived_self_type<
243 real_t, Spline::geoDim(), Spline::degree(0)>>;
244
246 std::tuple<typename std::tuple_element_t<0, boundary_spline_type>,
247 typename std::tuple_element_t<0, boundary_spline_type>,
248 typename std::tuple_element_t<1, boundary_spline_type>,
249 typename std::tuple_element_t<1, boundary_spline_type>>
251
252public:
254 using boundary_type = decltype(bdr_);
255
257 using eval_type = std::tuple<utils::TensorArray<1>, utils::TensorArray<1>,
259
263 : bdr_({std::tuple_element_t<0, boundary_spline_type>(options),
264 std::tuple_element_t<0, boundary_spline_type>(options),
265 std::tuple_element_t<1, boundary_spline_type>(options),
266 std::tuple_element_t<1, boundary_spline_type>(options)}) {}
267
269 BoundaryCore(const boundary_type &bdr_) : bdr_(bdr_) {}
270
272 BoundaryCore(boundary_type &&bdr_) : bdr_(bdr_) {}
273
275 BoundaryCore(const BoundaryCore &other, bool clone)
276 : bdr_(clone ? std::apply(
277 [](const auto &...bspline) {
278 return std::make_tuple(bspline.clone()...);
279 },
280 other.coeffs())
281 : other.coeffs()) {}
282
284 BoundaryCore(const std::array<int64_t, 2> &ncoeffs,
285 enum init init = init::zeros,
288 : bdr_({std::tuple_element_t<0, boundary_spline_type>(
289 std::array<int64_t, 1>({ncoeffs[1]}), init, options),
290 std::tuple_element_t<0, boundary_spline_type>(
291 std::array<int64_t, 1>({ncoeffs[1]}), init, options),
292 std::tuple_element_t<1, boundary_spline_type>(
293 std::array<int64_t, 1>({ncoeffs[0]}), init, options),
294 std::tuple_element_t<1, boundary_spline_type>(
295 std::array<int64_t, 1>({ncoeffs[0]}), init, options)}) {}
296
299 const std::array<std::vector<typename Spline::value_type>, 2> &kv,
300 enum init init = init::zeros,
303 : bdr_({std::tuple_element_t<0, boundary_spline_type>(
304 std::array<std::vector<typename Spline::value_type>, 1>(
305 {kv[1]}),
306 init, options),
307 std::tuple_element_t<0, boundary_spline_type>(
308 std::array<std::vector<typename Spline::value_type>, 1>(
309 {kv[1]}),
310 init, options),
311 std::tuple_element_t<1, boundary_spline_type>(
312 std::array<std::vector<typename Spline::value_type>, 1>(
313 {kv[0]}),
314 init, options),
315 std::tuple_element_t<1, boundary_spline_type>(
316 std::array<std::vector<typename Spline::value_type>, 1>(
317 {kv[0]}),
318 init, options)}) {}
319
326 inline auto &from_full_tensor(const torch::Tensor &tensor) {
327
328 if (tensor.dim() > 1) {
329 auto tensor_view =
330 tensor.view({-1, side<west>().ncoeffs(0), side<south>().ncoeffs(0),
331 tensor.size(-1)});
332
333 side<west>().from_tensor(
335 .index({torch::indexing::Slice(), torch::indexing::Slice(), 0})
336 .reshape({-1, tensor.size(-1)}));
337 side<east>().from_tensor(
339 .index({torch::indexing::Slice(), torch::indexing::Slice(), -1})
340 .reshape({-1, tensor.size(-1)}));
341 side<south>().from_tensor(
343 .index({torch::indexing::Slice(), 0, torch::indexing::Slice()})
344 .reshape({-1, tensor.size(-1)}));
345 side<north>().from_tensor(
347 .index({torch::indexing::Slice(), -1, torch::indexing::Slice()})
348 .reshape({-1, tensor.size(-1)}));
349 } else {
350 auto tensor_view =
351 tensor.view({-1, side<west>().ncoeffs(0), side<south>().ncoeffs(0)});
352
353 side<west>().from_tensor(
355 .index({torch::indexing::Slice(), torch::indexing::Slice(), 0})
356 .flatten());
357 side<east>().from_tensor(
359 .index({torch::indexing::Slice(), torch::indexing::Slice(), -1})
360 .flatten());
361 side<south>().from_tensor(
363 .index({torch::indexing::Slice(), 0, torch::indexing::Slice()})
364 .flatten());
365 side<north>().from_tensor(
367 .index({torch::indexing::Slice(), -1, torch::indexing::Slice()})
368 .flatten());
369 }
370 return *this;
371 }
372
374 inline static constexpr short_t nsides() { return side::north; }
375
377 template <short_t s> inline constexpr auto &side() const {
378 static_assert(s > none && s <= nsides());
379 return std::get<s - 1>(bdr_);
380 }
381
383 template <short_t s> inline constexpr auto &side() {
384 static_assert(s > none && s <= nsides());
385 return std::get<s - 1>(bdr_);
386 }
387
390 inline constexpr auto &coeffs() const { return bdr_; }
391
394 inline constexpr auto &coeffs() { return bdr_; }
395
397 inline int64_t ncumcoeffs() const {
398 int64_t s = 0;
399 s += side<west>().ncumcoeffs();
400 s += side<east>().ncumcoeffs();
401 s += side<south>().ncumcoeffs();
402 s += side<north>().ncumcoeffs();
403
404 return s;
405 }
406
408 inline virtual void
409 pretty_print(std::ostream &os = Log(log::info)) const noexcept override {
410 os << name() << "(\n"
411 << "west = " << side<west>() << "\n"
412 << "east = " << side<east>() << "\n"
413 << "south = " << side<south>() << "\n"
414 << "north = " << side<north>() << "\n)";
415 }
416
418 inline nlohmann::json to_json() const override {
419 nlohmann::json json;
420 json["west"] = side<west>().to_json();
421 json["east"] = side<east>().to_json();
422 json["south"] = side<south>().to_json();
423 json["north"] = side<north>().to_json();
424
425 return json;
426 }
427
429 inline BoundaryCore &from_json(const nlohmann::json &json) {
430 side<west>().from_json(json["west"]);
431 side<east>().from_json(json["east"]);
432 side<south>().from_json(json["south"]);
433 side<north>().from_json(json["north"]);
434
435 return *this;
436 }
437
439 inline eval_type greville() const {
440 return eval_type{side<west>().greville(), side<east>().greville(),
441 side<south>().greville(), side<north>().greville()};
442 }
443};
444
454template <typename Spline>
455class BoundaryCore<Spline, /* parDim */ 3> : public utils::Serializable,
457
458 // Safeguard that template parameter is a valid SplineType
459 static_assert(is_SplineType_v<Spline>, "Spline must be a valid SplineType");
460
462 template <typename BoundaryCore> friend class BoundaryCommon;
463
464protected:
466 using spline_type = Spline;
467
470 std::tuple<typename Spline::template derived_self_type<
471 typename Spline::value_type, Spline::geoDim(),
472 Spline::degree(1), Spline::degree(2)>,
473 typename Spline::template derived_self_type<
474 typename Spline::value_type, Spline::geoDim(),
475 Spline::degree(0), Spline::degree(2)>,
476 typename Spline::template derived_self_type<
477 typename Spline::value_type, Spline::geoDim(),
478 Spline::degree(0), Spline::degree(1)>>;
479
482 template <typename real_t>
484 typename Spline::template derived_self_type<
485 real_t, Spline::geoDim(), Spline::degree(1), Spline::degree(2)>,
486 typename Spline::template derived_self_type<
487 real_t, Spline::geoDim(), Spline::degree(0), Spline::degree(2)>,
488 typename Spline::template derived_self_type<
489 real_t, Spline::geoDim(), Spline::degree(0), Spline::degree(1)>>;
490
492 std::tuple<typename std::tuple_element_t<0, boundary_spline_type>,
493 typename std::tuple_element_t<0, boundary_spline_type>,
494 typename std::tuple_element_t<1, boundary_spline_type>,
495 typename std::tuple_element_t<1, boundary_spline_type>,
496 typename std::tuple_element_t<2, boundary_spline_type>,
497 typename std::tuple_element_t<2, boundary_spline_type>>
499
500public:
502 using boundary_type = decltype(bdr_);
503
505 using eval_type = std::tuple<utils::TensorArray<2>, utils::TensorArray<2>,
508
512 : bdr_({std::tuple_element_t<0, boundary_spline_type>(options),
513 std::tuple_element_t<0, boundary_spline_type>(options),
514 std::tuple_element_t<1, boundary_spline_type>(options),
515 std::tuple_element_t<1, boundary_spline_type>(options),
516 std::tuple_element_t<2, boundary_spline_type>(options),
517 std::tuple_element_t<2, boundary_spline_type>(options)}) {}
518
520 BoundaryCore(const boundary_type &bdr_) : bdr_(bdr_) {}
521
523 BoundaryCore(boundary_type &&bdr_) : bdr_(bdr_) {}
524
526 BoundaryCore(const BoundaryCore &other, bool clone)
527 : bdr_(clone ? std::apply(
528 [](const auto &...bspline) {
529 return std::make_tuple(bspline.clone()...);
530 },
531 other.coeffs())
532 : other.coeffs()) {}
533
535 BoundaryCore(const std::array<int64_t, 3> &ncoeffs,
536 enum init init = init::zeros,
539 : bdr_({std::tuple_element_t<0, boundary_spline_type>(
540 std::array<int64_t, 2>({ncoeffs[1], ncoeffs[2]}), init,
541 options),
542 std::tuple_element_t<0, boundary_spline_type>(
543 std::array<int64_t, 2>({ncoeffs[1], ncoeffs[2]}), init,
544 options),
545 std::tuple_element_t<1, boundary_spline_type>(
546 std::array<int64_t, 2>({ncoeffs[0], ncoeffs[2]}), init,
547 options),
548 std::tuple_element_t<1, boundary_spline_type>(
549 std::array<int64_t, 2>({ncoeffs[0], ncoeffs[2]}), init,
550 options),
551 std::tuple_element_t<2, boundary_spline_type>(
552 std::array<int64_t, 2>({ncoeffs[0], ncoeffs[1]}), init,
553 options),
554 std::tuple_element_t<2, boundary_spline_type>(
555 std::array<int64_t, 2>({ncoeffs[0], ncoeffs[1]}), init,
556 options)}) {}
557
560 const std::array<std::vector<typename Spline::value_type>, 3> &kv,
561 enum init init = init::zeros,
564 : bdr_({std::tuple_element_t<0, boundary_spline_type>(
565 std::array<std::vector<typename Spline::value_type>, 2>(
566 {kv[1], kv[2]}),
567 init, options),
568 std::tuple_element_t<0, boundary_spline_type>(
569 std::array<std::vector<typename Spline::value_type>, 2>(
570 {kv[1], kv[2]}),
571 init, options),
572 std::tuple_element_t<1, boundary_spline_type>(
573 std::array<std::vector<typename Spline::value_type>, 2>(
574 {kv[0], kv[2]}),
575 init, options),
576 std::tuple_element_t<1, boundary_spline_type>(
577 std::array<std::vector<typename Spline::value_type>, 2>(
578 {kv[0], kv[2]}),
579 init, options),
580 std::tuple_element_t<2, boundary_spline_type>(
581 std::array<std::vector<typename Spline::value_type>, 2>(
582 {kv[0], kv[1]}),
583 init, options),
584 std::tuple_element_t<2, boundary_spline_type>(
585 std::array<std::vector<typename Spline::value_type>, 2>(
586 {kv[0], kv[1]}),
587 init, options)}) {}
588
595 inline auto &from_full_tensor(const torch::Tensor &tensor) {
596
597 if (tensor.dim() > 1) {
598 auto tensor_view =
599 tensor.view({-1, side<west>().ncoeffs(1), side<west>().ncoeffs(0),
600 side<south>().ncoeffs(0), tensor.size(-1)});
601
602 side<west>().from_tensor(
604 .index({torch::indexing::Slice(), torch::indexing::Slice(),
605 torch::indexing::Slice(), 0})
606 .reshape({-1, tensor.size(-1)}));
607 side<east>().from_tensor(
609 .index({torch::indexing::Slice(), torch::indexing::Slice(),
610 torch::indexing::Slice(), -1})
611 .reshape({-1, tensor.size(-1)}));
612 side<south>().from_tensor(
614 .index({torch::indexing::Slice(), torch::indexing::Slice(), 0,
615 torch::indexing::Slice()})
616 .reshape({-1, tensor.size(-1)}));
617 side<north>().from_tensor(
619 .index({torch::indexing::Slice(), torch::indexing::Slice(), -1,
620 torch::indexing::Slice()})
621 .reshape({-1, tensor.size(-1)}));
622 side<front>().from_tensor(
624 .index({torch::indexing::Slice(), 0, torch::indexing::Slice(),
625 torch::indexing::Slice()})
626 .reshape({-1, tensor.size(-1)}));
627 side<back>().from_tensor(
629 .index({torch::indexing::Slice(), -1, torch::indexing::Slice(),
630 torch::indexing::Slice()})
631 .reshape({-1, tensor.size(-1)}));
632 } else {
633 auto tensor_view =
634 tensor.view({-1, side<west>().ncoeffs(1), side<west>().ncoeffs(0),
635 side<south>().ncoeffs(0)});
636
637 side<west>().from_tensor(
639 .index({torch::indexing::Slice(), torch::indexing::Slice(),
640 torch::indexing::Slice(), 0})
641 .flatten());
642 side<east>().from_tensor(
644 .index({torch::indexing::Slice(), torch::indexing::Slice(),
645 torch::indexing::Slice(), -1})
646 .flatten());
647
648 side<south>().from_tensor(
650 .index({torch::indexing::Slice(), torch::indexing::Slice(), 0,
651 torch::indexing::Slice()})
652 .flatten());
653 side<north>().from_tensor(
655 .index({torch::indexing::Slice(), torch::indexing::Slice(), -1,
656 torch::indexing::Slice()})
657 .flatten());
658
659 side<front>().from_tensor(
661 .index({torch::indexing::Slice(), 0, torch::indexing::Slice(),
662 torch::indexing::Slice()})
663 .flatten());
664 side<back>().from_tensor(
666 .index({torch::indexing::Slice(), -1, torch::indexing::Slice(),
667 torch::indexing::Slice()})
668 .flatten());
669 }
670 return *this;
671 }
672
674 inline static constexpr short_t nsides() { return side::back; }
675
677 template <short_t s> inline constexpr auto &side() const {
678 static_assert(s > none && s <= nsides());
679 return std::get<s - 1>(bdr_);
680 }
681
683 template <short_t s> inline constexpr auto &side() {
684 static_assert(s > none && s <= nsides());
685 return std::get<s - 1>(bdr_);
686 }
687
690 inline constexpr auto &coeffs() const { return bdr_; }
691
694 inline constexpr auto &coeffs() { return bdr_; }
695
697 inline int64_t ncumcoeffs() const {
698 int64_t s = 0;
699 s += side<west>().ncumcoeffs();
700 s += side<east>().ncumcoeffs();
701 s += side<south>().ncumcoeffs();
702 s += side<north>().ncumcoeffs();
703 s += side<front>().ncumcoeffs();
704 s += side<back>().ncumcoeffs();
705
706 return s;
707 }
708
710 inline virtual void
711 pretty_print(std::ostream &os = Log(log::info)) const noexcept override {
712 os << name() << "(\n"
713 << "west = " << side<west>() << "\n"
714 << "east = " << side<east>() << "\n"
715 << "south = " << side<south>() << "\n"
716 << "north = " << side<north>() << "\n"
717 << "front = " << side<front>() << "\n"
718 << "back = " << side<back>() << "\n)";
719 }
720
722 inline nlohmann::json to_json() const override {
723 nlohmann::json json;
724 json["west"] = side<west>().to_json();
725 json["east"] = side<east>().to_json();
726 json["south"] = side<south>().to_json();
727 json["north"] = side<north>().to_json();
728 json["front"] = side<front>().to_json();
729 json["back"] = side<back>().to_json();
730
731 return json;
732 }
733
735 inline BoundaryCore &from_json(const nlohmann::json &json) {
736 side<west>().from_json(json["west"]);
737 side<east>().from_json(json["east"]);
738 side<south>().from_json(json["south"]);
739 side<north>().from_json(json["north"]);
740 side<front>().from_json(json["front"]);
741 side<back>().from_json(json["back"]);
742
743 return *this;
744 }
745
747 inline eval_type greville() const {
748 return eval_type{side<west>().greville(), side<east>().greville(),
749 side<south>().greville(), side<north>().greville(),
750 side<front>().greville(), side<back>().greville()};
751 }
752};
753
765template <typename Spline>
766class BoundaryCore<Spline, /* parDim */ 4> : public utils::Serializable,
768
769 // Safeguard that template parameter is a valid SplineType
770 static_assert(is_SplineType_v<Spline>, "Spline must be a valid SplineType");
771
773 template <typename BoundaryCore> friend class BoundaryCommon;
774
775protected:
777 using spline_type = Spline;
778
781 std::tuple<typename Spline::template derived_self_type<
782 typename Spline::value_type, Spline::geoDim(),
783 Spline::degree(1), Spline::degree(2), Spline::degree(3)>,
784 typename Spline::template derived_self_type<
785 typename Spline::value_type, Spline::geoDim(),
786 Spline::degree(0), Spline::degree(2), Spline::degree(3)>,
787 typename Spline::template derived_self_type<
788 typename Spline::value_type, Spline::geoDim(),
789 Spline::degree(0), Spline::degree(1), Spline::degree(3)>,
790 typename Spline::template derived_self_type<
791 typename Spline::value_type, Spline::geoDim(),
792 Spline::degree(0), Spline::degree(1), Spline::degree(2)>>;
793
796 template <typename real_t>
798 std::tuple<typename Spline::template derived_self_type<
799 real_t, Spline::geoDim(), Spline::degree(1),
800 Spline::degree(2), Spline::degree(3)>,
801 typename Spline::template derived_self_type<
802 real_t, Spline::geoDim(), Spline::degree(0),
803 Spline::degree(2), Spline::degree(3)>,
804 typename Spline::template derived_self_type<
805 real_t, Spline::geoDim(), Spline::degree(0),
806 Spline::degree(1), Spline::degree(3)>,
807 typename Spline::template derived_self_type<
808 real_t, Spline::geoDim(), Spline::degree(0),
809 Spline::degree(1), Spline::degree(2)>>;
810
812 std::tuple<typename std::tuple_element_t<0, boundary_spline_type>,
813 typename std::tuple_element_t<0, boundary_spline_type>,
814 typename std::tuple_element_t<1, boundary_spline_type>,
815 typename std::tuple_element_t<1, boundary_spline_type>,
816 typename std::tuple_element_t<2, boundary_spline_type>,
817 typename std::tuple_element_t<2, boundary_spline_type>,
818 typename std::tuple_element_t<3, boundary_spline_type>,
819 typename std::tuple_element_t<3, boundary_spline_type>>
821
822public:
824 using boundary_type = decltype(bdr_);
825
827 using eval_type = std::tuple<utils::TensorArray<3>, utils::TensorArray<3>,
831
835 : bdr_({std::tuple_element_t<0, boundary_spline_type>(options),
836 std::tuple_element_t<0, boundary_spline_type>(options),
837 std::tuple_element_t<1, boundary_spline_type>(options),
838 std::tuple_element_t<1, boundary_spline_type>(options),
839 std::tuple_element_t<2, boundary_spline_type>(options),
840 std::tuple_element_t<2, boundary_spline_type>(options),
841 std::tuple_element_t<3, boundary_spline_type>(options),
842 std::tuple_element_t<3, boundary_spline_type>(options)}) {}
843
845 BoundaryCore(const boundary_type &bdr_) : bdr_(bdr_) {}
846
848 BoundaryCore(boundary_type &&bdr_) : bdr_(bdr_) {}
849
851 BoundaryCore(const BoundaryCore &other, bool clone)
852 : bdr_(clone ? std::apply(
853 [](const auto &...bspline) {
854 return std::make_tuple(bspline.clone()...);
855 },
856 other.coeffs())
857 : other.coeffs()) {}
858
860 BoundaryCore(const std::array<int64_t, 4> &ncoeffs,
861 enum init init = init::zeros,
864 : bdr_({std::tuple_element_t<0, boundary_spline_type>(
865 std::array<int64_t, 3>({ncoeffs[1], ncoeffs[2], ncoeffs[3]}),
866 init, options),
867 std::tuple_element_t<0, boundary_spline_type>(
868 std::array<int64_t, 3>({ncoeffs[1], ncoeffs[2], ncoeffs[3]}),
869 init, options),
870 std::tuple_element_t<1, boundary_spline_type>(
871 std::array<int64_t, 3>({ncoeffs[0], ncoeffs[2], ncoeffs[3]}),
872 init, options),
873 std::tuple_element_t<1, boundary_spline_type>(
874 std::array<int64_t, 3>({ncoeffs[0], ncoeffs[2], ncoeffs[3]}),
875 init, options),
876 std::tuple_element_t<2, boundary_spline_type>(
877 std::array<int64_t, 3>({ncoeffs[0], ncoeffs[1], ncoeffs[3]}),
878 init, options),
879 std::tuple_element_t<2, boundary_spline_type>(
880 std::array<int64_t, 3>({ncoeffs[0], ncoeffs[1], ncoeffs[3]}),
881 init, options),
882 std::tuple_element_t<3, boundary_spline_type>(
883 std::array<int64_t, 3>({ncoeffs[0], ncoeffs[1], ncoeffs[2]}),
884 init, options),
885 std::tuple_element_t<3, boundary_spline_type>(
886 std::array<int64_t, 3>({ncoeffs[0], ncoeffs[1], ncoeffs[2]}),
887 init, options)}) {}
888
891 const std::array<std::vector<typename Spline::value_type>, 4> &kv,
892 enum init init = init::zeros,
895 : bdr_({std::tuple_element_t<0, boundary_spline_type>(
896 std::array<std::vector<typename Spline::value_type>, 3>(
897 {kv[1], kv[2], kv[3]}),
898 init, options),
899 std::tuple_element_t<0, boundary_spline_type>(
900 std::array<std::vector<typename Spline::value_type>, 3>(
901 {kv[1], kv[2], kv[3]}),
902 init, options),
903 std::tuple_element_t<1, boundary_spline_type>(
904 std::array<std::vector<typename Spline::value_type>, 3>(
905 {kv[0], kv[2], kv[3]}),
906 init, options),
907 std::tuple_element_t<1, boundary_spline_type>(
908 std::array<std::vector<typename Spline::value_type>, 3>(
909 {kv[0], kv[2], kv[3]}),
910 init, options),
911 std::tuple_element_t<2, boundary_spline_type>(
912 std::array<std::vector<typename Spline::value_type>, 3>(
913 {kv[0], kv[1], kv[3]}),
914 init, options),
915 std::tuple_element_t<2, boundary_spline_type>(
916 std::array<std::vector<typename Spline::value_type>, 3>(
917 {kv[0], kv[1], kv[3]}),
918 init, options),
919 std::tuple_element_t<3, boundary_spline_type>(
920 std::array<std::vector<typename Spline::value_type>, 3>(
921 {kv[0], kv[1], kv[2]}),
922 init, options),
923 std::tuple_element_t<3, boundary_spline_type>(
924 std::array<std::vector<typename Spline::value_type>, 3>(
925 {kv[0], kv[1], kv[2]}),
926 init, options)}) {}
927
934 inline auto &from_full_tensor(const torch::Tensor &tensor) {
935
936 if (tensor.dim() > 1) {
937 auto tensor_view = tensor.view(
938 {-1, side<west>().ncoeffs(2), side<west>().ncoeffs(1),
939 side<west>().ncoeffs(0), side<south>().ncoeffs(0), tensor.size(-1)});
940
941 side<west>().from_tensor(
943 .index({torch::indexing::Slice(), torch::indexing::Slice(),
944 torch::indexing::Slice(), torch::indexing::Slice(), 0})
945 .reshape({-1, tensor.size(-1)}));
946 side<east>().from_tensor(
948 .index({torch::indexing::Slice(), torch::indexing::Slice(),
949 torch::indexing::Slice(), torch::indexing::Slice(), -1})
950 .reshape({-1, tensor.size(-1)}));
951 side<south>().from_tensor(
953 .index({torch::indexing::Slice(), torch::indexing::Slice(),
954 torch::indexing::Slice(), 0, torch::indexing::Slice()})
955 .reshape({-1, tensor.size(-1)}));
956 side<north>().from_tensor(
958 .index({torch::indexing::Slice(), torch::indexing::Slice(),
959 torch::indexing::Slice(), -1, torch::indexing::Slice()})
960 .reshape({-1, tensor.size(-1)}));
961 side<front>().from_tensor(
963 .index({torch::indexing::Slice(), torch::indexing::Slice(), 0,
964 torch::indexing::Slice(), torch::indexing::Slice()})
965 .reshape({-1, tensor.size(-1)}));
966 side<back>().from_tensor(
968 .index({torch::indexing::Slice(), torch::indexing::Slice(), -1,
969 torch::indexing::Slice(), torch::indexing::Slice()})
970 .reshape({-1, tensor.size(-1)}));
971 side<stime>().from_tensor(
973 .index({torch::indexing::Slice(), 0, torch::indexing::Slice(),
974 torch::indexing::Slice(), torch::indexing::Slice()})
975 .reshape({-1, tensor.size(-1)}));
976 side<etime>().from_tensor(
978 .index({torch::indexing::Slice(), -1, torch::indexing::Slice(),
979 torch::indexing::Slice(), torch::indexing::Slice()})
980 .reshape({-1, tensor.size(-1)}));
981 } else {
982 auto tensor_view =
983 tensor.view({-1, side<west>().ncoeffs(2), side<west>().ncoeffs(1),
984 side<west>().ncoeffs(0), side<south>().ncoeffs(0)});
985
986 side<west>().from_tensor(
988 .index({torch::indexing::Slice(), torch::indexing::Slice(),
989 torch::indexing::Slice(), torch::indexing::Slice(), 0})
990 .flatten());
991 side<east>().from_tensor(
993 .index({torch::indexing::Slice(), torch::indexing::Slice(),
994 torch::indexing::Slice(), torch::indexing::Slice(), -1})
995 .flatten());
996
997 side<south>().from_tensor(
999 .index({torch::indexing::Slice(), torch::indexing::Slice(),
1000 torch::indexing::Slice(), 0, torch::indexing::Slice()})
1001 .flatten());
1002 side<north>().from_tensor(
1004 .index({torch::indexing::Slice(), torch::indexing::Slice(),
1005 torch::indexing::Slice(), -1, torch::indexing::Slice()})
1006 .flatten());
1007
1008 side<front>().from_tensor(
1010 .index({torch::indexing::Slice(), torch::indexing::Slice(), 0,
1011 torch::indexing::Slice(), torch::indexing::Slice()})
1012 .flatten());
1013 side<back>().from_tensor(
1015 .index({torch::indexing::Slice(), torch::indexing::Slice(), -1,
1016 torch::indexing::Slice(), torch::indexing::Slice()})
1017 .flatten());
1018
1019 side<stime>().from_tensor(
1021 .index({torch::indexing::Slice(), 0, torch::indexing::Slice(),
1022 torch::indexing::Slice(), torch::indexing::Slice()})
1023 .flatten());
1024 side<etime>().from_tensor(
1026 .index({torch::indexing::Slice(), -1, torch::indexing::Slice(),
1027 torch::indexing::Slice(), torch::indexing::Slice()})
1028 .flatten());
1029 }
1030 return *this;
1031 }
1032
1034 inline static constexpr short_t nsides() { return side::etime; }
1035
1037 template <short_t s> inline constexpr auto &side() const {
1038 static_assert(s > none && s <= nsides());
1039 return std::get<s - 1>(bdr_);
1040 }
1041
1043 template <short_t s> inline constexpr auto &side() {
1044 static_assert(s > none && s <= nsides());
1045 return std::get<s - 1>(bdr_);
1046 }
1047
1050 inline constexpr auto &coeffs() const { return bdr_; }
1051
1054 inline constexpr auto &coeffs() { return bdr_; }
1055
1057 inline int64_t ncumcoeffs() const {
1058 int64_t s = 0;
1059 s += side<west>().ncumcoeffs();
1060 s += side<east>().ncumcoeffs();
1061 s += side<south>().ncumcoeffs();
1062 s += side<north>().ncumcoeffs();
1063 s += side<front>().ncumcoeffs();
1064 s += side<back>().ncumcoeffs();
1065 s += side<stime>().ncumcoeffs();
1066 s += side<etime>().ncumcoeffs();
1067
1068 return s;
1069 }
1070
1072 inline virtual void
1073 pretty_print(std::ostream &os = Log(log::info)) const noexcept override {
1074 os << name() << "(\n"
1075 << "west = " << side<west>() << "\n"
1076 << "east = " << side<east>() << "\n"
1077 << "south = " << side<south>() << "\n"
1078 << "north = " << side<north>() << "\n"
1079 << "front = " << side<front>() << "\n"
1080 << "back = " << side<back>() << "\n"
1081 << "stime = " << side<stime>() << "\n"
1082 << "etime = " << side<etime>() << "\n)";
1083 }
1084
1086 inline nlohmann::json to_json() const override {
1087 nlohmann::json json;
1088 json["west"] = side<west>().to_json();
1089 json["east"] = side<east>().to_json();
1090 json["south"] = side<south>().to_json();
1091 json["north"] = side<north>().to_json();
1092 json["front"] = side<front>().to_json();
1093 json["back"] = side<back>().to_json();
1094 json["stime"] = side<stime>().to_json();
1095 json["etime"] = side<etime>().to_json();
1096
1097 return json;
1098 }
1099
1101 inline BoundaryCore &from_json(const nlohmann::json &json) {
1102 side<west>().from_json(json["west"]);
1103 side<east>().from_json(json["east"]);
1104 side<south>().from_json(json["south"]);
1105 side<north>().from_json(json["north"]);
1106 side<front>().from_json(json["front"]);
1107 side<back>().from_json(json["back"]);
1108 side<stime>().from_json(json["stime"]);
1109 side<etime>().from_json(json["etime"]);
1110
1111 return *this;
1112 }
1113
1115 inline eval_type greville() const {
1116 return eval_type{side<west>().greville(), side<east>().greville(),
1117 side<south>().greville(), side<north>().greville(),
1118 side<front>().greville(), side<back>().greville(),
1119 side<stime>().greville(), side<etime>().greville()};
1120 }
1121};
1122
1124
1125namespace detail {
1128} // namespace detail
1129
1131template <typename... T>
1133 std::conjunction<std::is_base_of<detail::BoundaryType, T>...>;
1134
1136template <typename... T>
1137inline constexpr bool is_BoundaryType_v = is_BoundaryType<T...>::value;
1138
1140template <typename BoundaryCore>
1142public:
1144 using BoundaryCore::BoundaryCore;
1145
1147 BoundaryCommon clone() const { return BoundaryCommon(*this); }
1148
1149private:
1154 template <std::size_t... Is>
1155 inline torch::Tensor as_tensor_(std::index_sequence<Is...>) const {
1156 return torch::cat({std::get<Is>(BoundaryCore::bdr_).as_tensor()...});
1157 }
1158
1159public:
1164 inline torch::Tensor as_tensor() const {
1165 return as_tensor_(std::make_index_sequence<BoundaryCore::nsides()>{});
1166 }
1167
1168private:
1173 template <std::size_t... Is>
1174 inline int64_t as_tensor_size_(std::index_sequence<Is...>) const {
1175 return std::apply(
1176 [](auto... size) { return (size + ...); },
1177 std::make_tuple(std::get<Is>(BoundaryCore::bdr_).as_tensor_size()...));
1178 }
1179
1180public:
1183 //
1185 inline int64_t as_tensor_size() const {
1186 return as_tensor_size_(std::make_index_sequence<BoundaryCore::nsides()>{});
1187 }
1188
1189private:
1196 template <std::size_t... Is>
1197 inline auto &from_tensor_(std::index_sequence<Is...>,
1198 const torch::Tensor &tensor) {
1199
1200 std::size_t start(0);
1201 auto end = [&start](std::size_t inc) { return start += inc; };
1202
1203 (std::get<Is>(BoundaryCore::bdr_)
1204 .from_tensor(tensor.index({torch::indexing::Slice(
1205 start, end(std::get<Is>(BoundaryCore::bdr_).ncumcoeffs() *
1206 std::get<Is>(BoundaryCore::bdr_).geoDim()))})),
1207 ...);
1208
1209 return *this;
1210 }
1211
1212public:
1219 inline auto &from_tensor(const torch::Tensor &tensor) {
1220 return from_tensor_(std::make_index_sequence<BoundaryCore::nsides()>{},
1221 tensor);
1222 }
1223
1224private:
1227 template <deriv deriv = deriv::func, bool memory_optimized = false,
1228 size_t... Is, typename... Xi>
1229 inline auto eval_(std::index_sequence<Is...>,
1230 const std::tuple<Xi...> &xi) const {
1231 return std::tuple(
1232 std::get<Is>(BoundaryCore::bdr_)
1233 .template eval<deriv, memory_optimized>(std::get<Is>(xi))...);
1234 }
1235
1236 template <deriv deriv = deriv::func, bool memory_optimized = false,
1237 size_t... Is, typename... Xi, typename... Indices>
1238 inline auto eval_(std::index_sequence<Is...>, const std::tuple<Xi...> &xi,
1239 const std::tuple<Indices...> &indices) const {
1240 return std::tuple(std::get<Is>(BoundaryCore::bdr_)
1242 std::get<Is>(xi), std::get<Is>(indices))...);
1243 }
1244
1245 template <deriv deriv = deriv::func, bool memory_optimized = false,
1246 size_t... Is, typename... Xi, typename... Indices,
1247 typename... Coeff_Indices>
1248 inline auto eval_(std::index_sequence<Is...>, const std::tuple<Xi...> &xi,
1249 const std::tuple<Indices...> &indices,
1250 const std::tuple<Coeff_Indices...> &coeff_indices) const {
1251 return std::tuple(std::get<Is>(BoundaryCore::bdr_)
1253 std::get<Is>(xi), std::get<Is>(indices),
1254 std::get<Is>(coeff_indices))...);
1255 }
1257
1258public:
1261 template <deriv deriv = deriv::func, bool memory_optimized = false,
1262 typename... Xi>
1263 inline auto eval(const std::tuple<Xi...> &xi) const {
1265 std::make_index_sequence<BoundaryCore::nsides()>{}, xi);
1266 }
1267
1268 template <deriv deriv = deriv::func, bool memory_optimized = false,
1269 typename... Xi, typename... Indices>
1270 inline auto eval(const std::tuple<Xi...> &xi,
1271 const std::tuple<Indices...> &indices) const {
1272 static_assert(sizeof...(Xi) == sizeof...(Indices));
1274 std::make_index_sequence<BoundaryCore::nsides()>{}, xi, indices);
1275 }
1276
1277 template <deriv deriv = deriv::func, bool memory_optimized = false,
1278 typename... Xi, typename... Indices, typename... Coeff_Indices>
1279 inline auto eval(const std::tuple<Xi...> &xi,
1280 const std::tuple<Indices...> &indices,
1281 const std::tuple<Coeff_Indices...> &coeff_indices) const {
1282 static_assert(sizeof...(Xi) == sizeof...(Indices) &&
1283 sizeof...(Xi) == sizeof...(Coeff_Indices));
1285 std::make_index_sequence<BoundaryCore::nsides()>{}, xi, indices,
1287 }
1289
1290private:
1293 template <size_t... Is, typename... Basfunc, typename... Coeff_Indices,
1294 typename... Numeval, typename... Sizes>
1295 inline auto
1296 eval_from_precomputed_(std::index_sequence<Is...>,
1297 const std::tuple<Basfunc...> &basfunc,
1298 const std::tuple<Coeff_Indices...> &coeff_indices,
1299 const std::tuple<Numeval...> &numeval,
1300 const std::tuple<Sizes...> &sizes) const {
1301 return std::tuple(std::get<Is>(BoundaryCore::bdr_)
1302 .eval_from_precomputed(std::get<Is>(basfunc),
1303 std::get<Is>(coeff_indices),
1304 std::get<Is>(numeval),
1305 std::get<Is>(sizes))...);
1306 }
1307
1308 template <size_t... Is, typename... Basfunc, typename... Coeff_Indices,
1309 typename... Xi>
1310 inline auto
1311 eval_from_precomputed_(std::index_sequence<Is...>,
1312 const std::tuple<Basfunc...> &basfunc,
1313 const std::tuple<Coeff_Indices...> &coeff_indices,
1314 const std::tuple<Xi...> &xi) const {
1315 return std::tuple(
1316 std::get<Is>(BoundaryCore::bdr_)
1318 std::get<Is>(basfunc), std::get<Is>(coeff_indices),
1319 std::get<Is>(xi)[0].numel(), std::get<Is>(xi)[0].sizes())...);
1320 }
1322
1323public:
1326 template <typename... Basfunc, typename... Coeff_Indices, typename... Numeval,
1327 typename... Sizes>
1328 inline auto
1329 eval_from_precomputed(const std::tuple<Basfunc...> &basfunc,
1330 const std::tuple<Coeff_Indices...> &coeff_indices,
1331 const std::tuple<Numeval...> &numeval,
1332 const std::tuple<Sizes...> &sizes) const {
1333 static_assert(sizeof...(Basfunc) == sizeof...(Coeff_Indices) &&
1334 sizeof...(Basfunc) == sizeof...(Numeval) &&
1335 sizeof...(Basfunc) == sizeof...(Sizes));
1337 std::make_index_sequence<BoundaryCore::nsides()>{}, basfunc,
1339 }
1340
1341 template <typename... Basfunc, typename... Coeff_Indices, typename... Xi>
1342 inline auto
1343 eval_from_precomputed(const std::tuple<Basfunc...> &basfunc,
1344 const std::tuple<Coeff_Indices...> &coeff_indices,
1345 const std::tuple<Xi...> &xi) const {
1346 static_assert(sizeof...(Basfunc) == sizeof...(Coeff_Indices) &&
1347 sizeof...(Basfunc) == sizeof...(Xi));
1349 std::make_index_sequence<BoundaryCore::nsides()>{}, basfunc,
1350 coeff_indices, xi);
1351 }
1353
1354private:
1357 template <size_t... Is, typename... Xi>
1358 inline auto find_knot_indices_(std::index_sequence<Is...>,
1359 const std::tuple<Xi...> &xi) const {
1360 return std::tuple(std::get<Is>(BoundaryCore::bdr_)
1361 .find_knot_indices(std::get<Is>(xi))...);
1362 }
1363
1364public:
1366 template <typename... Xi>
1367 inline auto find_knot_indices(const std::tuple<Xi...> &xi) const {
1368 return find_knot_indices_(
1369 std::make_index_sequence<BoundaryCore::nsides()>{}, xi);
1370 }
1371
1372private:
1376 template <deriv deriv = deriv::func, bool memory_optimized = false,
1377 size_t... Is, typename... Xi>
1378 inline auto eval_basfunc_(std::index_sequence<Is...>,
1379 const std::tuple<Xi...> &xi) const {
1380 return std::tuple(std::get<Is>(BoundaryCore::bdr_)
1382 std::get<Is>(xi))...);
1383 }
1384
1385 template <deriv deriv = deriv::func, bool memory_optimized = false,
1386 size_t... Is, typename... Xi, typename... Indices>
1387 inline auto eval_basfunc_(std::index_sequence<Is...>,
1388 const std::tuple<Xi...> &xi,
1389 const std::tuple<Indices...> &indices) const {
1390 return std::tuple(std::get<Is>(BoundaryCore::bdr_)
1392 std::get<Is>(xi), std::get<Is>(indices))...);
1393 }
1395
1396public:
1399 template <deriv deriv = deriv::func, bool memory_optimized = false,
1400 typename... Xi>
1401 inline auto eval_basfunc(const std::tuple<Xi...> &xi) const {
1403 std::make_index_sequence<BoundaryCore::nsides()>{}, xi);
1404 }
1405
1406 template <deriv deriv = deriv::func, bool memory_optimized = false,
1407 typename... Xi, typename... Indices>
1408 inline auto eval_basfunc(const std::tuple<Xi...> &xi,
1409 const std::tuple<Indices...> &indices) const {
1410 static_assert(sizeof...(Xi) == sizeof...(Indices));
1412 std::make_index_sequence<BoundaryCore::nsides()>{}, xi, indices);
1413 }
1415
1416private:
1419 template <bool memory_optimized = false, size_t... Is, typename... Indices>
1420 inline auto find_coeff_indices_(std::index_sequence<Is...>,
1421 const std::tuple<Indices...> &indices) const {
1422 return std::tuple(std::get<Is>(BoundaryCore::bdr_)
1424 std::get<Is>(indices))...);
1425 }
1426
1427public:
1430 template <bool memory_optimized = false, typename... Indices>
1431 inline auto find_coeff_indices(const std::tuple<Indices...> &indices) const {
1433 std::make_index_sequence<BoundaryCore::nsides()>{}, indices);
1434 }
1435
1436private:
1439 template <size_t... Is>
1440 inline auto &uniform_refine_(std::index_sequence<Is...>, int numRefine = 1,
1441 int dim = -1) {
1442 (std::get<Is>(BoundaryCore::bdr_).uniform_refine(numRefine, dim), ...);
1443 return *this;
1444 }
1445
1446public:
1449 inline auto &uniform_refine(int numRefine = 1, int dim = -1) {
1450 if (dim == -1) {
1451 if constexpr (BoundaryCore::spline_type::parDim() > 1)
1452 uniform_refine_(std::make_index_sequence<BoundaryCore::nsides()>{},
1453 numRefine, dim);
1454 } else if (dim == 0) {
1455 if constexpr (BoundaryCore::nsides() == 2) {
1456 // We do not refine the boundary of a curve
1457 } else if constexpr (BoundaryCore::nsides() == 4) {
1458 std::get<side::south - 1>(BoundaryCore::bdr_)
1460 std::get<side::north - 1>(BoundaryCore::bdr_)
1462 } else if constexpr (BoundaryCore::nsides() == 6) {
1463 std::get<side::south - 1>(BoundaryCore::bdr_)
1465 std::get<side::north - 1>(BoundaryCore::bdr_)
1467 std::get<side::front - 1>(BoundaryCore::bdr_)
1469 std::get<side::back - 1>(BoundaryCore::bdr_)
1471 } else if constexpr (BoundaryCore::nsides() == 8) {
1472 std::get<side::south - 1>(BoundaryCore::bdr_)
1474 std::get<side::north - 1>(BoundaryCore::bdr_)
1476 std::get<side::front - 1>(BoundaryCore::bdr_)
1478 std::get<side::back - 1>(BoundaryCore::bdr_)
1480 std::get<side::stime - 1>(BoundaryCore::bdr_)
1482 std::get<side::etime - 1>(BoundaryCore::bdr_)
1484 } else
1485 throw std::runtime_error("Invalid dimension");
1486 } else if (dim == 1) {
1487 if constexpr (BoundaryCore::nsides() == 4) {
1488 std::get<side::east - 1>(BoundaryCore::bdr_)
1490 std::get<side::west - 1>(BoundaryCore::bdr_)
1492 } else if constexpr (BoundaryCore::nsides() == 6) {
1493 std::get<side::east - 1>(BoundaryCore::bdr_)
1495 std::get<side::west - 1>(BoundaryCore::bdr_)
1497 std::get<side::front - 1>(BoundaryCore::bdr_)
1499 std::get<side::back - 1>(BoundaryCore::bdr_)
1501
1502 } else if constexpr (BoundaryCore::nsides() == 8) {
1503 std::get<side::east - 1>(BoundaryCore::bdr_)
1505 std::get<side::west - 1>(BoundaryCore::bdr_)
1507 std::get<side::front - 1>(BoundaryCore::bdr_)
1509 std::get<side::back - 1>(BoundaryCore::bdr_)
1511 std::get<side::stime - 1>(BoundaryCore::bdr_)
1513 std::get<side::etime - 1>(BoundaryCore::bdr_)
1515 } else
1516 throw std::runtime_error("Invalid dimension");
1517 } else if (dim == 2) {
1518 if constexpr (BoundaryCore::nsides() == 6) {
1519 std::get<side::east - 1>(BoundaryCore::bdr_)
1521 std::get<side::west - 1>(BoundaryCore::bdr_)
1523 std::get<side::north - 1>(BoundaryCore::bdr_)
1525 std::get<side::south - 1>(BoundaryCore::bdr_)
1527 } else if constexpr (BoundaryCore::nsides() == 8) {
1528 std::get<side::west - 1>(BoundaryCore::bdr_)
1530 std::get<side::east - 1>(BoundaryCore::bdr_)
1532 std::get<side::south - 1>(BoundaryCore::bdr_)
1534 std::get<side::north - 1>(BoundaryCore::bdr_)
1536 std::get<side::stime - 1>(BoundaryCore::bdr_)
1538 std::get<side::etime - 1>(BoundaryCore::bdr_)
1540 } else
1541 throw std::runtime_error("Invalid dimension");
1542 } else if (dim == 3) {
1543 if constexpr (BoundaryCore::nsides() == 8) {
1544 std::get<side::west - 1>(BoundaryCore::bdr_)
1546 std::get<side::east - 1>(BoundaryCore::bdr_)
1548 std::get<side::south - 1>(BoundaryCore::bdr_)
1550 std::get<side::north - 1>(BoundaryCore::bdr_)
1552 std::get<side::front - 1>(BoundaryCore::bdr_)
1554 std::get<side::back - 1>(BoundaryCore::bdr_)
1556 } else
1557 throw std::runtime_error("Invalid dimension");
1558 } else
1559 throw std::runtime_error("Invalid dimension");
1560 return *this;
1561 }
1562
1563private:
1566 template <size_t... Is>
1567 inline torch::serialize::OutputArchive &
1568 write_(std::index_sequence<Is...>, torch::serialize::OutputArchive &archive,
1569 const std::string &key = "boundary") const {
1570 (std::get<Is>(BoundaryCore::bdr_)
1571 .write(archive, key + ".bdr[" + std::to_string(Is) + "]"),
1572 ...);
1573 return archive;
1574 }
1575
1576public:
1578 inline void save(const std::string &filename,
1579 const std::string &key = "boundary") const {
1580 torch::serialize::OutputArchive archive;
1581 write(archive, key).save_to(filename);
1582 }
1583
1586 inline torch::serialize::OutputArchive &
1587 write(torch::serialize::OutputArchive &archive,
1588 const std::string &key = "boundary") const {
1589 write_(std::make_index_sequence<BoundaryCore::nsides()>{}, archive, key);
1590 return archive;
1591 }
1592
1593private:
1596 template <size_t... Is>
1597 inline torch::serialize::InputArchive &
1598 read_(std::index_sequence<Is...>, torch::serialize::InputArchive &archive,
1599 const std::string &key = "boundary") {
1600 (std::get<Is>(BoundaryCore::bdr_)
1601 .read(archive, key + ".bdr[" + std::to_string(Is) + "]"),
1602 ...);
1603 return archive;
1604 }
1605
1606public:
1608 inline void load(const std::string &filename,
1609 const std::string &key = "boundary") {
1610 torch::serialize::InputArchive archive;
1611 archive.load_from(filename);
1612 read(archive, key);
1613 }
1614
1617 inline torch::serialize::InputArchive &
1618 read(torch::serialize::InputArchive &archive,
1619 const std::string &key = "boundary") {
1620 read_(std::make_index_sequence<BoundaryCore::nsides()>{}, archive, key);
1621 return archive;
1622 }
1623
1625 inline pugi::xml_document to_xml(int id = 0, std::string label = "",
1626 int index = -1) const {
1627 pugi::xml_document doc;
1628 pugi::xml_node root = doc.append_child("xml");
1629 to_xml(root, id, label, index);
1630
1631 return doc;
1632 }
1633
1635 inline pugi::xml_node &to_xml(pugi::xml_node &root, int id = 0,
1636 std::string label = "", int index = -1) const {
1637 // add Boundary node
1638 pugi::xml_node bdr = root.append_child("Boundary");
1639
1640 if (id >= 0)
1641 bdr.append_attribute("id") = id;
1642
1643 if (index >= 0)
1644 bdr.append_attribute("index") = index;
1645
1646 if (!label.empty())
1647 bdr.append_attribute("label") = label.c_str();
1648
1649 int index_ = 0;
1650 std::apply(
1651 [&bdr, &index_](const auto &...bspline) {
1652 (bspline.to_xml(bdr, -1, "", index_++), ...);
1653 },
1654 BoundaryCore::bdr_);
1655
1656 return root;
1657 }
1658
1660 inline BoundaryCommon &from_xml(const pugi::xml_document &doc, int id = 0,
1661 std::string label = "", int index = -1) {
1662 return from_xml(doc.child("xml"), id, label, index);
1663 }
1664
1666 inline BoundaryCommon &from_xml(const pugi::xml_node &root, int id = 0,
1667 std::string label = "", int index = -1) {
1668
1669 // Loop through all boundary nodes
1670 for (pugi::xml_node bdr : root.children("Boundary")) {
1671
1672 // Check for "Boundary" with given id, index, label
1673 if ((id >= 0 ? bdr.attribute("id").as_int() == id : true) &&
1674 (index >= 0 ? bdr.attribute("index").as_int() == index : true) &&
1675 (!label.empty() ? bdr.attribute("label").value() == label : true)) {
1676
1677 int index_ = 0;
1678 std::apply(
1679 [&bdr, &index_](auto &...bspline) {
1680 (bspline.from_xml(bdr, -1, "", index_++), ...);
1681 },
1682 BoundaryCore::bdr_);
1683
1684 return *this;
1685 } else
1686 continue; // try next "Boundary"
1687 }
1688
1689 throw std::runtime_error("XML object does not provide geometry with given "
1690 "id, index, and/or label");
1691 return *this;
1692 }
1693
1694private:
1697 template <typename BoundaryCore_, size_t... Is>
1698 inline bool isequal_(std::index_sequence<Is...>,
1699 const BoundaryCommon<BoundaryCore_> &other) const {
1700 return (
1701 (std::get<Is>(BoundaryCore::bdr_) == std::get<Is>(other.coeffs())) &&
1702 ...);
1703 }
1704
1705public:
1707 template <typename BoundaryCore_>
1709 return isequal_(std::make_index_sequence<BoundaryCore::nsides()>{}, other);
1710 }
1711
1713 template <typename BoundaryCore_>
1715 return !(
1716 *this ==
1717 other); // Do not change this to (*this != other) is it does not work
1718 }
1719
1720private:
1723 template <typename BoundaryCore_, size_t... Is>
1724 inline bool
1725 isclose_(std::index_sequence<Is...>,
1727 typename BoundaryCore::spline_type::value_type rtol,
1728 typename BoundaryCore::spline_type::value_type atol) const {
1729 return ((std::get<Is>(BoundaryCore::bdr_)
1730 .isclose(std::get<Is>(other.coeffs()))) &&
1731 ...);
1732 }
1733
1734public:
1737 template <typename BoundaryCore_>
1738 inline bool
1740 typename BoundaryCore::spline_type::value_type rtol =
1741 typename BoundaryCore::spline_type::value_type{1e-5},
1742 typename BoundaryCore::spline_type::value_type atol =
1743 typename BoundaryCore::spline_type::value_type{1e-8}) const {
1744 return isclose_(std::make_index_sequence<BoundaryCore::nsides()>{}, other,
1745 rtol, atol);
1746 }
1747
1748#define GENERATE_EXPR_MACRO(r, data, name) \
1749private: \
1750 template <bool memory_optimized = false, size_t... Is, typename... Xi> \
1751 inline auto BOOST_PP_CAT(name, _)(std::index_sequence<Is...>, \
1752 const std::tuple<Xi...> &xi) const { \
1753 return std::tuple( \
1754 std::get<Is>(BoundaryCore::bdr_) \
1755 .template name<memory_optimized>(std::get<Is>(xi))...); \
1756 } \
1757 \
1758 template <bool memory_optimized = false, size_t... Is, typename... Xi, \
1759 typename... Indices> \
1760 inline auto BOOST_PP_CAT(name, _)(std::index_sequence<Is...>, \
1761 const std::tuple<Xi...> &xi, \
1762 const std::tuple<Indices...> &indices) \
1763 const { \
1764 return std::tuple(std::get<Is>(BoundaryCore::bdr_) \
1765 .template name<memory_optimized>( \
1766 std::get<Is>(xi), std::get<Is>(indices))...); \
1767 } \
1768 \
1769 template <bool memory_optimized = false, size_t... Is, typename... Xi, \
1770 typename... Indices, typename... Coeff_Indices> \
1771 inline auto BOOST_PP_CAT(name, _)( \
1772 std::index_sequence<Is...>, const std::tuple<Xi...> &xi, \
1773 const std::tuple<Indices...> &indices, \
1774 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
1775 return std::tuple(std::get<Is>(BoundaryCore::bdr_) \
1776 .template name<memory_optimized>( \
1777 std::get<Is>(xi), std::get<Is>(indices), \
1778 std::get<Is>(coeff_indices))...); \
1779 } \
1780 \
1781public: \
1782 template <bool memory_optimized = false, typename... Args> \
1783 inline auto name(const Args &...args) const { \
1784 return BOOST_PP_CAT(name, _)<memory_optimized>( \
1785 std::make_index_sequence<BoundaryCore::nsides()>{}, args...); \
1786 }
1787
1792#undef GENERATE_EXPR_MACRO
1793
1794#define GENERATE_IEXPR_MACRO(r, data, name) \
1795private: \
1796 template <bool memory_optimized = false, size_t... Is, typename... Geometry, \
1797 typename... Xi> \
1798 inline auto BOOST_PP_CAT(name, _)(std::index_sequence<Is...>, \
1799 const std::tuple<Geometry...> &G, \
1800 const std::tuple<Xi...> &xi) const { \
1801 return std::tuple(std::get<Is>(BoundaryCore::bdr_) \
1802 .template name<memory_optimized>( \
1803 std::get<Is>(G), std::get<Is>(xi))...); \
1804 } \
1805 \
1806 template <bool memory_optimized = false, size_t... Is, typename... Geometry, \
1807 typename... Xi, typename... Indices> \
1808 inline auto BOOST_PP_CAT(name, _)( \
1809 std::index_sequence<Is...>, const std::tuple<Geometry...> &G, \
1810 const std::tuple<Xi...> &xi, const std::tuple<Indices...> &indices) \
1811 const { \
1812 return std::tuple( \
1813 std::get<Is>(BoundaryCore::bdr_) \
1814 .template name<memory_optimized>( \
1815 std::get<Is>(G), std::get<Is>(xi), std::get<Is>(indices))...); \
1816 } \
1817 \
1818 template <bool memory_optimized = false, size_t... Is, typename... Geometry, \
1819 typename... Xi, typename... Indices, typename... Coeff_Indices> \
1820 inline auto BOOST_PP_CAT(name, _)( \
1821 std::index_sequence<Is...>, const std::tuple<Geometry...> &G, \
1822 const std::tuple<Xi...> &xi, const std::tuple<Indices...> &indices, \
1823 const std::tuple<Coeff_Indices...> &coeff_indices) const { \
1824 return std::tuple(std::get<Is>(BoundaryCore::bdr_) \
1825 .template name<memory_optimized>( \
1826 std::get<Is>(G), std::get<Is>(xi), \
1827 std::get<Is>(indices), \
1828 std::get<Is>(coeff_indices))...); \
1829 } \
1830 \
1831public: \
1832 template <bool memory_optimized = false, typename... Args> \
1833 inline auto name(const Args &...args) const { \
1834 return BOOST_PP_CAT(name, _)<memory_optimized>( \
1835 std::make_index_sequence<BoundaryCore::nsides()>{}, args...); \
1836 }
1837
1842#undef GENERATE_IEXPR_MACRO
1843
1846 return std::apply(
1847 [](const auto &...bspline) {
1848 return std::make_tuple(bspline.device()...);
1849 },
1850 BoundaryCore::bdr_);
1851 }
1852
1855 return std::apply(
1856 [](const auto &...bspline) {
1857 return std::make_tuple(bspline.device_index()...);
1858 },
1859 BoundaryCore::bdr_);
1860 }
1861
1864 return std::apply(
1865 [](const auto &...bspline) {
1866 return std::make_tuple(bspline.dtype()...);
1867 },
1868 BoundaryCore::bdr_);
1869 }
1870
1873 return std::apply(
1874 [](const auto &...bspline) {
1875 return std::make_tuple(bspline.layout()...);
1876 },
1877 BoundaryCore::bdr_);
1878 }
1879
1882 return std::apply(
1883 [](const auto &...bspline) {
1884 return std::make_tuple(bspline.requires_grad()...);
1885 },
1886 BoundaryCore::bdr_);
1887 }
1888
1891 return std::apply(
1892 [](const auto &...bspline) {
1893 return std::make_tuple(bspline.pinned_memory()...);
1894 },
1895 BoundaryCore::bdr_);
1896 }
1897
1900 return std::apply(
1901 [](const auto &...bspline) {
1902 return std::make_tuple(bspline.is_sparse()...);
1903 },
1904 BoundaryCore::bdr_);
1905 }
1906
1909 return std::apply(
1910 [](const auto &...bspline) {
1911 return std::make_tuple(bspline.is_uniform()...);
1912 },
1913 BoundaryCore::bdr_);
1914 }
1915
1918 return std::apply(
1919 [](const auto &...bspline) {
1920 return std::make_tuple(bspline.is_nonuniform()...);
1921 },
1922 BoundaryCore::bdr_);
1923 }
1924
1927 std::apply(
1928 [requires_grad](const auto &...bspline) {
1929 (bspline.set_requires_grad(requires_grad), ...);
1930 },
1931 BoundaryCore::bdr_);
1932
1933 return *this;
1934 }
1935
1937 template <typename real_t> inline auto to(Options<real_t> options) const {
1938 using boundary_type = BoundaryCommon<iganet::BoundaryCore<
1939 decltype(typename BoundaryCore::spline_type{}.to(options)),
1940 BoundaryCore::spline_type::parDim()>>;
1941
1942 return boundary_type(std::apply(
1943 [&options](const auto &...bspline) {
1944 return std::make_tuple(bspline.to(options)...);
1945 },
1946 BoundaryCore::bdr_));
1947 }
1948
1950 inline auto to(torch::Device device) const {
1951 return BoundaryCommon(std::apply(
1952 [&device](const auto &...bspline) {
1953 return std::make_tuple(bspline.to(device)...);
1954 },
1955 BoundaryCore::bdr_));
1956 }
1957
1959 template <typename real_t> inline auto to() const {
1960 using boundary_type = BoundaryCommon<iganet::BoundaryCore<
1961 decltype(typename BoundaryCore::spline_type{}.template to<real_t>()),
1962 BoundaryCore::spline_type::parDim()>>;
1963
1964 return boundary_type(std::apply(
1965 [](const auto &...bspline) {
1966 return std::make_tuple(bspline.template to<real_t>()...);
1967 },
1968 BoundaryCore::bdr_));
1969 }
1970};
1971
1973template <typename Spline>
1974using Boundary = BoundaryCommon<BoundaryCore<Spline, Spline::parDim()>>;
1975
1977template <typename Spline>
1978inline std::ostream &operator<<(std::ostream &os, const Boundary<Spline> &obj) {
1979 obj.pretty_print(os);
1980 return os;
1981}
1982
1983} // namespace iganet
#define GENERATE_IEXPR_MACRO(r, data, name)
Auto-generated functions.
Definition boundary.hpp:1794
#define GENERATE_EXPR_MACRO(r, data, name)
Definition boundary.hpp:1748
Multivariate B-splines.
#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:1141
auto find_knot_indices(const std::tuple< Xi... > &xi) const
Returns the knot indicies of knot spans containing xi
Definition boundary.hpp:1367
auto to(torch::Device device) const
Returns a copy of the boundary object with settings from device.
Definition boundary.hpp:1950
auto dtype() const noexcept
Returns the dtype property of all splines.
Definition boundary.hpp:1863
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:1329
auto pinned_memory() const noexcept
Returns the pinned_memory property of all splines.
Definition boundary.hpp:1890
bool isequal_(std::index_sequence< Is... >, const BoundaryCommon< BoundaryCore_ > &other) const
Returns true if both boundary spline objects are the same.
Definition boundary.hpp:1698
auto eval_basfunc(const std::tuple< Xi... > &xi) const
Returns the values of the spline objects' basis functions in the points xi
Definition boundary.hpp:1401
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:1618
auto eval(const std::tuple< Xi... > &xi) const
Returns the values of the spline objects in the points xi
Definition boundary.hpp:1263
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 boundary spline objects from precomputed basis function.
Definition boundary.hpp:1296
auto to() const
Returns a copy of the boundary object with real_t type.
Definition boundary.hpp:1959
bool isclose_(std::index_sequence< Is... >, const BoundaryCommon< BoundaryCore_ > &other, typename BoundaryCore::spline_type::value_type rtol, typename BoundaryCore::spline_type::value_type atol) const
Returns true if both boundary spline objects are close up to the given tolerances.
Definition boundary.hpp:1725
auto to(Options< real_t > options) const
Returns a copy of the boundary object with settings from options.
Definition boundary.hpp:1937
auto device_index() const noexcept
Returns the device_index property of all splines.
Definition boundary.hpp:1854
auto is_uniform() const noexcept
Returns true if the B-spline is uniform of all splines.
Definition boundary.hpp:1908
BoundaryCommon & from_xml(const pugi::xml_document &doc, int id=0, std::string label="", int index=-1)
Updates the boundary object from XML object.
Definition boundary.hpp:1660
torch::Tensor as_tensor_(std::index_sequence< Is... >) const
Returns all coefficients of all spline objects as a single tensor.
Definition boundary.hpp:1155
int64_t as_tensor_size_(std::index_sequence< Is... >) const
Returns the size of the single tensor representation of all spline objects.
Definition boundary.hpp:1174
auto eval_basfunc_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the values of the boundary spline spline object's basis functions in the points xi
Definition boundary.hpp:1378
auto find_knot_indices_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the knot indicies of boundary spline object's knot spans containing xi
Definition boundary.hpp:1358
auto & uniform_refine_(std::index_sequence< Is... >, int numRefine=1, int dim=-1)
Returns the boundary spline object with uniformly refined knot and coefficient vectors.
Definition boundary.hpp:1440
torch::serialize::OutputArchive & write_(std::index_sequence< Is... >, torch::serialize::OutputArchive &archive, const std::string &key="boundary") const
Writes the boundary spline object into a torch::serialize::OutputArchive object.
Definition boundary.hpp:1568
pugi::xml_document to_xml(int id=0, std::string label="", int index=-1) const
Returns the boundary object as XML object.
Definition boundary.hpp:1625
auto is_nonuniform() const noexcept
Returns true if the B-spline is non-uniform if all splines.
Definition boundary.hpp:1917
BoundaryCommon & from_xml(const pugi::xml_node &root, int id=0, std::string label="", int index=-1)
Updates the boundary object from XML node.
Definition boundary.hpp:1666
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Indices... > &indices, const std::tuple< Coeff_Indices... > &coeff_indices) const
Returns the values of the boundary spline objects in the points xi
Definition boundary.hpp:1248
auto find_coeff_indices(const std::tuple< Indices... > &indices) const
Returns the indices of the spline objects' coefficients corresponding to the knot indices indices
Definition boundary.hpp:1431
auto requires_grad() const noexcept
Returns the requires_grad property of all splines.
Definition boundary.hpp:1881
auto eval(const std::tuple< Xi... > &xi, const std::tuple< Indices... > &indices) const
Returns the values of the spline objects in the points xi
Definition boundary.hpp:1270
BoundaryCommon clone() const
Returns a clone of the boundary object.
Definition boundary.hpp:1147
auto eval_basfunc(const std::tuple< Xi... > &xi, const std::tuple< Indices... > &indices) const
Returns the values of the spline objects' basis functions in the points xi
Definition boundary.hpp:1408
auto & from_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor.
Definition boundary.hpp:1219
auto & from_tensor_(std::index_sequence< Is... >, const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor.
Definition boundary.hpp:1197
auto eval(const std::tuple< Xi... > &xi, const std::tuple< Indices... > &indices, const std::tuple< Coeff_Indices... > &coeff_indices) const
Returns the values of the spline objects in the points xi
Definition boundary.hpp:1279
void load(const std::string &filename, const std::string &key="boundary")
Loads the boundary spline object from file.
Definition boundary.hpp:1608
torch::Tensor as_tensor() const
Returns all coefficients of all spline objects as a single tensor.
Definition boundary.hpp:1164
auto eval_basfunc_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Indices... > &indices) const
Returns the values of the boundary spline spline object's basis functions in the points xi
Definition boundary.hpp:1387
BoundaryCommon & set_requires_grad(bool requires_grad)
Sets the boundary object's requires_grad property.
Definition boundary.hpp:1926
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi) const
Returns the values of the boundary spline objects in the points xi
Definition boundary.hpp:1229
pugi::xml_node & to_xml(pugi::xml_node &root, int id=0, std::string label="", int index=-1) const
Returns the boundary object as XML node.
Definition boundary.hpp:1635
bool isclose(const BoundaryCommon< BoundaryCore_ > &other, typename BoundaryCore::spline_type::value_type rtol=typename BoundaryCore::spline_type::value_type{1e-5}, typename BoundaryCore::spline_type::value_type atol=typename BoundaryCore::spline_type::value_type{1e-8}) const
Returns true if both boundary objects are close up to the given tolerances.
Definition boundary.hpp:1739
auto & uniform_refine(int numRefine=1, int dim=-1)
Returns the spline objects with uniformly refined knot and coefficient vectors.
Definition boundary.hpp:1449
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 boundary spline objects from precomputed basis function.
Definition boundary.hpp:1311
int64_t as_tensor_size() const
Returns the size of the single tensor representation of all spline objects.
Definition boundary.hpp:1185
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 boundary.hpp:1343
bool operator==(const BoundaryCommon< BoundaryCore_ > &other) const
Returns true if both boundary objects are the same.
Definition boundary.hpp:1708
auto find_coeff_indices_(std::index_sequence< Is... >, const std::tuple< Indices... > &indices) const
Returns the indices of the boundary spline object's coefficients corresponding to the knot indices in...
Definition boundary.hpp:1420
auto layout() const noexcept
Returns the layout property of all splines.
Definition boundary.hpp:1872
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:1587
torch::serialize::InputArchive & read_(std::index_sequence< Is... >, torch::serialize::InputArchive &archive, const std::string &key="boundary")
Loads the function space object from a torch::serialize::InputArchive object.
Definition boundary.hpp:1598
auto eval_(std::index_sequence< Is... >, const std::tuple< Xi... > &xi, const std::tuple< Indices... > &indices) const
Returns the values of the boundary spline objects in the points xi
Definition boundary.hpp:1238
void save(const std::string &filename, const std::string &key="boundary") const
Saves the boundary spline to file.
Definition boundary.hpp:1578
auto device() const noexcept
Auto-generated functions.
Definition boundary.hpp:1845
bool operator!=(const BoundaryCommon< BoundaryCore_ > &other) const
Returns true if both boundary objects are different.
Definition boundary.hpp:1714
auto is_sparse() const noexcept
Returns if the layout is sparse of all splines.
Definition boundary.hpp:1899
constexpr auto & side() const
Returns constant reference to side-th Spline.
Definition boundary.hpp:149
BoundaryCore(const std::array< int64_t, 1 > &, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:105
std::tuple< boundary_spline_type, boundary_spline_type > bdr_
Tuple of splines.
Definition boundary.hpp:75
std::tuple< torch::Tensor, torch::Tensor > eval_type
Evaluation type.
Definition boundary.hpp:82
BoundaryCore(const BoundaryCore &other, bool clone)
Copy/clone constructor.
Definition boundary.hpp:96
BoundaryCore(const boundary_type &bdr_)
Copy constructor.
Definition boundary.hpp:90
BoundaryCore(const std::array< std::vector< typename Spline::value_type >, 1 > &, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:112
constexpr auto & coeffs() const
Returns a constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:162
typename Spline::template derived_self_type< real_t, Spline::geoDim()> real_derived_boundary_spline_type
Deduces the derived boundary spline type when exposed to a different class template parameter real_t
Definition boundary.hpp:72
constexpr auto & coeffs()
Returns a non-constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:166
static constexpr short_t nsides()
Returns the number of sides.
Definition boundary.hpp:146
BoundaryCore(Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Default constructor.
Definition boundary.hpp:85
int64_t ncumcoeffs() const
Returns the total number of coefficients.
Definition boundary.hpp:169
BoundaryCore & from_json(const nlohmann::json &json)
Updates the boundary object from JSON object.
Definition boundary.hpp:195
BoundaryCore(boundary_type &&bdr_)
Move constructor.
Definition boundary.hpp:93
constexpr auto & side()
Returns non-constant reference to side-th Spline.
Definition boundary.hpp:155
typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim()> boundary_spline_type
Boundary spline type.
Definition boundary.hpp:66
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the Boundary object.
Definition boundary.hpp:179
nlohmann::json to_json() const override
Returns the boundary object as JSON object.
Definition boundary.hpp:186
Spline spline_type
Spline type.
Definition boundary.hpp:61
decltype(bdr_) boundary_type
Boundary type.
Definition boundary.hpp:79
eval_type greville() const
Returns the Greville abscissae.
Definition boundary.hpp:203
auto & from_full_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor that holds both boundary and inner c...
Definition boundary.hpp:125
std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(1)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0)> > boundary_spline_type
Boundary spline type.
Definition boundary.hpp:234
constexpr auto & side()
Returns non-constant reference to the s-th side's spline.
Definition boundary.hpp:383
std::tuple< utils::TensorArray< 1 >, utils::TensorArray< 1 >, utils::TensorArray< 1 >, utils::TensorArray< 1 > > eval_type
Evaluation type.
Definition boundary.hpp:258
static constexpr short_t nsides()
Returns the number of sides.
Definition boundary.hpp:374
eval_type greville() const
Returns the Greville abscissae.
Definition boundary.hpp:439
BoundaryCore(const BoundaryCore &other, bool clone)
Copy/clone constructor.
Definition boundary.hpp:275
nlohmann::json to_json() const override
Returns the boundary object as JSON object.
Definition boundary.hpp:418
constexpr auto & coeffs()
Returns a non-constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:394
constexpr auto & coeffs() const
Returns a constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:390
BoundaryCore & from_json(const nlohmann::json &json)
Updates the boundary object from JSON object.
Definition boundary.hpp:429
Spline spline_type
Spline type.
Definition boundary.hpp:227
auto & from_full_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor that holds both boundary and inner c...
Definition boundary.hpp:326
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the Boundary object.
Definition boundary.hpp:409
decltype(bdr_) boundary_type
Boundary type.
Definition boundary.hpp:254
BoundaryCore(Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Default constructor.
Definition boundary.hpp:261
BoundaryCore(const boundary_type &bdr_)
Copy constructor.
Definition boundary.hpp:269
std::tuple< typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(1)>, typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(0)> > real_derived_boundary_spline_type
Deduces the derived boundary spline type when exposed to a different class template parameter real_t
Definition boundary.hpp:243
BoundaryCore(const std::array< int64_t, 2 > &ncoeffs, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:284
constexpr auto & side() const
Returns constant reference to the s-th side's spline.
Definition boundary.hpp:377
std::tuple< typename std::tuple_element_t< 0, boundary_spline_type >, typename std::tuple_element_t< 0, boundary_spline_type >, typename std::tuple_element_t< 1, boundary_spline_type >, typename std::tuple_element_t< 1, boundary_spline_type > > bdr_
Tuple of splines.
Definition boundary.hpp:250
int64_t ncumcoeffs() const
Returns the total number of coefficients.
Definition boundary.hpp:397
BoundaryCore(const std::array< std::vector< typename Spline::value_type >, 2 > &kv, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:298
BoundaryCore(boundary_type &&bdr_)
Move constructor.
Definition boundary.hpp:272
BoundaryCore & from_json(const nlohmann::json &json)
Updates the boundary object from JSON object.
Definition boundary.hpp:735
constexpr auto & side() const
Returns constant reference to side-th spline.
Definition boundary.hpp:677
constexpr auto & coeffs() const
Returns a constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:690
BoundaryCore(const std::array< std::vector< typename Spline::value_type >, 3 > &kv, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:559
BoundaryCore(const boundary_type &bdr_)
Copy constructor.
Definition boundary.hpp:520
decltype(bdr_) boundary_type
Boundary type.
Definition boundary.hpp:502
BoundaryCore(const BoundaryCore &other, bool clone)
Copy/clone constructor.
Definition boundary.hpp:526
Spline spline_type
Spline type.
Definition boundary.hpp:466
std::tuple< typename std::tuple_element_t< 0, boundary_spline_type >, typename std::tuple_element_t< 0, boundary_spline_type >, typename std::tuple_element_t< 1, boundary_spline_type >, typename std::tuple_element_t< 1, boundary_spline_type >, typename std::tuple_element_t< 2, boundary_spline_type >, typename std::tuple_element_t< 2, boundary_spline_type > > bdr_
Tuple of splines.
Definition boundary.hpp:498
std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(1), Spline::degree(2)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(2)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(1)> > boundary_spline_type
Boundary spline type.
Definition boundary.hpp:478
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the Boundary object.
Definition boundary.hpp:711
constexpr auto & coeffs()
Returns a non-constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:694
BoundaryCore(boundary_type &&bdr_)
Move constructor.
Definition boundary.hpp:523
BoundaryCore(Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Default constructor.
Definition boundary.hpp:510
BoundaryCore(const std::array< int64_t, 3 > &ncoeffs, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:535
int64_t ncumcoeffs() const
Returns the total number of coefficients.
Definition boundary.hpp:697
auto & from_full_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor that holds both boundary and inner c...
Definition boundary.hpp:595
std::tuple< typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(1), Spline::degree(2)>, typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(0), Spline::degree(2)>, typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(0), Spline::degree(1)> > real_derived_boundary_spline_type
Deduces the derived boundary spline type when exposed to a different class template parameter real_t
Definition boundary.hpp:489
nlohmann::json to_json() const override
Returns the boundary object as JSON object.
Definition boundary.hpp:722
constexpr auto & side()
Returns non-constant reference to side-th spline.
Definition boundary.hpp:683
std::tuple< utils::TensorArray< 2 >, utils::TensorArray< 2 >, utils::TensorArray< 2 >, utils::TensorArray< 2 >, utils::TensorArray< 2 >, utils::TensorArray< 2 > > eval_type
Evaluation type.
Definition boundary.hpp:507
static constexpr short_t nsides()
Returns the number of sides.
Definition boundary.hpp:674
eval_type greville() const
Returns the Greville abscissae.
Definition boundary.hpp:747
BoundaryCore(const std::array< int64_t, 4 > &ncoeffs, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:860
constexpr auto & side()
Returns non-constant reference to side-th spline.
Definition boundary.hpp:1043
BoundaryCore & from_json(const nlohmann::json &json)
Updates the boundary object from JSON object.
Definition boundary.hpp:1101
auto & from_full_tensor(const torch::Tensor &tensor)
Sets the coefficients of all spline objects from a single tensor that holds both boundary and inner c...
Definition boundary.hpp:934
eval_type greville() const
Returns the Greville abscissae.
Definition boundary.hpp:1115
int64_t ncumcoeffs() const
Returns the total number of coefficients.
Definition boundary.hpp:1057
std::tuple< typename std::tuple_element_t< 0, boundary_spline_type >, typename std::tuple_element_t< 0, boundary_spline_type >, typename std::tuple_element_t< 1, boundary_spline_type >, typename std::tuple_element_t< 1, boundary_spline_type >, typename std::tuple_element_t< 2, boundary_spline_type >, typename std::tuple_element_t< 2, boundary_spline_type >, typename std::tuple_element_t< 3, boundary_spline_type >, typename std::tuple_element_t< 3, boundary_spline_type > > bdr_
Tuple of splines.
Definition boundary.hpp:820
BoundaryCore(boundary_type &&bdr_)
Move constructor.
Definition boundary.hpp:848
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the Boundary object.
Definition boundary.hpp:1073
static constexpr short_t nsides()
Returns the number of sides.
Definition boundary.hpp:1034
std::tuple< utils::TensorArray< 3 >, utils::TensorArray< 3 >, utils::TensorArray< 3 >, utils::TensorArray< 3 >, utils::TensorArray< 3 >, utils::TensorArray< 3 >, utils::TensorArray< 3 >, utils::TensorArray< 3 > > eval_type
Evaluation type.
Definition boundary.hpp:830
BoundaryCore(const BoundaryCore &other, bool clone)
Copy/clone constructor.
Definition boundary.hpp:851
constexpr auto & coeffs()
Returns a non-constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:1054
Spline spline_type
Spline type.
Definition boundary.hpp:777
BoundaryCore(const boundary_type &bdr_)
Copy constructor.
Definition boundary.hpp:845
constexpr auto & side() const
Returns constant reference to side-th spline.
Definition boundary.hpp:1037
BoundaryCore(const std::array< std::vector< typename Spline::value_type >, 4 > &kv, enum init init=init::zeros, Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Constructor.
Definition boundary.hpp:890
std::tuple< typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), 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(2), Spline::degree(3)>, typename Spline::template derived_self_type< typename Spline::value_type, Spline::geoDim(), Spline::degree(0), Spline::degree(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)> > boundary_spline_type
Array storing the degrees.
Definition boundary.hpp:792
nlohmann::json to_json() const override
Returns the boundary object as JSON object.
Definition boundary.hpp:1086
BoundaryCore(Options< typename Spline::value_type > options=Options< typename Spline::value_type >{})
Default constructor.
Definition boundary.hpp:833
decltype(bdr_) boundary_type
Boundary type.
Definition boundary.hpp:824
std::tuple< typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(1), Spline::degree(2), Spline::degree(3)>, typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(0), Spline::degree(2), Spline::degree(3)>, typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(3)>, typename Spline::template derived_self_type< real_t, Spline::geoDim(), Spline::degree(0), Spline::degree(1), Spline::degree(2)> > real_derived_boundary_spline_type
Deduces the derived boundary spline type when exposed to a different class template parameter real_t
Definition boundary.hpp:809
constexpr auto & coeffs() const
Returns a constant reference to the array of coefficients for all boundary segments.
Definition boundary.hpp:1050
BoundaryCore.
Definition boundary.hpp:42
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:90
Boundary type.
Definition boundary.hpp:1127
Full qualified name descriptor.
Definition fqn.hpp:26
std::array< torch::Tensor, N > TensorArray
Definition tensorarray.hpp:28
Definition boundary.hpp:22
deriv
Enumerator for specifying the derivative of B-spline evaluation.
Definition bspline.hpp:74
constexpr bool is_SplineType_v
Alias to the value of is_SplineType.
Definition bspline.hpp:3243
std::ostream & operator<<(std::ostream &os, const Boundary< Spline > &obj)
Print (as string) a Boundary object.
Definition boundary.hpp:1978
struct iganet::@0 Log
Logger.
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:55
std::conjunction< std::is_base_of< detail::BoundaryType, T >... > is_BoundaryType
Type trait to check if T is a valid Boundary type.
Definition boundary.hpp:1133
constexpr bool is_BoundaryType_v
Alias to the value of is_BoundaryType.
Definition boundary.hpp:1137
side
Identifiers for topological sides.
Definition boundary.hpp:25
@ stime
Definition boundary.hpp:32
@ down
Definition boundary.hpp:36
@ right
Definition boundary.hpp:35
@ left
Definition boundary.hpp:34
@ back
Definition boundary.hpp:31
@ east
Definition boundary.hpp:27
@ etime
Definition boundary.hpp:33
@ front
Definition boundary.hpp:30
@ north
Definition boundary.hpp:29
@ south
Definition boundary.hpp:28
@ west
Definition boundary.hpp:26
@ up
Definition boundary.hpp:37
@ none
Definition boundary.hpp:38
short int short_t
Definition core.hpp:74
STL namespace.
Serialization prototype.
Definition serialize.hpp:31