IgANet
IGAnets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
iganet.hpp
Go to the documentation of this file.
1
15#pragma once
16
17#include <core/options.hpp>
18#include <net/generator.hpp>
19#include <net/collocation.hpp>
20#include <net/optimizer.hpp>
21#include <splines/boundary.hpp>
23#include <utils/container.hpp>
24#include <utils/fqn.hpp>
25#include <utils/tuple.hpp>
26#include <utils/zip.hpp>
27
28namespace iganet {
29
30
31
32
35 TORCH_ARG(int64_t, max_epoch) = 100;
36 TORCH_ARG(int64_t, batch_size) = 1000;
37 TORCH_ARG(double, min_loss) = 1e-4;
38 TORCH_ARG(double, min_loss_change) = 0;
39 TORCH_ARG(double, min_loss_rel_change) = 1e-3;
40};
41
46template <typename, typename, typename = void> class IgABase;
47
48template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs,
49 detail::HasAsTensor... CollPts>
50class IgABase<std::tuple<Inputs...>, std::tuple<Outputs...>,
51 std::tuple<CollPts...>> {
52public:
54 using value_type = std::common_type_t<typename Inputs::value_type...,
55 typename Outputs::value_type...>;
56
58 using inputs_type = std::tuple<Inputs...>;
59
61 using outputs_type = std::tuple<Outputs...>;
62
64 using collPts_type = std::tuple<typename CollPtsHelper<CollPts...>::type>;
65
66protected:
69
72
75
76private:
80 template <typename... Objs, std::size_t... NumCoeffs, std::size_t... Is>
82 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
84 std::index_sequence<Is...>) {
85 static_assert(sizeof...(Objs) == sizeof...(NumCoeffs));
86 return std::make_tuple(std::apply(
87 [&]<typename... Args>(Args &&...args) {
88 return Objs(std::forward<Args>(args)..., init, options);
89 },
90 std::get<Is>(numCoeffs))...);
91 }
92
93 template <typename... Objs, std::size_t... NumCoeffs>
95 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
97 return construct_tuple_from_arrays_impl<Objs...>(
98 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
99 }
101
105 template <typename... Objs, typename... NumCoeffsTuples, std::size_t... Is>
107 const std::tuple<NumCoeffsTuples...> &numCoeffs, enum init init,
108 iganet::Options<value_type> options, std::index_sequence<Is...>) {
109 static_assert(sizeof...(Objs) == sizeof...(NumCoeffsTuples));
110 return std::make_tuple(std::apply(
111 [&]<typename... Args>(Args &&...args) {
112 return Objs(std::forward<Args>(args)..., init, options);
113 },
114 std::get<Is>(numCoeffs))...);
115 }
116
117 template <typename... Objs, typename... NumCoeffsTuples>
118 auto
119 construct_tuple_from_tuples(const std::tuple<NumCoeffsTuples...> &numCoeffs,
120 enum init init,
122 return construct_tuple_from_tuples_impl<Objs...>(
123 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
124 }
126
127public:
129 explicit IgABase(
131 : inputs_(), outputs_(), collPts_() {}
132
137 template <std::size_t NumCoeffs>
138 explicit IgABase(
139 const std::array<int64_t, NumCoeffs> &ncoeffs,
140 enum init init = init::greville,
142 : IgABase(std::tuple{ncoeffs}, std::tuple{ncoeffs}, std::tuple{ncoeffs},
143 init, options) {}
144
149 template <std::size_t NumCoeffsInputs, std::size_t NumCoeffsOutputs,
150 std::size_t NumCoeffsCollPts>
151 IgABase(const std::array<int64_t, NumCoeffsInputs> &ncoeffsInputs,
152 const std::array<int64_t, NumCoeffsOutputs> &ncoeffsOutputs,
153 const std::array<int64_t, NumCoeffsCollPts> &ncoeffsCollPts,
154 enum init init = init::greville,
156 : IgABase(std::tuple{ncoeffsInputs}, std::tuple{ncoeffsOutputs},
157 std::tuple{ncoeffsCollPts}, init, options) {}
158
164 template <std::size_t... NumCoeffs>
165 explicit IgABase(
166 const std::tuple<std::array<int64_t, NumCoeffs>...> &ncoeffs,
167 enum init init = init::greville,
169 : IgABase(ncoeffs, ncoeffs, ncoeffs, init, options) {}
170
175 template <std::size_t... NumCoeffsInputs, std::size_t... NumCoeffsOutputs,
176 std::size_t... NumCoeffsCollPts>
178 const std::tuple<std::array<int64_t, NumCoeffsInputs>...> &ncoeffsInputs,
179 const std::tuple<std::array<int64_t, NumCoeffsOutputs>...>
180 &ncoeffsOutputs,
181 const std::tuple<std::array<int64_t, NumCoeffsCollPts>...>
182 &ncoeffsCollPts,
183 enum init init = init::greville,
185 : inputs_(construct_tuple_from_arrays<Inputs...>(ncoeffsInputs, init,
186 options)),
187 outputs_(construct_tuple_from_arrays<Outputs...>(ncoeffsOutputs, init,
188 options)),
189 collPts_(construct_tuple_from_arrays<Outputs...>(ncoeffsCollPts, init,
190 options)) {}
191
197 template <typename... CoeffsInputs, typename... CoeffsOutputs,
198 typename... CoeffsCollPts>
199 IgABase(const std::tuple<CoeffsInputs...> &coeffsInputs,
200 const std::tuple<CoeffsOutputs...> &coeffsOutputs,
201 const std::tuple<CoeffsCollPts...> &coeffsCollPts,
202 enum init init = init::greville,
204 : inputs_(construct_tuple_from_tuples<Inputs...>(coeffsInputs, init,
205 options)),
206 outputs_(construct_tuple_from_tuples<Outputs...>(coeffsOutputs, init,
207 options)),
208 collPts_(construct_tuple_from_tuples<CollPts...>(coeffsCollPts, init,
209 options)) {}
210
212 inline static constexpr std::size_t ninputs() noexcept {
213 return sizeof...(Inputs);
214 }
215
217 inline constexpr const auto &inputs() const { return inputs_; }
218
220 inline constexpr auto &inputs() { return inputs_; }
221
223 template <std::size_t index> inline constexpr const auto &input() const {
224 static_assert(index < sizeof...(Inputs));
225 return std::get<index>(inputs_);
226 }
227
229 template <std::size_t index> inline constexpr auto &input() {
230 static_assert(index < sizeof...(Inputs));
231 return std::get<index>(inputs_);
232 }
233
235 inline static constexpr std::size_t noutputs() noexcept {
236 return sizeof...(Outputs);
237 }
238
240 inline constexpr const auto &outputs() const { return outputs_; }
241
243 inline constexpr auto &outputs() { return outputs_; }
244
246 template <std::size_t index> inline constexpr const auto &output() const {
247 static_assert(index < sizeof...(Outputs));
248 return std::get<index>(outputs_);
249 }
250
252 template <std::size_t index> inline constexpr auto &output() {
253 static_assert(index < sizeof...(Outputs));
254 return std::get<index>(outputs_);
255 }
256
259 inline static constexpr std::size_t ncollPts() noexcept {
260 return sizeof...(CollPts);
261 }
262
265 inline constexpr const auto &collPts() const { return collPts_; }
266
269 inline constexpr auto &collPts() { return collPts_; }
270
277 template <std::size_t index>
278 std::tuple_element_t<index, collPts_type>
279 collPts(enum collPts collPts) const {
281 }
282};
283
284template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs>
285class IgABase<std::tuple<Inputs...>, std::tuple<Outputs...>, void> {
286public:
288 using value_type = std::common_type_t<typename Inputs::value_type...,
289 typename Outputs::value_type...>;
290
292 using inputs_type = std::tuple<Inputs...>;
293
295 template <std::size_t index>
296 using input_t = std::tuple_element_t<index, inputs_type>;
297
299 using outputs_type = std::tuple<Outputs...>;
300
302 template <std::size_t index>
303 using output_t = std::tuple_element_t<index, outputs_type>;
304
306 using collPts_type = std::tuple<typename CollPtsHelper<Outputs...>::type>;
307
309 template <std::size_t index>
310 using collPts_t = std::tuple_element_t<index, collPts_type>;
311
312protected:
315
318
319private:
323 template <typename... Objs, std::size_t... NumCoeffs, std::size_t... Is>
325 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
327 std::index_sequence<Is...>) {
328 static_assert(sizeof...(Objs) == sizeof...(NumCoeffs));
329 return std::make_tuple(Objs(std::get<Is>(numCoeffs), init, options)...);
330 }
331
332 template <typename... Objs, std::size_t... NumCoeffs>
334 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
335 enum init init, iganet::Options<value_type> options) {
336 return construct_tuple_from_arrays_impl<Objs...>(
337 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
338 }
340
344 template <typename... Objs, typename... NumCoeffs, std::size_t... Is>
346 const std::tuple<NumCoeffs...> &numCoeffs, enum init init,
347 iganet::Options<value_type> options, std::index_sequence<Is...>) {
348 static_assert(sizeof...(Objs) == sizeof...(NumCoeffs));
349 return std::make_tuple(std::apply(
350 [&]<typename... Args>(Args &&...args) {
351 return Objs(std::forward<Args>(args)..., init, options);
352 },
353 std::get<Is>(numCoeffs))...);
354 }
355
356 template <typename... Objs, typename... NumCoeffsTuples>
357 auto
358 construct_tuple_from_tuples(const std::tuple<NumCoeffsTuples...> &numCoeffs,
359 enum init init,
361 return construct_tuple_from_tuples_impl<Objs...>(
362 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
363 }
365
366public:
368 explicit IgABase(
370 : inputs_(), outputs_() {}
371
376 template <std::size_t NumCoeffs>
377 explicit IgABase(
378 const std::array<int64_t, NumCoeffs> &ncoeffs,
379 enum init init = init::greville,
381 : IgABase(std::tuple{ncoeffs}, std::tuple{ncoeffs}, init, options) {}
382
387 template <std::size_t NumCoeffsInputs, std::size_t NumCoeffsOutputs>
388 IgABase(const std::array<int64_t, NumCoeffsInputs> &ncoeffsInputs,
389 const std::array<int64_t, NumCoeffsOutputs> &ncoeffsOutputs,
390 enum init init = init::greville,
392 : IgABase(std::tuple{ncoeffsInputs}, std::tuple{ncoeffsOutputs}, init,
393 options) {}
394
400 template <std::size_t... NumCoeffs>
401 explicit IgABase(
402 const std::tuple<std::array<int64_t, NumCoeffs>...> &ncoeffs,
403 enum init init = init::greville,
405 : IgABase(ncoeffs, ncoeffs, init, options) {}
406
411 template <std::size_t... NumCoeffsInputs, std::size_t... NumCoeffsOutputs>
413 const std::tuple<std::array<int64_t, NumCoeffsInputs>...> &ncoeffsInputs,
414 const std::tuple<std::array<int64_t, NumCoeffsOutputs>...>
415 &ncoeffsOutputs,
416 enum init init = init::greville,
418 : inputs_(construct_tuple_from_arrays<Inputs...>(ncoeffsInputs, init,
419 options)),
420 outputs_(construct_tuple_from_arrays<Outputs...>(ncoeffsOutputs, init,
421 options)) {}
422
427 template <typename... CoeffsInputs, typename... CoeffsOutputs>
428 IgABase(const std::tuple<CoeffsInputs...> &coeffsInputs,
429 const std::tuple<CoeffsOutputs...> &coeffsOutputs,
430 enum init init = init::greville,
432 : inputs_(construct_tuple_from_tuples<Inputs...>(coeffsInputs, init,
433 options)),
434 outputs_(construct_tuple_from_tuples<Outputs...>(coeffsOutputs, init,
435 options)) {}
436
438 inline static constexpr std::size_t ninputs() noexcept {
439 return sizeof...(Inputs);
440 }
441
443 inline constexpr const auto &inputs() const { return inputs_; }
444
446 inline constexpr auto &inputs() { return inputs_; }
447
449 template <std::size_t index> inline constexpr const auto &input() const {
450 static_assert(index < sizeof...(Inputs));
451 return std::get<index>(inputs_);
452 }
453
455 template <std::size_t index> inline constexpr auto &input() {
456 static_assert(index < sizeof...(Inputs));
457 return std::get<index>(inputs_);
458 }
459
461 inline static constexpr std::size_t noutputs() noexcept {
462 return sizeof...(Outputs);
463 }
464
466 inline constexpr const auto &outputs() const { return outputs_; }
467
469 inline constexpr auto &outputs() { return outputs_; }
470
472 template <std::size_t index> inline constexpr const auto &output() const {
473 static_assert(index < sizeof...(Outputs));
474 return std::get<index>(outputs_);
475 }
476
478 template <std::size_t index> inline constexpr auto &output() {
479 static_assert(index < sizeof...(Outputs));
480 return std::get<index>(outputs_);
481 }
482
485 inline static constexpr std::size_t ncollPts() noexcept {
486 return sizeof...(Outputs);
487 }
488
491 inline constexpr const auto &collPts() const { return outputs_; }
492
495 inline constexpr auto &collPts() { return outputs_; }
496
503 template <std::size_t index>
504 std::tuple_element_t<index, collPts_type>
505 collPts(enum collPts collPts) const {
507 }
508};
510
514template <typename Optimizer, typename Inputs, typename Outputs,
515 typename CollPts = void>
516 requires OptimizerType<Optimizer>
517class IgANet : public IgABase<Inputs, Outputs, CollPts>,
520public:
523
525 using value_type = Base::value_type;
526
528 using optimizer_type = Optimizer;
529
532
533protected:
536
538 std::unique_ptr<optimizer_type> opt_;
539
542
543public:
545 explicit IgANet(const IgANetOptions &defaults = {},
548 : // Construct the base class
549 Base(),
550 // Construct the optimizer
551 opt_(std::make_unique<optimizer_type>(net_->parameters())),
552 // Set options
553 options_(defaults) {}
554
557 template <typename NumCoeffs>
558 IgANet(const std::vector<int64_t> &layers,
559 const std::vector<std::vector<std::any>> &activations,
560 const NumCoeffs &numCoeffs, enum init init = init::greville,
561 IgANetOptions defaults = {},
564 : IgANet(layers, activations, numCoeffs, numCoeffs, init, defaults,
565 options) {}
566
569 template <typename NumCoeffsInputs, typename NumCoeffsOutputs>
570 IgANet(const std::vector<int64_t> &layers,
571 const std::vector<std::vector<std::any>> &activations,
572 const NumCoeffsInputs &numCoeffsInputs,
573 const NumCoeffsOutputs &numCoeffsOutputs,
574 enum init init = init::greville, IgANetOptions defaults = {},
577 : // Construct the base class
578 Base(numCoeffsInputs, numCoeffsOutputs, init, options),
579 // Construct the deep neural network
580 net_(utils::concat(
581 std::vector<int64_t>{inputs(/* epoch */ 0).size(0)}, layers,
582 std::vector<int64_t>{outputs(/* epoch */ 0).size(0)}),
583 activations, options),
584
585 // Construct the optimizer
586 opt_(std::make_unique<optimizer_type>(net_->parameters())),
587
588 // Set options
589 options_(defaults) {}
590
593 return net_;
594 }
595
598
600 inline const optimizer_type &optimizer() const { return *opt_; }
601
603 inline optimizer_type &optimizer() { return *opt_; }
604
609 inline void optimizerReset(bool resetOptions = true) {
610 if (resetOptions)
611 opt_ = std::make_unique<optimizer_type>(net_->parameters());
612 else {
613 std::vector<optimizer_options_type> options;
614 for (auto &group : opt_->param_groups())
615 options.push_back(
616 static_cast<optimizer_options_type &>(group.options()));
617 opt_ = std::make_unique<optimizer_type>(net_->parameters());
618 for (auto [group, options] : utils::zip(opt_->param_groups(), options))
619 static_cast<optimizer_options_type &>(group.options()) = options;
620 }
621 }
622
625 opt_ =
626 std::make_unique<optimizer_type>(net_->parameters(), optimizerOptions);
627 }
628
630 inline optimizer_options_type &optimizerOptions(std::size_t param_group = 0) {
631 if (param_group < opt_->param_groups().size())
632 return static_cast<optimizer_options_type &>(
633 opt_->param_groups()[param_group].options());
634 else
635 throw std::runtime_error("Index exceeds number of parameter groups");
636 }
637
639 inline const optimizer_options_type &
640 optimizerOptions(std::size_t param_group = 0) const {
641 if (param_group < opt_->param_groups().size())
642 return static_cast<optimizer_options_type &>(
643 opt_->param_groups()[param_group].options());
644 else
645 throw std::runtime_error("Index exceeds number of parameter groups");
646 }
647
650 for (auto &group : opt_->param_groups())
651 static_cast<optimizer_options_type &>(group.options()) = options;
652 }
653
656 for (auto &group : opt_->param_groups())
657 static_cast<optimizer_options_type &>(group.options()) = options;
658 }
659
662 std::size_t param_group) {
663 if (param_group < opt_->param_groups().size())
664 static_cast<optimizer_options_type &>(opt_->param_group().options()) =
665 options;
666 else
667 throw std::runtime_error("Index exceeds number of parameter groups");
668 }
669
672 std::size_t param_group) {
673 if (param_group < opt_->param_groups().size())
674 static_cast<optimizer_options_type &>(opt_->param_group().options()) =
675 options;
676 else
677 throw std::runtime_error("Index exceeds number of parameter groups");
678 }
679
681 inline const auto &options() const { return options_; }
682
684 inline auto &options() { return options_; }
685
687 inline constexpr const auto &inputs() const { return Base::inputs(); }
688
690 inline constexpr auto &inputs() { return Base::inputs(); }
691
693 inline constexpr const auto &outputs() const { return Base::outputs(); }
694
696 inline constexpr auto &outputs() { return Base::outputs(); }
697
699 virtual torch::Tensor inputs(int64_t epoch) const {
701 Base::inputs_, [](const auto &obj) { return obj.as_tensor(); });
702 }
703
705 virtual torch::Tensor outputs(int64_t epoch) const {
707 Base::outputs_, [](const auto &obj) { return obj.as_tensor(); });
708 }
709
711 virtual void inputs(const torch::Tensor &tensor) {
713 Base::inputs_, tensor,
714 [](const auto &obj) { return obj.as_tensor_size(); },
715 [](auto &obj, const auto &tensor) { return obj.from_tensor(tensor); });
716 }
717
719 virtual void outputs(const torch::Tensor &tensor) {
721 Base::outputs_, tensor,
722 [](const auto &obj) { return obj.as_tensor_size(); },
723 [](auto &obj, const auto &tensor) { return obj.from_tensor(tensor); });
724 }
725
727 virtual bool epoch(int64_t) = 0;
728
730 virtual torch::Tensor loss(const torch::Tensor &, int64_t) = 0;
731
733 virtual void train(
734#ifdef IGANET_WITH_MPI
735 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
736 c10d::ProcessGroupMPI::createProcessGroupMPI()
737#endif
738 ) {
739 torch::Tensor inputs, outputs, loss;
740 typename Base::value_type previous_loss(-1.0);
741
742 // Loop over epochs
743 for (int64_t epoch = 0; epoch != options_.max_epoch(); ++epoch) {
744
745 // Update epoch and inputs
746 if (this->epoch(epoch))
747 inputs = this->inputs(epoch);
748
749 auto closure = [&]() {
750 // Reset gradients
751 net_->zero_grad();
752
753 // Execute the model on the inputs
754 outputs = net_->forward(inputs);
755
756 // Compute the loss value
757 loss = this->loss(outputs, epoch);
758
759 // Compute gradients of the loss w.r.t. the model parameters
760 loss.backward({}, true, false);
761
762 return loss;
763 };
764
765#ifdef IGANET_WITH_MPI
766 // Averaging the gradients of the parameters in all the processors
767 // Note: This may lag behind DistributedDataParallel (DDP) in performance
768 // since this synchronizes parameters after backward pass while DDP
769 // overlaps synchronizing parameters and computing gradients in backward
770 // pass
771 std::vector<c10::intrusive_ptr<::c10d::Work>> works;
772 for (auto &param : net_->named_parameters()) {
773 std::vector<torch::Tensor> tmp = {param.value().grad()};
774 works.emplace_back(pg->allreduce(tmp));
775 }
776
777 waitWork(pg, works);
778
779 for (auto &param : net_->named_parameters()) {
780 param.value().grad().data() =
781 param.value().grad().data() / pg->getSize();
782 }
783#endif
784
785 // Update the parameters based on the calculated gradients
786 opt_->step(closure);
787
788 typename Base::value_type current_loss =
789 loss.item<typename Base::value_type>();
790 Log(log::verbose) << "Epoch " << std::to_string(epoch) << ": "
791 << current_loss << std::endl;
792
793 if (current_loss < options_.min_loss() ||
794 std::abs(current_loss - previous_loss) < options_.min_loss_change() ||
795 std::abs(current_loss - previous_loss) / current_loss <
796 options_.min_loss_rel_change() ||
797 loss.isnan().item<bool>()) {
798 Log(log::info) << "Total epochs: " << epoch
799 << ", loss: " << current_loss << std::endl;
800 return;
801 }
802 previous_loss = current_loss;
803 }
804 Log(log::info) << "Max epochs reached: " << options_.max_epoch()
805 << ", loss: " << previous_loss << std::endl;
806 }
807
809 template <typename DataLoader>
810 void train(DataLoader &loader
811#ifdef IGANET_WITH_MPI
812 ,
813 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
814 c10d::ProcessGroupMPI::createProcessGroupMPI()
815#endif
816 ) {
817 torch::Tensor inputs, outputs, loss;
818 typename Base::value_type previous_loss(-1.0);
819
820 // Loop over epochs
821 for (int64_t epoch = 0; epoch != options_.max_epoch(); ++epoch) {
822
823 typename Base::value_type current_loss(0);
824
825 for (auto &batch : loader) {
826 inputs = batch.data;
827
828 if (inputs.dim() > 0) {
829 // if constexpr (Base::has_GeometryMap && Base::has_RefData) {
830 // Base::G_.from_tensor(
831 // inputs.slice(1, 0, Base::G_.as_tensor_size()).t());
832 // Base::f_.from_tensor(inputs
833 // .slice(1, Base::G_.as_tensor_size(),
834 // Base::G_.as_tensor_size() +
835 // Base::f_.as_tensor_size())
836 // .t());
837 // } else if constexpr (Base::has_GeometryMap && !Base::has_RefData)
838 // Base::G_.from_tensor(
839 // inputs.slice(1, 0, Base::G_.as_tensor_size()).t());
840 // else if constexpr (!Base::has_GeometryMap && Base::has_RefData)
841 // Base::f_.from_tensor(
842 // inputs.slice(1, 0, Base::f_.as_tensor_size()).t());
843
844 } else {
845 // if constexpr (Base::has_GeometryMap && Base::has_RefData) {
846 // Base::G_.from_tensor(
847 // inputs.slice(1, 0, Base::G_.as_tensor_size()).flatten());
848 // Base::f_.from_tensor(inputs
849 // .slice(1, Base::G_.as_tensor_size(),
850 // Base::G_.as_tensor_size() +
851 // Base::f_.as_tensor_size())
852 // .flatten());
853 // } else if constexpr (Base::has_GeometryMap && !Base::has_RefData)
854 // Base::G_.from_tensor(
855 // inputs.slice(1, 0, Base::G_.as_tensor_size()).flatten());
856 // else if constexpr (!Base::has_GeometryMap && Base::has_RefData)
857 // Base::f_.from_tensor(
858 // inputs.slice(1, 0, Base::f_.as_tensor_size()).flatten());
859 }
860
861 this->epoch(epoch);
862
863 auto closure = [&]() {
864 // Reset gradients
865 net_->zero_grad();
866
867 // Execute the model on the inputs
868 outputs = net_->forward(inputs);
869
870 // Compute the loss value
871 loss = this->loss(outputs, epoch);
872
873 // Compute gradients of the loss w.r.t. the model parameters
874 loss.backward({}, true, false);
875
876 return loss;
877 };
878
879 // Update the parameters based on the calculated gradients
880 opt_->step(closure);
881
882 current_loss += loss.item<typename Base::value_type>();
883 }
884 Log(log::verbose) << "Epoch " << std::to_string(epoch) << ": "
885 << current_loss << std::endl;
886
887 if (current_loss < options_.min_loss() ||
888 std::abs(current_loss - previous_loss) < options_.min_loss_change() ||
889 std::abs(current_loss - previous_loss) / current_loss <
890 options_.min_loss_rel_change() ||
891 loss.isnan().item<bool>()) {
892 Log(log::info) << "Total epochs: " << epoch
893 << ", loss: " << current_loss << std::endl;
894 return;
895 }
896 previous_loss = current_loss;
897 }
898 Log(log::info) << "Max epochs reached: " << options_.max_epoch()
899 << ", loss: " << previous_loss << std::endl;
900 }
901
903 void eval() {
904 torch::Tensor inputs = this->inputs(0);
905 torch::Tensor outputs = net_->forward(inputs);
906 this->outputs(outputs);
907 }
908
910 inline nlohmann::json to_json() const override {
911 return "Not implemented yet";
912 }
913
915 inline std::vector<torch::Tensor> parameters() const noexcept {
916 return net_->parameters();
917 }
918
921 inline torch::OrderedDict<std::string, torch::Tensor>
922 named_parameters() const noexcept {
923 return net_->named_parameters();
924 }
925
927 inline std::size_t nparameters() const noexcept {
928 std::size_t result = 0;
929 for (const auto &param : this->parameters()) {
930 result += param.numel();
931 }
932 return result;
933 }
934
936 torch::Tensor& register_parameter(std::string name, torch::Tensor tensor, bool requires_grad = true) {
937 return net_->register_parameter(name, tensor, requires_grad);
938 }
939
941 inline void pretty_print(std::ostream &os) const noexcept override {
942 os << name() << "(\n"
943 << "net = " << net_ << "\n";
944
945 os << "inputs[" << Base::ninputs() << "] = (";
946 std::apply([&os](const auto &...elems) { ((os << elems << "\n"), ...); },
947 Base::inputs());
948 os << ")";
949
950 os << "outputs [" << Base::noutputs() << "]= (";
951 std::apply([&os](const auto &...elems) { ((os << elems << "\n"), ...); },
952 Base::inputs());
953 os << ")";
954
955 os << "collPts [" << Base::ncollPts() << "]= (";
956 std::apply([&os](const auto &...elems) { ((os << elems << "\n"), ...); },
957 Base::collPts());
958 os << ")";
959 }
960
962 inline void save(const std::string &filename,
963 const std::string &key = "iganet") const {
964 torch::serialize::OutputArchive archive;
965 write(archive, key).save_to(filename);
966 }
967
969 inline void load(const std::string &filename,
970 const std::string &key = "iganet") {
971 torch::serialize::InputArchive archive;
972 archive.load_from(filename);
973 read(archive, key);
974 }
975
977 inline torch::serialize::OutputArchive &
978 write(torch::serialize::OutputArchive &archive,
979 const std::string &key = "iganet") const {
980
981 std::apply(
982 [&](auto &&...elems) {
983 std::size_t counter = 0;
984 (elems.write(archive,
985 key + ".input[" + std::to_string(counter++) + "]"),
986 ...);
987 },
988 Base::inputs());
989
990 std::apply(
991 [&](auto &&...elems) {
992 std::size_t counter = 0;
993 (elems.write(archive,
994 key + ".output[" + std::to_string(counter++) + "]"),
995 ...);
996 },
997 Base::outputs());
998
999 if constexpr (!std::is_void_v<CollPts>) {
1000 std::apply(
1001 [&](auto &&...elems) {
1002 std::size_t counter = 0;
1003 (elems.write(archive,
1004 key + ".collpts[" + std::to_string(counter++) + "]"),
1005 ...);
1006 },
1007 Base::collPts());
1008 }
1009
1010 net_->write(archive, key + ".net");
1011 torch::serialize::OutputArchive archive_net;
1012 net_->save(archive_net);
1013 archive.write(key + ".net.data", archive_net);
1014
1015 torch::serialize::OutputArchive archive_opt;
1016 opt_->save(archive_opt);
1017 archive.write(key + ".opt", archive_opt);
1018
1019 return archive;
1020 }
1021
1023 inline torch::serialize::InputArchive &
1024 read(torch::serialize::InputArchive &archive,
1025 const std::string &key = "iganet") {
1026
1027 std::apply(
1028 [&](auto &&...elems) {
1029 std::size_t counter = 0;
1030 (elems.read(archive,
1031 key + ".input[" + std::to_string(counter++) + "]"),
1032 ...);
1033 },
1034 Base::inputs());
1035
1036 std::apply(
1037 [&](auto &&...elems) {
1038 std::size_t counter = 0;
1039 (elems.read(archive,
1040 key + ".output[" + std::to_string(counter++) + "]"),
1041 ...);
1042 },
1043 Base::outputs());
1044
1045 if constexpr (!std::is_void_v<CollPts>) {
1046 std::apply(
1047 [&](auto &&...elems) {
1048 std::size_t counter = 0;
1049 (elems.read(archive,
1050 key + ".collpts[" + std::to_string(counter++) + "]"),
1051 ...);
1052 },
1053 Base::collPts());
1054 }
1055
1056 net_->read(archive, key + ".net");
1057 torch::serialize::InputArchive archive_net;
1058 archive.read(key + ".net.data", archive_net);
1059 net_->load(archive_net);
1060
1061 opt_->add_parameters(net_->parameters());
1062 torch::serialize::InputArchive archive_opt;
1063 archive.read(key + ".opt", archive_opt);
1064 opt_->load(archive_opt);
1065
1066 return archive;
1067 }
1068
1070 bool operator==(const IgANet &other) const {
1071 bool result(true);
1072
1073 result *= std::apply(
1074 [&](auto &&...elemsThis) {
1075 return std::apply(
1076 [&](auto &&...elemsOther) {
1077 return ((elemsThis == elemsOther) && ...);
1078 },
1079 other.inputs());
1080 },
1081 Base::inputs());
1082
1083 return result;
1084 }
1085
1087 bool operator!=(const IgANet &other) const { return *this != other; }
1088
1089#ifdef IGANET_WITH_MPI
1090private:
1092 static void waitWork(c10::intrusive_ptr<c10d::ProcessGroupMPI> pg,
1093 std::vector<c10::intrusive_ptr<c10d::Work>> works) {
1094 for (auto &work : works) {
1095 try {
1096 work->wait();
1097 } catch (const std::exception &ex) {
1098 Log(log::error) << "Exception received during waitWork: " << ex.what()
1099 << std::endl;
1100 pg->abort();
1101 }
1102 }
1103 }
1104#endif
1105};
1106
1108template <typename Optimizer, typename Inputs, typename Outputs,
1109 typename CollPts>
1110 requires OptimizerType<Optimizer>
1111inline std::ostream &
1112operator<<(std::ostream &os,
1114 obj.pretty_print(os);
1115 return os;
1116}
1117
1125template <typename, typename, typename = void> class IgANetCustomizable;
1126
1127template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs>
1128class IgANetCustomizable<std::tuple<Inputs...>, std::tuple<Outputs...>, void> {
1129private:
1131 static auto find_interior_knot_indices(auto &&tuple) {
1132 return std::apply(
1133 []<typename... Elems>(Elems &&...elems) {
1134 return std::make_tuple(([&] {
1135 using T = std::decay_t<Elems>;
1137 return elems.template find_knot_indices<functionspace::interior>(
1138 typename T::eval_type{});
1139 else if constexpr (detail::HasFindKnotIndices<T>)
1140 // Note that this is a fake call here
1141 return elems.find_knot_indices(typename T::eval_type{});
1142 })()...);
1143 },
1144 tuple);
1145 }
1146
1148 static auto find_boundary_knot_indices(auto &&tuple) {
1149 return std::apply(
1150 []<typename... Elems>(Elems &&...elems) {
1151 return std::make_tuple(([&] {
1152 using T = std::decay_t<Elems>;
1154 return elems.template find_knot_indices<functionspace::boundary>(
1155 typename T::boundary_eval_type{});
1156 else if constexpr (detail::HasFindKnotIndices<T>)
1157 // Note that this is a fake call here
1158 return elems.find_knot_indices(typename T::eval_type{});
1159 })()...);
1160 },
1161 tuple);
1162 }
1163
1165 static auto find_interior_coeff_indices(auto &&tuple) {
1166 return std::apply(
1167 []<typename... Elems>(Elems &&...elems) {
1168 return std::make_tuple(([&] {
1169 using T = std::decay_t<Elems>;
1171 return elems.template find_coeff_indices<functionspace::interior>(
1172 typename T::eval_type{});
1173 else if constexpr (detail::HasFindCoeffIndices<T>)
1174 // Note that this is a fake call here
1175 return elems.find_coeff_indices(typename T::eval_type{});
1176 })()...);
1177 },
1178 tuple);
1179 }
1180
1182 static auto find_boundary_coeff_indices(auto &&tuple) {
1183 return std::apply(
1184 []<typename... Elems>(Elems &&...elems) {
1185 return std::make_tuple(([&] {
1186 using T = std::decay_t<Elems>;
1188 return elems.template find_coeff_indices<functionspace::boundary>(
1189 typename T::boundary_eval_type{});
1190 else if constexpr (detail::HasFindCoeffIndices<T>)
1191 // Note that this is a fake call here
1192 return elems.find_coeff_indices(typename T::eval_type{});
1193 })()...);
1194 },
1195 tuple);
1196 }
1197
1198public:
1200 using inputs_interior_knot_indices_type = decltype(find_interior_knot_indices(
1201 std::declval<std::tuple<Inputs...>>()));
1202
1205 template <std::size_t index>
1207 std::tuple_element_t<index, inputs_interior_knot_indices_type>;
1208
1210 using inputs_boundary_knot_indices_type = decltype(find_boundary_knot_indices(
1211 std::declval<std::tuple<Inputs...>>()));
1212
1215 template <std::size_t index>
1217 std::tuple_element_t<index, inputs_boundary_knot_indices_type>;
1218
1221 decltype(find_interior_knot_indices(
1222 std::declval<std::tuple<Outputs...>>()));
1223
1226 template <std::size_t index>
1228 std::tuple_element_t<index, outputs_interior_knot_indices_type>;
1229
1232 decltype(find_boundary_knot_indices(
1233 std::declval<std::tuple<Outputs...>>()));
1234
1237 template <std::size_t index>
1239 std::tuple_element_t<index, outputs_boundary_knot_indices_type>;
1240
1243 decltype(find_interior_coeff_indices(
1244 std::declval<std::tuple<Inputs...>>()));
1245
1248 template <std::size_t index>
1250 std::tuple_element_t<index, inputs_interior_coeff_indices_type>;
1251
1254 decltype(find_boundary_coeff_indices(
1255 std::declval<std::tuple<Inputs...>>()));
1256
1259 template <std::size_t index>
1261 std::tuple_element_t<index, inputs_boundary_coeff_indices_type>;
1262
1265 decltype(find_interior_coeff_indices(
1266 std::declval<std::tuple<Outputs...>>()));
1267
1270 template <std::size_t index>
1272 std::tuple_element_t<index, outputs_interior_coeff_indices_type>;
1273
1276 decltype(find_boundary_coeff_indices(
1277 std::declval<std::tuple<Outputs...>>()));
1278
1281 template <std::size_t index>
1283 std::tuple_element_t<index, outputs_boundary_coeff_indices_type>;
1284};
1285
1286template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs,
1287 detail::HasAsTensor... CollPts>
1288class IgANetCustomizable<std::tuple<Inputs...>, std::tuple<Outputs...>,
1289 std::tuple<CollPts...>>
1290 : public IgANetCustomizable<std::tuple<Inputs...>, std::tuple<Outputs...>,
1291 void> {
1292public:
1296 decltype(std::declval<CollPts>()
1297 .template find_knot_indices<functionspace::interior>(
1298 std::declval<typename CollPts::eval_type>()))...>;
1299
1303 decltype(std::declval<CollPts>()
1304 .template find_knot_indices<functionspace::boundary>(
1305 std::declval<
1306 typename CollPts::boundary_eval_type>()))...>;
1307
1311 decltype(std::declval<CollPts>()
1312 .template find_coeff_indices<functionspace::interior>(
1313 std::declval<typename CollPts::eval_type>()))...>;
1314
1318 decltype(std::declval<CollPts>()
1319 .template find_coeff_indices<functionspace::boundary>(
1320 std::declval<
1321 typename CollPts::boundary_eval_type>()))...>;
1322};
1323
1325
1326} // namespace iganet
Boundary treatment.
Definition unittest_iganet.cxx:24
IgABase(iganet::Options< value_type > options=iganet::Options< value_type >{})
Default constructor.
Definition iganet.hpp:129
constexpr const auto & outputs() const
Returns a constant reference to the tuple of output objects.
Definition iganet.hpp:240
IgABase(const std::tuple< std::array< int64_t, NumCoeffsInputs >... > &ncoeffsInputs, const std::tuple< std::array< int64_t, NumCoeffsOutputs >... > &ncoeffsOutputs, const std::tuple< std::array< int64_t, NumCoeffsCollPts >... > &ncoeffsCollPts, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:177
std::tuple< typename CollPtsHelper< CollPts... >::type > collPts_type
Type of the collocation points.
Definition iganet.hpp:64
constexpr const auto & input() const
Returns a constant reference to the index-th input object.
Definition iganet.hpp:223
IgABase(const std::array< int64_t, NumCoeffsInputs > &ncoeffsInputs, const std::array< int64_t, NumCoeffsOutputs > &ncoeffsOutputs, const std::array< int64_t, NumCoeffsCollPts > &ncoeffsCollPts, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:151
constexpr auto & output()
Returns a non-constant reference to the index-th output object.
Definition iganet.hpp:252
static constexpr std::size_t noutputs() noexcept
Returns the number of elements in the tuple of output objects.
Definition iganet.hpp:235
std::common_type_t< typename Inputs::value_type..., typename Outputs::value_type... > value_type
Value type.
Definition iganet.hpp:55
IgABase(const std::tuple< std::array< int64_t, NumCoeffs >... > &ncoeffs, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:165
constexpr const auto & collPts() const
Returns a constant reference to the tuple of collocation points objects.
Definition iganet.hpp:265
std::tuple< Outputs... > outputs_type
Type of the outputs.
Definition iganet.hpp:61
std::tuple< Inputs... > inputs_type
Type of the inputs.
Definition iganet.hpp:58
static constexpr std::size_t ncollPts() noexcept
Returns the number of elements in the tuple of collocation points objects.
Definition iganet.hpp:259
constexpr const auto & inputs() const
Returns a constant reference to the tuple of input objects.
Definition iganet.hpp:217
auto construct_tuple_from_arrays(const std::tuple< std::array< int64_t, NumCoeffs >... > &numCoeffs, enum init init, iganet::Options< value_type > options)
Constructs a tuple from arrays.
Definition iganet.hpp:94
IgABase(const std::tuple< CoeffsInputs... > &coeffsInputs, const std::tuple< CoeffsOutputs... > &coeffsOutputs, const std::tuple< CoeffsCollPts... > &coeffsCollPts, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:199
auto construct_tuple_from_arrays_impl(const std::tuple< std::array< int64_t, NumCoeffs >... > &numCoeffs, enum init init, iganet::Options< value_type > options, std::index_sequence< Is... >)
Constructs a tuple from arrays.
Definition iganet.hpp:81
constexpr auto & input()
Returns a non-constant reference to the index-th input object.
Definition iganet.hpp:229
std::tuple_element_t< index, collPts_type > collPts(enum collPts collPts) const
Returns the collocation points of the index-th function spaces.
Definition iganet.hpp:279
static constexpr std::size_t ninputs() noexcept
Returns the number of elements in the tuple of input objects.
Definition iganet.hpp:212
constexpr auto & collPts()
Returns a non-constant reference to the tuple of collocation points objects.
Definition iganet.hpp:269
constexpr auto & inputs()
Returns a non-constant reference to the tuple of input objects.
Definition iganet.hpp:220
constexpr const auto & output() const
Returns a constant reference to the index-th output object.
Definition iganet.hpp:246
auto construct_tuple_from_tuples(const std::tuple< NumCoeffsTuples... > &numCoeffs, enum init init, iganet::Options< value_type > options)
Constructs a tuple from tuples.
Definition iganet.hpp:119
IgABase(const std::array< int64_t, NumCoeffs > &ncoeffs, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:138
constexpr auto & outputs()
Returns a non-constant reference to the tuple of output objects.
Definition iganet.hpp:243
auto construct_tuple_from_tuples_impl(const std::tuple< NumCoeffsTuples... > &numCoeffs, enum init init, iganet::Options< value_type > options, std::index_sequence< Is... >)
Constructs a tuple from tuples.
Definition iganet.hpp:106
IgABase(const std::array< int64_t, NumCoeffsInputs > &ncoeffsInputs, const std::array< int64_t, NumCoeffsOutputs > &ncoeffsOutputs, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:388
auto construct_tuple_from_tuples(const std::tuple< NumCoeffsTuples... > &numCoeffs, enum init init, iganet::Options< value_type > options)
Constructs a tuple from tuples.
Definition iganet.hpp:358
constexpr const auto & input() const
Returns a constant reference to the index-th input object.
Definition iganet.hpp:449
static constexpr std::size_t ncollPts() noexcept
Returns the number of elements in the tuple of collocation points objects.
Definition iganet.hpp:485
std::common_type_t< typename Inputs::value_type..., typename Outputs::value_type... > value_type
Value type.
Definition iganet.hpp:289
std::tuple_element_t< index, collPts_type > collPts(enum collPts collPts) const
Returns the collocation points of the index-th function spaces.
Definition iganet.hpp:505
constexpr auto & output()
Returns a non-constant reference to the index-th output object.
Definition iganet.hpp:478
IgABase(const std::tuple< std::array< int64_t, NumCoeffsInputs >... > &ncoeffsInputs, const std::tuple< std::array< int64_t, NumCoeffsOutputs >... > &ncoeffsOutputs, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:412
constexpr auto & inputs()
Returns a non-constant reference to the tuple of input objects.
Definition iganet.hpp:446
std::tuple< Inputs... > inputs_type
Type of the inputs.
Definition iganet.hpp:292
IgABase(const std::array< int64_t, NumCoeffs > &ncoeffs, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:377
IgABase(const std::tuple< CoeffsInputs... > &coeffsInputs, const std::tuple< CoeffsOutputs... > &coeffsOutputs, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:428
constexpr const auto & collPts() const
Returns a constant reference to the tuple of collocation points objects.
Definition iganet.hpp:491
auto construct_tuple_from_arrays_impl(const std::tuple< std::array< int64_t, NumCoeffs >... > &numCoeffs, enum init init, iganet::Options< value_type > options, std::index_sequence< Is... >)
Constructs a tuple from arrays.
Definition iganet.hpp:324
std::tuple_element_t< index, outputs_type > output_t
Type alias for the type of the index-th outputs object.
Definition iganet.hpp:303
static constexpr std::size_t noutputs() noexcept
Returns the number of elements in the tuple of output objects.
Definition iganet.hpp:461
std::tuple_element_t< index, inputs_type > input_t
Type alias for the type of the index-th inputs object.
Definition iganet.hpp:296
IgABase(iganet::Options< value_type > options=iganet::Options< value_type >{})
Default constructor.
Definition iganet.hpp:368
constexpr auto & collPts()
Returns a non-constant reference to the tuple of collocation points objects.
Definition iganet.hpp:495
constexpr const auto & output() const
Returns a constant reference to the index-th output object.
Definition iganet.hpp:472
constexpr const auto & inputs() const
Returns a constant reference to the tuple of input objects.
Definition iganet.hpp:443
auto construct_tuple_from_tuples_impl(const std::tuple< NumCoeffs... > &numCoeffs, enum init init, iganet::Options< value_type > options, std::index_sequence< Is... >)
Constructs a tuple from tuples.
Definition iganet.hpp:345
IgABase(const std::tuple< std::array< int64_t, NumCoeffs >... > &ncoeffs, enum init init=init::greville, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor.
Definition iganet.hpp:401
constexpr auto & input()
Returns a non-constant reference to the index-th input object.
Definition iganet.hpp:455
std::tuple< Outputs... > outputs_type
Type of the outputs.
Definition iganet.hpp:299
auto construct_tuple_from_arrays(const std::tuple< std::array< int64_t, NumCoeffs >... > &numCoeffs, enum init init, iganet::Options< value_type > options)
Constructs a tuple from arrays.
Definition iganet.hpp:333
static constexpr std::size_t ninputs() noexcept
Returns the number of elements in the tuple of input objects.
Definition iganet.hpp:438
constexpr auto & outputs()
Returns a non-constant reference to the tuple of output objects.
Definition iganet.hpp:469
constexpr const auto & outputs() const
Returns a constant reference to the tuple of output objects.
Definition iganet.hpp:466
std::tuple< typename CollPtsHelper< Outputs... >::type > collPts_type
Type of the collocation points.
Definition iganet.hpp:306
std::tuple_element_t< index, collPts_type > collPts_t
Type alias for the type of the index-th collocation points object.
Definition iganet.hpp:310
IgA base class.
Definition iganet.hpp:46
std::tuple< decltype(std::declval< CollPts >() .template find_knot_indices< functionspace::interior >(std::declval< typename CollPts::eval_type >()))... > collPts_interior_knot_indices_type
Type of the knot indices of the collocation points objects in the interior.
Definition iganet.hpp:1298
std::tuple< decltype(std::declval< CollPts >() .template find_coeff_indices< functionspace::interior >(std::declval< typename CollPts::eval_type >()))... > collPts_interior_coeff_indices_type
Type of the coefficient indices of the collocation points objects in the interior.
Definition iganet.hpp:1313
std::tuple< decltype(std::declval< CollPts >() .template find_coeff_indices< functionspace::boundary >(std::declval< typename CollPts::boundary_eval_type >()))... > collPts_boundary_coeff_indices_type
Type of the coefficient indices of the collocation points objects at the boundary.
Definition iganet.hpp:1321
std::tuple< decltype(std::declval< CollPts >() .template find_knot_indices< functionspace::boundary >(std::declval< typename CollPts::boundary_eval_type >()))... > collPts_boundary_knot_indices_type
Type of the knot indices of the collocation points objects at the boundary.
Definition iganet.hpp:1306
static auto find_interior_coeff_indices(auto &&tuple)
Returns the interior coeff indices of all tuple elements.
Definition iganet.hpp:1165
decltype(find_interior_coeff_indices(std::declval< std::tuple< Outputs... > >())) outputs_interior_coeff_indices_type
Type of the coefficient indices of the outputs in the interior.
Definition iganet.hpp:1266
std::tuple_element_t< index, inputs_boundary_coeff_indices_type > input_boundary_coeff_indices_t
Type alias for the type of the index-th coefficient indices of the inputs at the boundary.
Definition iganet.hpp:1261
std::tuple_element_t< index, outputs_interior_knot_indices_type > output_interior_knot_indices_t
Type alias for the type of the index-th knot indices of the outputs in the interior.
Definition iganet.hpp:1228
decltype(find_boundary_knot_indices(std::declval< std::tuple< Outputs... > >())) outputs_boundary_knot_indices_type
Type of the knot indices of the outputs at the boundary.
Definition iganet.hpp:1233
static auto find_boundary_knot_indices(auto &&tuple)
Returns the boundary knot indices of all tuple elements.
Definition iganet.hpp:1148
decltype(find_boundary_knot_indices(std::declval< std::tuple< Inputs... > >())) inputs_boundary_knot_indices_type
Type of the knot indices of the inputs at the boundary.
Definition iganet.hpp:1211
std::tuple_element_t< index, outputs_interior_coeff_indices_type > output_interior_coeff_indices_t
Type alias for the type of the index-th coefficient indices of the outputs in the interior.
Definition iganet.hpp:1272
decltype(find_interior_knot_indices(std::declval< std::tuple< Outputs... > >())) outputs_interior_knot_indices_type
Type of the knot indices of the outputs in the interior.
Definition iganet.hpp:1222
decltype(find_boundary_coeff_indices(std::declval< std::tuple< Outputs... > >())) outputs_boundary_coeff_indices_type
Type of the coefficient indices of the outputs at the boundary.
Definition iganet.hpp:1277
std::tuple_element_t< index, outputs_boundary_coeff_indices_type > output_boundary_coeff_indices_t
Type alias for the type of the index-th coefficient indices of the outputs at the boundary.
Definition iganet.hpp:1283
static auto find_interior_knot_indices(auto &&tuple)
Returns the interior knot indices of all tuple elements.
Definition iganet.hpp:1131
std::tuple_element_t< index, inputs_boundary_knot_indices_type > input_boundary_knot_indices_t
Type alias for the type of the index-th knot indices of the inputs at the boundary.
Definition iganet.hpp:1217
std::tuple_element_t< index, inputs_interior_knot_indices_type > input_interior_knot_indices_t
Type alias for the type of the index-th knot indices of the inputs in the interior.
Definition iganet.hpp:1207
decltype(find_boundary_coeff_indices(std::declval< std::tuple< Inputs... > >())) inputs_boundary_coeff_indices_type
Type of the coefficient indices of the inputs at the boundary.
Definition iganet.hpp:1255
decltype(find_interior_knot_indices(std::declval< std::tuple< Inputs... > >())) inputs_interior_knot_indices_type
Type of the knot indices of the inputs in the interior.
Definition iganet.hpp:1201
std::tuple_element_t< index, outputs_boundary_knot_indices_type > output_boundary_knot_indices_t
Type alias for the type of the index-th knot indices of the outputs at the boundary.
Definition iganet.hpp:1239
decltype(find_interior_coeff_indices(std::declval< std::tuple< Inputs... > >())) inputs_interior_coeff_indices_type
Type of the coefficient indices of the inputs in the interior.
Definition iganet.hpp:1244
static auto find_boundary_coeff_indices(auto &&tuple)
Returns the boundary coeff indices of all tuple elements.
Definition iganet.hpp:1182
std::tuple_element_t< index, inputs_interior_coeff_indices_type > input_interior_coeff_indices_t
Type alias for the type of the index-th coefficient indices of the inputs in the interior.
Definition iganet.hpp:1250
IgANetGenerator.
Definition generator.hpp:927
IgANet.
Definition iganet.hpp:519
void optimizerReset(bool resetOptions=true)
Resets the optimizer.
Definition iganet.hpp:609
void optimizerReset(const optimizer_options_type &optimizerOptions)
Resets the optimizer.
Definition iganet.hpp:624
void load(const std::string &filename, const std::string &key="iganet")
Loads the IgANet from file.
Definition iganet.hpp:969
constexpr auto & inputs()
Returns a non-constant reference to the tuple of input objects.
Definition iganet.hpp:690
torch::serialize::OutputArchive & write(torch::serialize::OutputArchive &archive, const std::string &key="iganet") const
Writes the IgANet into a torch::serialize::OutputArchive object.
Definition iganet.hpp:978
virtual void outputs(const torch::Tensor &tensor)
Attaches the given tensor to the outputs.
Definition iganet.hpp:719
void train(DataLoader &loader)
Trains the IgANet.
Definition iganet.hpp:810
const optimizer_type & optimizer() const
Returns a constant reference to the optimizer.
Definition iganet.hpp:600
void optimizerOptionsReset(optimizer_options_type &&options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:671
torch::OrderedDict< std::string, torch::Tensor > named_parameters() const noexcept
Returns a constant reference to the named parameters of the IgANet object.
Definition iganet.hpp:922
Base::value_type value_type
Value type.
Definition iganet.hpp:525
std::vector< torch::Tensor > parameters() const noexcept
Returns a constant reference to the parameters of the IgANet object.
Definition iganet.hpp:915
torch::Tensor & register_parameter(std::string name, torch::Tensor tensor, bool requires_grad=true)
Registers a parameter.
Definition iganet.hpp:936
void save(const std::string &filename, const std::string &key="iganet") const
Saves the IgANet to file.
Definition iganet.hpp:962
void optimizerOptionsReset(const optimizer_options_type &options)
Resets the optimizer options.
Definition iganet.hpp:649
IgANet(const IgANetOptions &defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Default constructor.
Definition iganet.hpp:545
optimizer_type & optimizer()
Returns a non-constant reference to the optimizer.
Definition iganet.hpp:603
torch::serialize::InputArchive & read(torch::serialize::InputArchive &archive, const std::string &key="iganet")
Loads the IgANet from a torch::serialize::InputArchive object.
Definition iganet.hpp:1024
IgANet(const std::vector< int64_t > &layers, const std::vector< std::vector< std::any > > &activations, const NumCoeffsInputs &numCoeffsInputs, const NumCoeffsOutputs &numCoeffsOutputs, enum init init=init::greville, IgANetOptions defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Constructor: number of layers, activation functions, and number of spline coefficients (same for all ...
Definition iganet.hpp:570
virtual bool epoch(int64_t)=0
Initializes epoch.
const IgANetGenerator< typename Base::value_type > & net() const
Returns a constant reference to the IgANet generator.
Definition iganet.hpp:592
auto & options()
Returns a non-constant reference to the options structure.
Definition iganet.hpp:684
IgANetGenerator< typename Base::value_type > net_
IgANet generator.
Definition iganet.hpp:535
IgABase< Inputs, Outputs, CollPts > Base
Base type.
Definition iganet.hpp:522
std::unique_ptr< optimizer_type > opt_
Optimizer.
Definition iganet.hpp:538
bool operator!=(const IgANet &other) const
Returns true if both IgANet objects are different.
Definition iganet.hpp:1087
IgANetOptions options_
Options.
Definition iganet.hpp:541
constexpr auto & outputs()
Returns a non-constant reference to the tuple of output objects.
Definition iganet.hpp:696
optimizer_options_type & optimizerOptions(std::size_t param_group=0)
Returns a non-constant reference to the optimizer options.
Definition iganet.hpp:630
virtual torch::Tensor outputs(int64_t epoch) const
Returns the network outputs as tensor.
Definition iganet.hpp:705
IgANet(const std::vector< int64_t > &layers, const std::vector< std::vector< std::any > > &activations, const NumCoeffs &numCoeffs, enum init init=init::greville, IgANetOptions defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Constructor: number of layers, activation functions, and number of spline coefficients (same for all ...
Definition iganet.hpp:558
virtual void train()
Trains the IgANet.
Definition iganet.hpp:733
std::size_t nparameters() const noexcept
Returns the total number of parameters of the IgANet object.
Definition iganet.hpp:927
Optimizer optimizer_type
Type of the optimizer.
Definition iganet.hpp:528
void optimizerOptionsReset(optimizer_options_type &&options)
Resets the optimizer options.
Definition iganet.hpp:655
optimizer_options_type< Optimizer >::type optimizer_options_type
Type of the optimizer options.
Definition iganet.hpp:531
virtual torch::Tensor inputs(int64_t epoch) const
Returns the network inputs as tensor.
Definition iganet.hpp:699
void pretty_print(std::ostream &os) const noexcept override
Returns a string representation of the IgANet object.
Definition iganet.hpp:941
virtual void inputs(const torch::Tensor &tensor)
Attaches the given tensor to the inputs.
Definition iganet.hpp:711
bool operator==(const IgANet &other) const
Returns true if both IgANet objects are the same.
Definition iganet.hpp:1070
nlohmann::json to_json() const override
Returns the IgANet object as JSON object.
Definition iganet.hpp:910
void optimizerOptionsReset(const optimizer_options_type &options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:661
constexpr const auto & inputs() const
Returns a constant reference to the tuple of input objects.
Definition iganet.hpp:687
constexpr const auto & outputs() const
Returns a constant reference to the tuple of output objects.
Definition iganet.hpp:693
void eval()
Evaluate IgANet.
Definition iganet.hpp:903
const auto & options() const
Returns a constant reference to the options structure.
Definition iganet.hpp:681
IgANetGenerator< typename Base::value_type > & net()
Returns a non-constant reference to the IgANet generator.
Definition iganet.hpp:597
const optimizer_options_type & optimizerOptions(std::size_t param_group=0) const
Returns a constant reference to the optimizer options.
Definition iganet.hpp:640
virtual torch::Tensor loss(const torch::Tensor &, int64_t)=0
Computes the loss function.
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:104
Full qualified name descriptor.
Definition fqn.hpp:22
virtual const std::string & name() const noexcept
Returns the full qualified name of the object.
Definition fqn.hpp:28
Isogeometric analysis base class.
Definition patch.hpp:29
Definition bspline.hpp:119
Definition bspline.hpp:112
Definition functionspace.hpp:54
Definition functionspace.hpp:47
Container utility functions.
Full qualified name utility functions.
Function spaces.
Network generator.
auto zip(T &&...seqs)
Definition zip.hpp:97
void slice_tensor_into_tuple(std::tuple< Tensors... > &tuple, const torch::Tensor &tensor, FuncSize &&funcSize, FuncAssign &&funcAssign, int64_t &offset, int64_t dim=0)
Slices the given tensor into the objects of the std::tuple.
Definition tuple.hpp:119
torch::Tensor cat_tuple_into_tensor(const std::tuple< Tensors... > &tensors, int64_t dim=0)
Concatenates the entries of a std::tuple object into a single Torch tensor along the given dimension.
Definition tuple.hpp:80
Definition core.hpp:72
collPts
Enumerator for the collocation point specifier.
Definition collocation.hpp:21
std::ostream & operator<<(std::ostream &os, const MemoryDebugger< id > &obj)
Print (as string) a memory debugger object.
Definition memory.hpp:125
struct iganet::@0 Log
Logger.
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:55
Collocation points helper
Definition collocation.hpp:35
IgANetCustomizable.
Definition iganet.hpp:1125
Type trait for the optimizer options type.
Definition optimizer.hpp:32
STL namespace.
Options.
IgANetOptions.
Definition iganet.hpp:34
TORCH_ARG(double, min_loss_change)=0
TORCH_ARG(int64_t, batch_size)
TORCH_ARG(double, min_loss)
TORCH_ARG(double, min_loss_rel_change)
TORCH_ARG(int64_t, max_epoch)
Serialization prototype.
Definition serialize.hpp:29
Tuple utility functions.
Zip utility function.