IgANet
IGAnets - Isogeometric Analysis Networks
Loading...
Searching...
No Matches
iganet.hpp
Go to the documentation of this file.
1
15#pragma once
16
24#include <iganet/utils/fqn.hpp>
26#include <iganet/utils/zip.hpp>
27
28namespace iganet {
29
30
31
32
36 TORCH_ARG(int64_t, max_epoch) = 100;
38 TORCH_ARG(int64_t, batch_size) = 1000;
40 TORCH_ARG(double, min_loss) = 1e-4;
42 TORCH_ARG(double, min_loss_change) = 0;
44 TORCH_ARG(double, min_loss_rel_change) = 1e-3;
45};
46
51template <typename, typename, typename = void> class IgABase;
52
53template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs,
54 detail::HasAsTensor... CollPts>
55class IgABase<std::tuple<Inputs...>, std::tuple<Outputs...>,
56 std::tuple<CollPts...>> {
57public:
59 using value_type = std::common_type_t<typename Inputs::value_type...,
60 typename Outputs::value_type...>;
61
63 using inputs_type = std::tuple<Inputs...>;
64
66 using outputs_type = std::tuple<Outputs...>;
67
69 using collPts_type = std::tuple<typename CollPtsHelper<CollPts...>::type>;
70
71protected:
74
77
80
81private:
85 template <typename... Objs, std::size_t... NumCoeffs, std::size_t... Is>
87 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
89 std::index_sequence<Is...>) {
90 static_assert(sizeof...(Objs) == sizeof...(NumCoeffs));
91 return std::make_tuple(std::apply(
92 [&]<typename... Args>(Args &&...args) {
93 return Objs(std::forward<Args>(args)..., init, options);
94 },
95 std::get<Is>(numCoeffs))...);
96 }
97
98 template <typename... Objs, std::size_t... NumCoeffs>
100 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
101 enum init init, iganet::Options<value_type> options) {
102 return construct_tuple_from_arrays_impl<Objs...>(
103 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
104 }
106
110 template <typename... Objs, typename... NumCoeffsTuples, std::size_t... Is>
112 const std::tuple<NumCoeffsTuples...> &numCoeffs, enum init init,
113 iganet::Options<value_type> options, std::index_sequence<Is...>) {
114 static_assert(sizeof...(Objs) == sizeof...(NumCoeffsTuples));
115 return std::make_tuple(std::apply(
116 [&]<typename... Args>(Args &&...args) {
117 return Objs(std::forward<Args>(args)..., init, options);
118 },
119 std::get<Is>(numCoeffs))...);
120 }
121
122 template <typename... Objs, typename... NumCoeffsTuples>
123 auto
124 construct_tuple_from_tuples(const std::tuple<NumCoeffsTuples...> &numCoeffs,
125 enum init init,
127 return construct_tuple_from_tuples_impl<Objs...>(
128 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
129 }
131
132public:
135 explicit IgABase(
137 : inputs_(), outputs_(), collPts_() {}
138
147 template <std::size_t NumCoeffs>
148 explicit IgABase(
149 const std::array<int64_t, NumCoeffs> &ncoeffs,
150 enum init init = init::greville,
152 : IgABase(std::tuple{ncoeffs}, std::tuple{ncoeffs}, std::tuple{ncoeffs},
153 init, options) {}
154
164 template <std::size_t NumCoeffsInputs, std::size_t NumCoeffsOutputs,
165 std::size_t NumCoeffsCollPts>
166 IgABase(const std::array<int64_t, NumCoeffsInputs> &ncoeffsInputs,
167 const std::array<int64_t, NumCoeffsOutputs> &ncoeffsOutputs,
168 const std::array<int64_t, NumCoeffsCollPts> &ncoeffsCollPts,
169 enum init init = init::greville,
171 : IgABase(std::tuple{ncoeffsInputs}, std::tuple{ncoeffsOutputs},
172 std::tuple{ncoeffsCollPts}, init, options) {}
173
183 template <std::size_t... NumCoeffs>
184 explicit IgABase(
185 const std::tuple<std::array<int64_t, NumCoeffs>...> &ncoeffs,
186 enum init init = init::greville,
188 : IgABase(ncoeffs, ncoeffs, ncoeffs, init, options) {}
189
199 template <std::size_t... NumCoeffsInputs, std::size_t... NumCoeffsOutputs,
200 std::size_t... NumCoeffsCollPts>
202 const std::tuple<std::array<int64_t, NumCoeffsInputs>...> &ncoeffsInputs,
203 const std::tuple<std::array<int64_t, NumCoeffsOutputs>...>
204 &ncoeffsOutputs,
205 const std::tuple<std::array<int64_t, NumCoeffsCollPts>...>
206 &ncoeffsCollPts,
207 enum init init = init::greville,
209 : inputs_(construct_tuple_from_arrays<Inputs...>(ncoeffsInputs, init,
210 options)),
211 outputs_(construct_tuple_from_arrays<Outputs...>(ncoeffsOutputs, init,
212 options)),
213 collPts_(construct_tuple_from_arrays<Outputs...>(ncoeffsCollPts, init,
214 options)) {}
215
226 template <typename... CoeffsInputs, typename... CoeffsOutputs,
227 typename... CoeffsCollPts>
228 IgABase(const std::tuple<CoeffsInputs...> &coeffsInputs,
229 const std::tuple<CoeffsOutputs...> &coeffsOutputs,
230 const std::tuple<CoeffsCollPts...> &coeffsCollPts,
231 enum init init = init::greville,
233 : inputs_(construct_tuple_from_tuples<Inputs...>(coeffsInputs, init,
234 options)),
235 outputs_(construct_tuple_from_tuples<Outputs...>(coeffsOutputs, init,
236 options)),
237 collPts_(construct_tuple_from_tuples<CollPts...>(coeffsCollPts, init,
238 options)) {}
239
242 inline static constexpr std::size_t ninputs() noexcept {
243 return sizeof...(Inputs);
244 }
245
248 inline constexpr const auto &inputs() const { return inputs_; }
249
252 inline constexpr auto &inputs() { return inputs_; }
253
257 template <std::size_t index> inline constexpr const auto &input() const {
258 static_assert(index < sizeof...(Inputs));
259 return std::get<index>(inputs_);
260 }
261
265 template <std::size_t index> inline constexpr auto &input() {
266 static_assert(index < sizeof...(Inputs));
267 return std::get<index>(inputs_);
268 }
269
272 inline static constexpr std::size_t noutputs() noexcept {
273 return sizeof...(Outputs);
274 }
275
278 inline constexpr const auto &outputs() const { return outputs_; }
279
282 inline constexpr auto &outputs() { return outputs_; }
283
287 template <std::size_t index> inline constexpr const auto &output() const {
288 static_assert(index < sizeof...(Outputs));
289 return std::get<index>(outputs_);
290 }
291
295 template <std::size_t index> inline constexpr auto &output() {
296 static_assert(index < sizeof...(Outputs));
297 return std::get<index>(outputs_);
298 }
299
303 inline static constexpr std::size_t ncollPts() noexcept {
304 return sizeof...(CollPts);
305 }
306
310 inline constexpr const auto &collPts() const { return collPts_; }
311
315 inline constexpr auto &collPts() { return collPts_; }
316
326 template <std::size_t index>
327 std::tuple_element_t<index, collPts_type>
328 collPts(enum collPts collPts) const {
330 }
331};
332
333template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs>
334class IgABase<std::tuple<Inputs...>, std::tuple<Outputs...>, void> {
335public:
337 using value_type = std::common_type_t<typename Inputs::value_type...,
338 typename Outputs::value_type...>;
339
341 using inputs_type = std::tuple<Inputs...>;
342
344 template <std::size_t index>
345 using input_t = std::tuple_element_t<index, inputs_type>;
346
348 using outputs_type = std::tuple<Outputs...>;
349
351 template <std::size_t index>
352 using output_t = std::tuple_element_t<index, outputs_type>;
353
355 using collPts_type = std::tuple<typename CollPtsHelper<Outputs...>::type>;
356
358 template <std::size_t index>
359 using collPts_t = std::tuple_element_t<index, collPts_type>;
360
361protected:
364
367
368private:
372 template <typename... Objs, std::size_t... NumCoeffs, std::size_t... Is>
374 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
376 std::index_sequence<Is...>) {
377 static_assert(sizeof...(Objs) == sizeof...(NumCoeffs));
378 return std::make_tuple(Objs(std::get<Is>(numCoeffs), init, options)...);
379 }
380
381 template <typename... Objs, std::size_t... NumCoeffs>
383 const std::tuple<std::array<int64_t, NumCoeffs>...> &numCoeffs,
384 enum init init, iganet::Options<value_type> options) {
385 return construct_tuple_from_arrays_impl<Objs...>(
386 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
387 }
389
393 template <typename... Objs, typename... NumCoeffs, std::size_t... Is>
395 const std::tuple<NumCoeffs...> &numCoeffs, enum init init,
396 iganet::Options<value_type> options, std::index_sequence<Is...>) {
397 static_assert(sizeof...(Objs) == sizeof...(NumCoeffs));
398 return std::make_tuple(std::apply(
399 [&]<typename... Args>(Args &&...args) {
400 return Objs(std::forward<Args>(args)..., init, options);
401 },
402 std::get<Is>(numCoeffs))...);
403 }
404
405 template <typename... Objs, typename... NumCoeffsTuples>
406 auto
407 construct_tuple_from_tuples(const std::tuple<NumCoeffsTuples...> &numCoeffs,
408 enum init init,
410 return construct_tuple_from_tuples_impl<Objs...>(
411 numCoeffs, init, options, std::index_sequence_for<Objs...>{});
412 }
414
415public:
418 explicit IgABase(
420 : inputs_(), outputs_() {}
421
430 template <std::size_t NumCoeffs>
431 explicit IgABase(
432 const std::array<int64_t, NumCoeffs> &ncoeffs,
433 enum init init = init::greville,
435 : IgABase(std::tuple{ncoeffs}, std::tuple{ncoeffs}, init, options) {}
436
447 template <std::size_t NumCoeffsInputs, std::size_t NumCoeffsOutputs>
448 IgABase(const std::array<int64_t, NumCoeffsInputs> &ncoeffsInputs,
449 const std::array<int64_t, NumCoeffsOutputs> &ncoeffsOutputs,
450 enum init init = init::greville,
452 : IgABase(std::tuple{ncoeffsInputs}, std::tuple{ncoeffsOutputs}, init,
453 options) {}
454
464 template <std::size_t... NumCoeffs>
465 explicit IgABase(
466 const std::tuple<std::array<int64_t, NumCoeffs>...> &ncoeffs,
467 enum init init = init::greville,
469 : IgABase(ncoeffs, ncoeffs, init, options) {}
470
481 template <std::size_t... NumCoeffsInputs, std::size_t... NumCoeffsOutputs>
483 const std::tuple<std::array<int64_t, NumCoeffsInputs>...> &ncoeffsInputs,
484 const std::tuple<std::array<int64_t, NumCoeffsOutputs>...>
485 &ncoeffsOutputs,
486 enum init init = init::greville,
488 : inputs_(construct_tuple_from_arrays<Inputs...>(ncoeffsInputs, init,
489 options)),
490 outputs_(construct_tuple_from_arrays<Outputs...>(ncoeffsOutputs, init,
491 options)) {}
492
503 template <typename... CoeffsInputs, typename... CoeffsOutputs>
504 IgABase(const std::tuple<CoeffsInputs...> &coeffsInputs,
505 const std::tuple<CoeffsOutputs...> &coeffsOutputs,
506 enum init init = init::greville,
508 : inputs_(construct_tuple_from_tuples<Inputs...>(coeffsInputs, init,
509 options)),
510 outputs_(construct_tuple_from_tuples<Outputs...>(coeffsOutputs, init,
511 options)) {}
512
515 inline static constexpr std::size_t ninputs() noexcept {
516 return sizeof...(Inputs);
517 }
518
521 inline constexpr const auto &inputs() const { return inputs_; }
522
525 inline constexpr auto &inputs() { return inputs_; }
526
530 template <std::size_t index> inline constexpr const auto &input() const {
531 static_assert(index < sizeof...(Inputs));
532 return std::get<index>(inputs_);
533 }
534
538 template <std::size_t index> inline constexpr auto &input() {
539 static_assert(index < sizeof...(Inputs));
540 return std::get<index>(inputs_);
541 }
542
545 inline static constexpr std::size_t noutputs() noexcept {
546 return sizeof...(Outputs);
547 }
548
551 inline constexpr const auto &outputs() const { return outputs_; }
552
555 inline constexpr auto &outputs() { return outputs_; }
556
560 template <std::size_t index> inline constexpr const auto &output() const {
561 static_assert(index < sizeof...(Outputs));
562 return std::get<index>(outputs_);
563 }
564
568 template <std::size_t index> inline constexpr auto &output() {
569 static_assert(index < sizeof...(Outputs));
570 return std::get<index>(outputs_);
571 }
572
576 inline static constexpr std::size_t ncollPts() noexcept {
577 return sizeof...(Outputs);
578 }
579
583 inline constexpr const auto &collPts() const { return outputs_; }
584
588 inline constexpr auto &collPts() { return outputs_; }
589
599 template <std::size_t index>
600 std::tuple_element_t<index, collPts_type>
601 collPts(enum collPts collPts) const {
603 }
604};
606
610template <typename Optimizer, typename Inputs, typename Outputs,
611 typename CollPts = void>
612 requires OptimizerType<Optimizer>
613class IgANet : public IgABase<Inputs, Outputs, CollPts>,
616public:
619
621 using value_type = Base::value_type;
622
624 using optimizer_type = Optimizer;
625
628
629protected:
632
634 std::unique_ptr<optimizer_type> opt_;
635
638
639public:
643 explicit IgANet(const IgANetOptions &defaults = {},
646 : // Construct the base class
647 Base(),
648 // Construct the optimizer
649 opt_(std::make_unique<optimizer_type>(net_->parameters())),
650 // Set options
651 options_(defaults) {}
652
662 template <typename NumCoeffs>
663 IgANet(const std::vector<int64_t> &layers,
664 const std::vector<std::vector<std::any>> &activations,
665 const NumCoeffs &numCoeffs, enum init init = init::greville,
666 IgANetOptions defaults = {},
669 : IgANet(layers, activations, numCoeffs, numCoeffs, init, defaults,
670 options) {}
671
683 template <typename NumCoeffsInputs, typename NumCoeffsOutputs>
684 IgANet(const std::vector<int64_t> &layers,
685 const std::vector<std::vector<std::any>> &activations,
686 const NumCoeffsInputs &numCoeffsInputs,
687 const NumCoeffsOutputs &numCoeffsOutputs,
688 enum init init = init::greville, IgANetOptions defaults = {},
691 : // Construct the base class
692 Base(numCoeffsInputs, numCoeffsOutputs, init, options),
693 // Construct the deep neural network
694 net_(utils::concat(
695 std::vector<int64_t>{inputs(/* epoch */ 0).size(0)}, layers,
696 std::vector<int64_t>{outputs(/* epoch */ 0).size(0)}),
697 activations, options),
698
699 // Construct the optimizer
700 opt_(std::make_unique<optimizer_type>(net_->parameters())),
701
702 // Set options
703 options_(defaults) {}
704
708 return net_;
709 }
710
714
717 inline const optimizer_type &optimizer() const { return *opt_; }
718
721 inline optimizer_type &optimizer() { return *opt_; }
722
727 inline void optimizerReset(bool resetOptions = true) {
728 if (resetOptions)
729 opt_ = std::make_unique<optimizer_type>(net_->parameters());
730 else {
731 std::vector<optimizer_options_type> options;
732 for (auto &group : opt_->param_groups())
733 options.push_back(
734 static_cast<optimizer_options_type &>(group.options()));
735 opt_ = std::make_unique<optimizer_type>(net_->parameters());
736 for (auto [group, options] : utils::zip(opt_->param_groups(), options))
737 static_cast<optimizer_options_type &>(group.options()) = options;
738 }
739 }
740
744 opt_ =
745 std::make_unique<optimizer_type>(net_->parameters(), optimizerOptions);
746 }
747
751 inline optimizer_options_type &optimizerOptions(std::size_t param_group = 0) {
752 if (param_group < opt_->param_groups().size())
753 return static_cast<optimizer_options_type &>(
754 opt_->param_groups()[param_group].options());
755 else
756 throw std::runtime_error("Index exceeds number of parameter groups");
757 }
758
762 inline const optimizer_options_type &
763 optimizerOptions(std::size_t param_group = 0) const {
764 if (param_group < opt_->param_groups().size())
765 return static_cast<optimizer_options_type &>(
766 opt_->param_groups()[param_group].options());
767 else
768 throw std::runtime_error("Index exceeds number of parameter groups");
769 }
770
774 for (auto &group : opt_->param_groups())
775 static_cast<optimizer_options_type &>(group.options()) = options;
776 }
777
781 for (auto &group : opt_->param_groups())
782 static_cast<optimizer_options_type &>(group.options()) = options;
783 }
784
789 std::size_t param_group) {
790 if (param_group < opt_->param_groups().size())
791 static_cast<optimizer_options_type &>(opt_->param_group().options()) =
792 options;
793 else
794 throw std::runtime_error("Index exceeds number of parameter groups");
795 }
796
801 std::size_t param_group) {
802 if (param_group < opt_->param_groups().size())
803 static_cast<optimizer_options_type &>(opt_->param_group().options()) =
804 options;
805 else
806 throw std::runtime_error("Index exceeds number of parameter groups");
807 }
808
811 inline const auto &options() const { return options_; }
812
815 inline auto &options() { return options_; }
816
819 inline constexpr const auto &inputs() const { return Base::inputs(); }
820
823 inline constexpr auto &inputs() { return Base::inputs(); }
824
827 inline constexpr const auto &outputs() const { return Base::outputs(); }
828
831 inline constexpr auto &outputs() { return Base::outputs(); }
832
836 virtual torch::Tensor inputs(int64_t epoch) const {
838 Base::inputs_, [](const auto &obj) { return obj.as_tensor(); });
839 }
840
844 virtual torch::Tensor outputs(int64_t epoch) const {
846 Base::outputs_, [](const auto &obj) { return obj.as_tensor(); });
847 }
848
851 virtual void inputs(const torch::Tensor &tensor) {
853 Base::inputs_, tensor,
854 [](const auto &obj) { return obj.as_tensor_size(); },
855 [](auto &obj, const auto &tensor) { return obj.from_tensor(tensor); });
856 }
857
860 virtual void outputs(const torch::Tensor &tensor) {
862 Base::outputs_, tensor,
863 [](const auto &obj) { return obj.as_tensor_size(); },
864 [](auto &obj, const auto &tensor) { return obj.from_tensor(tensor); });
865 }
866
869 virtual bool epoch(int64_t) = 0;
870
873 virtual torch::Tensor loss(const torch::Tensor &, int64_t) = 0;
874
876 virtual void train(
877#ifdef IGANET_WITH_MPI
878 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
879 c10d::ProcessGroupMPI::createProcessGroupMPI()
880#endif
881 ) {
882 torch::Tensor inputs, outputs, loss;
883 typename Base::value_type previous_loss(-1.0);
884
885 // Loop over epochs
886 for (int64_t epoch = 0; epoch != options_.max_epoch(); ++epoch) {
887
888 // Update epoch and inputs
889 if (this->epoch(epoch))
890 inputs = this->inputs(epoch);
891
892 auto closure = [&]() {
893 // Reset gradients
894 net_->zero_grad();
895
896 // Execute the model on the inputs
897 outputs = net_->forward(inputs);
898
899 // Compute the loss value
900 loss = this->loss(outputs, epoch);
901
902 // Compute gradients of the loss w.r.t. the model parameters
903 loss.backward({}, true, false);
904
905 return loss;
906 };
907
908#ifdef IGANET_WITH_MPI
909 // Averaging the gradients of the parameters in all the processors
910 // Note: This may lag behind DistributedDataParallel (DDP) in performance
911 // since this synchronizes parameters after backward pass while DDP
912 // overlaps synchronizing parameters and computing gradients in backward
913 // pass
914 std::vector<c10::intrusive_ptr<::c10d::Work>> works;
915 for (auto &param : net_->named_parameters()) {
916 std::vector<torch::Tensor> tmp = {param.value().grad()};
917 works.emplace_back(pg->allreduce(tmp));
918 }
919
920 waitWork(pg, works);
921
922 for (auto &param : net_->named_parameters()) {
923 param.value().grad().data() =
924 param.value().grad().data() / pg->getSize();
925 }
926#endif
927
928 // Update the parameters based on the calculated gradients
929 opt_->step(closure);
930
931 typename Base::value_type current_loss =
932 loss.item<typename Base::value_type>();
933 Log(log::verbose) << "Epoch " << std::to_string(epoch) << ": "
934 << current_loss << std::endl;
935
936 if (current_loss < options_.min_loss() ||
937 std::abs(current_loss - previous_loss) < options_.min_loss_change() ||
938 std::abs(current_loss - previous_loss) / current_loss <
939 options_.min_loss_rel_change() ||
940 loss.isnan().item<bool>()) {
941 Log(log::info) << "Total epochs: " << epoch
942 << ", loss: " << current_loss << std::endl;
943 return;
944 }
945 previous_loss = current_loss;
946 }
947 Log(log::info) << "Max epochs reached: " << options_.max_epoch()
948 << ", loss: " << previous_loss << std::endl;
949 }
950
954#ifdef IGANET_WITH_MPI
956#endif
957 template <typename DataLoader>
958 void train(DataLoader &loader
959#ifdef IGANET_WITH_MPI
960 ,
961 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
962 c10d::ProcessGroupMPI::createProcessGroupMPI()
963#endif
964 ) {
965 torch::Tensor inputs, outputs, loss;
966 typename Base::value_type previous_loss(-1.0);
967
968 // Loop over epochs
969 for (int64_t epoch = 0; epoch != options_.max_epoch(); ++epoch) {
970
971 typename Base::value_type current_loss(0);
972
973 for (auto &batch : loader) {
974 inputs = batch.data;
975
976 if (inputs.dim() > 0) {
977 // if constexpr (Base::has_GeometryMap && Base::has_RefData) {
978 // Base::G_.from_tensor(
979 // inputs.slice(1, 0, Base::G_.as_tensor_size()).t());
980 // Base::f_.from_tensor(inputs
981 // .slice(1, Base::G_.as_tensor_size(),
982 // Base::G_.as_tensor_size() +
983 // Base::f_.as_tensor_size())
984 // .t());
985 // } else if constexpr (Base::has_GeometryMap && !Base::has_RefData)
986 // Base::G_.from_tensor(
987 // inputs.slice(1, 0, Base::G_.as_tensor_size()).t());
988 // else if constexpr (!Base::has_GeometryMap && Base::has_RefData)
989 // Base::f_.from_tensor(
990 // inputs.slice(1, 0, Base::f_.as_tensor_size()).t());
991
992 } else {
993 // if constexpr (Base::has_GeometryMap && Base::has_RefData) {
994 // Base::G_.from_tensor(
995 // inputs.slice(1, 0, Base::G_.as_tensor_size()).flatten());
996 // Base::f_.from_tensor(inputs
997 // .slice(1, Base::G_.as_tensor_size(),
998 // Base::G_.as_tensor_size() +
999 // Base::f_.as_tensor_size())
1000 // .flatten());
1001 // } else if constexpr (Base::has_GeometryMap && !Base::has_RefData)
1002 // Base::G_.from_tensor(
1003 // inputs.slice(1, 0, Base::G_.as_tensor_size()).flatten());
1004 // else if constexpr (!Base::has_GeometryMap && Base::has_RefData)
1005 // Base::f_.from_tensor(
1006 // inputs.slice(1, 0, Base::f_.as_tensor_size()).flatten());
1007 }
1008
1009 this->epoch(epoch);
1010
1011 auto closure = [&]() {
1012 // Reset gradients
1013 net_->zero_grad();
1014
1015 // Execute the model on the inputs
1016 outputs = net_->forward(inputs);
1017
1018 // Compute the loss value
1019 loss = this->loss(outputs, epoch);
1020
1021 // Compute gradients of the loss w.r.t. the model parameters
1022 loss.backward({}, true, false);
1023
1024 return loss;
1025 };
1026
1027 // Update the parameters based on the calculated gradients
1028 opt_->step(closure);
1029
1030 current_loss += loss.item<typename Base::value_type>();
1031 }
1032 Log(log::verbose) << "Epoch " << std::to_string(epoch) << ": "
1033 << current_loss << std::endl;
1034
1035 if (current_loss < options_.min_loss() ||
1036 std::abs(current_loss - previous_loss) < options_.min_loss_change() ||
1037 std::abs(current_loss - previous_loss) / current_loss <
1038 options_.min_loss_rel_change() ||
1039 loss.isnan().item<bool>()) {
1040 Log(log::info) << "Total epochs: " << epoch
1041 << ", loss: " << current_loss << std::endl;
1042 return;
1043 }
1044 previous_loss = current_loss;
1045 }
1046 Log(log::info) << "Max epochs reached: " << options_.max_epoch()
1047 << ", loss: " << previous_loss << std::endl;
1048 }
1049
1051 void eval() {
1052 torch::Tensor inputs = this->inputs(0);
1053 torch::Tensor outputs = net_->forward(inputs);
1054 this->outputs(outputs);
1055 }
1056
1059 inline nlohmann::json to_json() const override {
1060 return "Not implemented yet";
1061 }
1062
1065 inline std::vector<torch::Tensor> parameters() const noexcept {
1066 return net_->parameters();
1067 }
1068
1072 inline torch::OrderedDict<std::string, torch::Tensor>
1073 named_parameters() const noexcept {
1074 return net_->named_parameters();
1075 }
1076
1079 inline std::size_t nparameters() const noexcept {
1080 std::size_t result = 0;
1081 for (const auto &param : this->parameters()) {
1082 result += param.numel();
1083 }
1084 return result;
1085 }
1086
1092 torch::Tensor& register_parameter(std::string name, torch::Tensor tensor, bool requires_grad = true) {
1093 return net_->register_parameter(name, tensor, requires_grad);
1094 }
1095
1098 inline void pretty_print(std::ostream &os) const noexcept override {
1099 os << name() << "(\n"
1100 << "net = " << net_ << "\n";
1101
1102 os << "inputs[" << Base::ninputs() << "] = (";
1103 std::apply([&os](const auto &...elems) { ((os << elems << "\n"), ...); },
1104 Base::inputs());
1105 os << ")";
1106
1107 os << "outputs [" << Base::noutputs() << "]= (";
1108 std::apply([&os](const auto &...elems) { ((os << elems << "\n"), ...); },
1109 Base::inputs());
1110 os << ")";
1111
1112 os << "collPts [" << Base::ncollPts() << "]= (";
1113 std::apply([&os](const auto &...elems) { ((os << elems << "\n"), ...); },
1114 Base::collPts());
1115 os << ")";
1116 }
1117
1121 inline void save(const std::string &filename,
1122 const std::string &key = "iganet") const {
1123 torch::serialize::OutputArchive archive;
1124 write(archive, key).save_to(filename);
1125 }
1126
1130 inline void load(const std::string &filename,
1131 const std::string &key = "iganet") {
1132 torch::serialize::InputArchive archive;
1133 archive.load_from(filename);
1134 read(archive, key);
1135 }
1136
1141 inline torch::serialize::OutputArchive &
1142 write(torch::serialize::OutputArchive &archive,
1143 const std::string &key = "iganet") const {
1144
1145 std::apply(
1146 [&](auto &&...elems) {
1147 std::size_t counter = 0;
1148 (elems.write(archive,
1149 key + ".input[" + std::to_string(counter++) + "]"),
1150 ...);
1151 },
1152 Base::inputs());
1153
1154 std::apply(
1155 [&](auto &&...elems) {
1156 std::size_t counter = 0;
1157 (elems.write(archive,
1158 key + ".output[" + std::to_string(counter++) + "]"),
1159 ...);
1160 },
1161 Base::outputs());
1162
1163 if constexpr (!std::is_void_v<CollPts>) {
1164 std::apply(
1165 [&](auto &&...elems) {
1166 std::size_t counter = 0;
1167 (elems.write(archive,
1168 key + ".collpts[" + std::to_string(counter++) + "]"),
1169 ...);
1170 },
1171 Base::collPts());
1172 }
1173
1174 net_->write(archive, key + ".net");
1175 torch::serialize::OutputArchive archive_net;
1176 net_->save(archive_net);
1177 archive.write(key + ".net.data", archive_net);
1178
1179 torch::serialize::OutputArchive archive_opt;
1180 opt_->save(archive_opt);
1181 archive.write(key + ".opt", archive_opt);
1182
1183 return archive;
1184 }
1185
1190 inline torch::serialize::InputArchive &
1191 read(torch::serialize::InputArchive &archive,
1192 const std::string &key = "iganet") {
1193
1194 std::apply(
1195 [&](auto &&...elems) {
1196 std::size_t counter = 0;
1197 (elems.read(archive,
1198 key + ".input[" + std::to_string(counter++) + "]"),
1199 ...);
1200 },
1201 Base::inputs());
1202
1203 std::apply(
1204 [&](auto &&...elems) {
1205 std::size_t counter = 0;
1206 (elems.read(archive,
1207 key + ".output[" + std::to_string(counter++) + "]"),
1208 ...);
1209 },
1210 Base::outputs());
1211
1212 if constexpr (!std::is_void_v<CollPts>) {
1213 std::apply(
1214 [&](auto &&...elems) {
1215 std::size_t counter = 0;
1216 (elems.read(archive,
1217 key + ".collpts[" + std::to_string(counter++) + "]"),
1218 ...);
1219 },
1220 Base::collPts());
1221 }
1222
1223 net_->read(archive, key + ".net");
1224 torch::serialize::InputArchive archive_net;
1225 archive.read(key + ".net.data", archive_net);
1226 net_->load(archive_net);
1227
1228 opt_->add_parameters(net_->parameters());
1229 torch::serialize::InputArchive archive_opt;
1230 archive.read(key + ".opt", archive_opt);
1231 opt_->load(archive_opt);
1232
1233 return archive;
1234 }
1235
1239 bool operator==(const IgANet &other) const {
1240 bool result(true);
1241
1242 result *= std::apply(
1243 [&](auto &&...elemsThis) {
1244 return std::apply(
1245 [&](auto &&...elemsOther) {
1246 return ((elemsThis == elemsOther) && ...);
1247 },
1248 other.inputs());
1249 },
1250 Base::inputs());
1251
1252 return result;
1253 }
1254
1258 bool operator!=(const IgANet &other) const { return *this != other; }
1259
1260#ifdef IGANET_WITH_MPI
1261private:
1263 static void waitWork(c10::intrusive_ptr<c10d::ProcessGroupMPI> pg,
1264 std::vector<c10::intrusive_ptr<c10d::Work>> works) {
1265 for (auto &work : works) {
1266 try {
1267 work->wait();
1268 } catch (const std::exception &ex) {
1269 Log(log::error) << "Exception received during waitWork: " << ex.what()
1270 << std::endl;
1271 pg->abort();
1272 }
1273 }
1274 }
1275#endif
1276};
1277
1282template <typename Optimizer, typename Inputs, typename Outputs,
1283 typename CollPts>
1284 requires OptimizerType<Optimizer>
1285inline std::ostream &
1286operator<<(std::ostream &os,
1288 obj.pretty_print(os);
1289 return os;
1290}
1291
1299template <typename, typename, typename = void> class IgANetCustomizable;
1300
1301template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs>
1302class IgANetCustomizable<std::tuple<Inputs...>, std::tuple<Outputs...>, void> {
1303private:
1305 static auto find_interior_knot_indices(auto &&tuple) {
1306 return std::apply(
1307 []<typename... Elems>(Elems &&...elems) {
1308 return std::make_tuple(([&] {
1309 using T = std::decay_t<Elems>;
1311 return elems.template find_knot_indices<functionspace::interior>(
1312 typename T::eval_type{});
1313 else if constexpr (detail::HasFindKnotIndices<T>)
1314 // Note that this is a fake call here
1315 return elems.find_knot_indices(typename T::eval_type{});
1316 })()...);
1317 },
1318 tuple);
1319 }
1320
1322 static auto find_boundary_knot_indices(auto &&tuple) {
1323 return std::apply(
1324 []<typename... Elems>(Elems &&...elems) {
1325 return std::make_tuple(([&] {
1326 using T = std::decay_t<Elems>;
1328 return elems.template find_knot_indices<functionspace::boundary>(
1329 typename T::boundary_eval_type{});
1330 else if constexpr (detail::HasFindKnotIndices<T>)
1331 // Note that this is a fake call here
1332 return elems.find_knot_indices(typename T::eval_type{});
1333 })()...);
1334 },
1335 tuple);
1336 }
1337
1339 static auto find_interior_coeff_indices(auto &&tuple) {
1340 return std::apply(
1341 []<typename... Elems>(Elems &&...elems) {
1342 return std::make_tuple(([&] {
1343 using T = std::decay_t<Elems>;
1345 return elems.template find_coeff_indices<functionspace::interior>(
1346 typename T::eval_type{});
1347 else if constexpr (detail::HasFindCoeffIndices<T>)
1348 // Note that this is a fake call here
1349 return elems.find_coeff_indices(typename T::eval_type{});
1350 })()...);
1351 },
1352 tuple);
1353 }
1354
1356 static auto find_boundary_coeff_indices(auto &&tuple) {
1357 return std::apply(
1358 []<typename... Elems>(Elems &&...elems) {
1359 return std::make_tuple(([&] {
1360 using T = std::decay_t<Elems>;
1362 return elems.template find_coeff_indices<functionspace::boundary>(
1363 typename T::boundary_eval_type{});
1364 else if constexpr (detail::HasFindCoeffIndices<T>)
1365 // Note that this is a fake call here
1366 return elems.find_coeff_indices(typename T::eval_type{});
1367 })()...);
1368 },
1369 tuple);
1370 }
1371
1372public:
1374 using inputs_interior_knot_indices_type = decltype(find_interior_knot_indices(
1375 std::declval<std::tuple<Inputs...>>()));
1376
1379 template <std::size_t index>
1381 std::tuple_element_t<index, inputs_interior_knot_indices_type>;
1382
1384 using inputs_boundary_knot_indices_type = decltype(find_boundary_knot_indices(
1385 std::declval<std::tuple<Inputs...>>()));
1386
1389 template <std::size_t index>
1391 std::tuple_element_t<index, inputs_boundary_knot_indices_type>;
1392
1395 decltype(find_interior_knot_indices(
1396 std::declval<std::tuple<Outputs...>>()));
1397
1400 template <std::size_t index>
1402 std::tuple_element_t<index, outputs_interior_knot_indices_type>;
1403
1406 decltype(find_boundary_knot_indices(
1407 std::declval<std::tuple<Outputs...>>()));
1408
1411 template <std::size_t index>
1413 std::tuple_element_t<index, outputs_boundary_knot_indices_type>;
1414
1417 decltype(find_interior_coeff_indices(
1418 std::declval<std::tuple<Inputs...>>()));
1419
1422 template <std::size_t index>
1424 std::tuple_element_t<index, inputs_interior_coeff_indices_type>;
1425
1428 decltype(find_boundary_coeff_indices(
1429 std::declval<std::tuple<Inputs...>>()));
1430
1433 template <std::size_t index>
1435 std::tuple_element_t<index, inputs_boundary_coeff_indices_type>;
1436
1439 decltype(find_interior_coeff_indices(
1440 std::declval<std::tuple<Outputs...>>()));
1441
1444 template <std::size_t index>
1446 std::tuple_element_t<index, outputs_interior_coeff_indices_type>;
1447
1450 decltype(find_boundary_coeff_indices(
1451 std::declval<std::tuple<Outputs...>>()));
1452
1455 template <std::size_t index>
1457 std::tuple_element_t<index, outputs_boundary_coeff_indices_type>;
1458};
1459
1460template <detail::HasAsTensor... Inputs, detail::HasAsTensor... Outputs,
1461 detail::HasAsTensor... CollPts>
1462class IgANetCustomizable<std::tuple<Inputs...>, std::tuple<Outputs...>,
1463 std::tuple<CollPts...>>
1464 : public IgANetCustomizable<std::tuple<Inputs...>, std::tuple<Outputs...>,
1465 void> {
1466public:
1470 decltype(std::declval<CollPts>()
1471 .template find_knot_indices<functionspace::interior>(
1472 std::declval<typename CollPts::eval_type>()))...>;
1473
1477 decltype(std::declval<CollPts>()
1478 .template find_knot_indices<functionspace::boundary>(
1479 std::declval<
1480 typename CollPts::boundary_eval_type>()))...>;
1481
1485 decltype(std::declval<CollPts>()
1486 .template find_coeff_indices<functionspace::interior>(
1487 std::declval<typename CollPts::eval_type>()))...>;
1488
1492 decltype(std::declval<CollPts>()
1493 .template find_coeff_indices<functionspace::boundary>(
1494 std::declval<
1495 typename CollPts::boundary_eval_type>()))...>;
1496};
1497
1499
1500} // namespace iganet
Boundary treatment.
Definition unittest_iganet.cxx:22
IgABase(iganet::Options< value_type > options=iganet::Options< value_type >{})
Default constructor.
Definition iganet.hpp:135
constexpr const auto & outputs() const
Returns a constant reference to the tuple of output objects.
Definition iganet.hpp:278
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:201
std::tuple< typename CollPtsHelper< CollPts... >::type > collPts_type
Type of the collocation points.
Definition iganet.hpp:69
constexpr const auto & input() const
Returns a constant reference to the index-th input object.
Definition iganet.hpp:257
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:166
constexpr auto & output()
Returns a non-constant reference to the index-th output object.
Definition iganet.hpp:295
static constexpr std::size_t noutputs() noexcept
Returns the number of elements in the tuple of output objects.
Definition iganet.hpp:272
std::common_type_t< typename Inputs::value_type..., typename Outputs::value_type... > value_type
Value type.
Definition iganet.hpp:60
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:184
constexpr const auto & collPts() const
Returns a constant reference to the tuple of collocation points objects.
Definition iganet.hpp:310
std::tuple< Outputs... > outputs_type
Type of the outputs.
Definition iganet.hpp:66
std::tuple< Inputs... > inputs_type
Type of the inputs.
Definition iganet.hpp:63
static constexpr std::size_t ncollPts() noexcept
Returns the number of elements in the tuple of collocation points objects.
Definition iganet.hpp:303
constexpr const auto & inputs() const
Returns a constant reference to the tuple of input objects.
Definition iganet.hpp:248
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:99
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:228
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:86
constexpr auto & input()
Returns a non-constant reference to the index-th input object.
Definition iganet.hpp:265
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:328
static constexpr std::size_t ninputs() noexcept
Returns the number of elements in the tuple of input objects.
Definition iganet.hpp:242
constexpr auto & collPts()
Returns a non-constant reference to the tuple of collocation points objects.
Definition iganet.hpp:315
constexpr auto & inputs()
Returns a non-constant reference to the tuple of input objects.
Definition iganet.hpp:252
constexpr const auto & output() const
Returns a constant reference to the index-th output object.
Definition iganet.hpp:287
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:124
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:148
constexpr auto & outputs()
Returns a non-constant reference to the tuple of output objects.
Definition iganet.hpp:282
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:111
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:448
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:407
constexpr const auto & input() const
Returns a constant reference to the index-th input object.
Definition iganet.hpp:530
static constexpr std::size_t ncollPts() noexcept
Returns the number of elements in the tuple of collocation points objects.
Definition iganet.hpp:576
std::common_type_t< typename Inputs::value_type..., typename Outputs::value_type... > value_type
Value type.
Definition iganet.hpp:338
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:601
constexpr auto & output()
Returns a non-constant reference to the index-th output object.
Definition iganet.hpp:568
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:482
constexpr auto & inputs()
Returns a non-constant reference to the tuple of input objects.
Definition iganet.hpp:525
std::tuple< Inputs... > inputs_type
Type of the inputs.
Definition iganet.hpp:341
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:431
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:504
constexpr const auto & collPts() const
Returns a constant reference to the tuple of collocation points objects.
Definition iganet.hpp:583
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:373
std::tuple_element_t< index, outputs_type > output_t
Type alias for the type of the index-th outputs object.
Definition iganet.hpp:352
static constexpr std::size_t noutputs() noexcept
Returns the number of elements in the tuple of output objects.
Definition iganet.hpp:545
std::tuple_element_t< index, inputs_type > input_t
Type alias for the type of the index-th inputs object.
Definition iganet.hpp:345
IgABase(iganet::Options< value_type > options=iganet::Options< value_type >{})
Default constructor.
Definition iganet.hpp:418
constexpr auto & collPts()
Returns a non-constant reference to the tuple of collocation points objects.
Definition iganet.hpp:588
constexpr const auto & output() const
Returns a constant reference to the index-th output object.
Definition iganet.hpp:560
constexpr const auto & inputs() const
Returns a constant reference to the tuple of input objects.
Definition iganet.hpp:521
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:394
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:465
constexpr auto & input()
Returns a non-constant reference to the index-th input object.
Definition iganet.hpp:538
std::tuple< Outputs... > outputs_type
Type of the outputs.
Definition iganet.hpp:348
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:382
static constexpr std::size_t ninputs() noexcept
Returns the number of elements in the tuple of input objects.
Definition iganet.hpp:515
constexpr auto & outputs()
Returns a non-constant reference to the tuple of output objects.
Definition iganet.hpp:555
constexpr const auto & outputs() const
Returns a constant reference to the tuple of output objects.
Definition iganet.hpp:551
std::tuple< typename CollPtsHelper< Outputs... >::type > collPts_type
Type of the collocation points.
Definition iganet.hpp:355
std::tuple_element_t< index, collPts_type > collPts_t
Type alias for the type of the index-th collocation points object.
Definition iganet.hpp:359
IgA base class.
Definition iganet.hpp:51
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:1472
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:1487
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:1495
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:1480
static auto find_interior_coeff_indices(auto &&tuple)
Returns the interior coeff indices of all tuple elements.
Definition iganet.hpp:1339
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:1440
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:1435
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:1402
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:1407
static auto find_boundary_knot_indices(auto &&tuple)
Returns the boundary knot indices of all tuple elements.
Definition iganet.hpp:1322
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:1385
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:1446
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:1396
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:1451
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:1457
static auto find_interior_knot_indices(auto &&tuple)
Returns the interior knot indices of all tuple elements.
Definition iganet.hpp:1305
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:1391
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:1381
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:1429
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:1375
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:1413
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:1418
static auto find_boundary_coeff_indices(auto &&tuple)
Returns the boundary coeff indices of all tuple elements.
Definition iganet.hpp:1356
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:1424
IgANetGenerator.
Definition generator.hpp:940
IgANet.
Definition iganet.hpp:615
void optimizerReset(bool resetOptions=true)
Resets the optimizer.
Definition iganet.hpp:727
void optimizerReset(const optimizer_options_type &optimizerOptions)
Resets the optimizer.
Definition iganet.hpp:743
void load(const std::string &filename, const std::string &key="iganet")
Loads the IgANet from file.
Definition iganet.hpp:1130
constexpr auto & inputs()
Returns a non-constant reference to the tuple of input objects.
Definition iganet.hpp:823
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:1142
virtual void outputs(const torch::Tensor &tensor)
Attaches the given tensor to the outputs.
Definition iganet.hpp:860
void train(DataLoader &loader)
Trains the IgANet.
Definition iganet.hpp:958
const optimizer_type & optimizer() const
Returns a constant reference to the optimizer.
Definition iganet.hpp:717
void optimizerOptionsReset(optimizer_options_type &&options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:800
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:1073
Base::value_type value_type
Value type.
Definition iganet.hpp:621
std::vector< torch::Tensor > parameters() const noexcept
Returns a constant reference to the parameters of the IgANet object.
Definition iganet.hpp:1065
torch::Tensor & register_parameter(std::string name, torch::Tensor tensor, bool requires_grad=true)
Registers a parameter.
Definition iganet.hpp:1092
void save(const std::string &filename, const std::string &key="iganet") const
Saves the IgANet to file.
Definition iganet.hpp:1121
void optimizerOptionsReset(const optimizer_options_type &options)
Resets the optimizer options.
Definition iganet.hpp:773
IgANet(const IgANetOptions &defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Default constructor.
Definition iganet.hpp:643
optimizer_type & optimizer()
Returns a non-constant reference to the optimizer.
Definition iganet.hpp:721
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:1191
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:684
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:707
auto & options()
Returns a non-constant reference to the options structure.
Definition iganet.hpp:815
IgANetGenerator< typename Base::value_type > net_
IgANet generator.
Definition iganet.hpp:631
IgABase< Inputs, Outputs, CollPts > Base
Base type.
Definition iganet.hpp:618
std::unique_ptr< optimizer_type > opt_
Optimizer.
Definition iganet.hpp:634
bool operator!=(const IgANet &other) const
Returns true if both IgANet objects are different.
Definition iganet.hpp:1258
IgANetOptions options_
Options.
Definition iganet.hpp:637
constexpr auto & outputs()
Returns a non-constant reference to the tuple of output objects.
Definition iganet.hpp:831
optimizer_options_type & optimizerOptions(std::size_t param_group=0)
Returns a non-constant reference to the optimizer options.
Definition iganet.hpp:751
virtual torch::Tensor outputs(int64_t epoch) const
Returns the network outputs as tensor.
Definition iganet.hpp:844
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:663
virtual void train()
Trains the IgANet.
Definition iganet.hpp:876
std::size_t nparameters() const noexcept
Returns the total number of parameters of the IgANet object.
Definition iganet.hpp:1079
Optimizer optimizer_type
Type of the optimizer.
Definition iganet.hpp:624
void optimizerOptionsReset(optimizer_options_type &&options)
Resets the optimizer options.
Definition iganet.hpp:780
optimizer_options_type< Optimizer >::type optimizer_options_type
Type of the optimizer options.
Definition iganet.hpp:627
virtual torch::Tensor inputs(int64_t epoch) const
Returns the network inputs as tensor.
Definition iganet.hpp:836
void pretty_print(std::ostream &os) const noexcept override
Returns a string representation of the IgANet object.
Definition iganet.hpp:1098
virtual void inputs(const torch::Tensor &tensor)
Attaches the given tensor to the inputs.
Definition iganet.hpp:851
bool operator==(const IgANet &other) const
Returns true if both IgANet objects are the same.
Definition iganet.hpp:1239
nlohmann::json to_json() const override
Returns the IgANet object as JSON object.
Definition iganet.hpp:1059
void optimizerOptionsReset(const optimizer_options_type &options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:788
constexpr const auto & inputs() const
Returns a constant reference to the tuple of input objects.
Definition iganet.hpp:819
constexpr const auto & outputs() const
Returns a constant reference to the tuple of output objects.
Definition iganet.hpp:827
void eval()
Evaluate IgANet.
Definition iganet.hpp:1051
const auto & options() const
Returns a constant reference to the options structure.
Definition iganet.hpp:811
IgANetGenerator< typename Base::value_type > & net()
Returns a non-constant reference to the IgANet generator.
Definition iganet.hpp:713
const optimizer_options_type & optimizerOptions(std::size_t param_group=0) const
Returns a constant reference to the optimizer options.
Definition iganet.hpp:763
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:47
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:32
Definition bspline.hpp:123
Definition bspline.hpp:116
Definition functionspace.hpp:54
Definition functionspace.hpp:47
Container utility functions.
Full qualified name utility functions.
Function spaces.
Network generator.
auto zip(T &&...seqs)
Provides the zip operation.
Definition zip.hpp:135
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:140
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:87
Definition core.hpp:73
collPts
Enumerator for the collocation point specifier.
Definition collocation.hpp:21
std::ostream & operator<<(std::ostream &os, const MemoryDebugger< id > &obj)
Prints a memory debugger object.
Definition memory.hpp:145
struct iganet::@0 Log
Logger.
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:58
Collocation points helper
Definition collocation.hpp:35
IgANetCustomizable.
Definition iganet.hpp:1299
Type trait for the optimizer options type.
Definition optimizer.hpp:32
STL namespace.
Optimizier type traits.
Options.
IgANetOptions.
Definition iganet.hpp:34
TORCH_ARG(double, min_loss_change)=0
Provides the TORCH_ARG operation.
TORCH_ARG(int64_t, batch_size)
Provides the TORCH_ARG operation.
TORCH_ARG(double, min_loss)
Provides the TORCH_ARG operation.
TORCH_ARG(double, min_loss_rel_change)
Provides the TORCH_ARG operation.
TORCH_ARG(int64_t, max_epoch)
Provides the TORCH_ARG operation.
Serialization prototype.
Definition serialize.hpp:29
Tuple utility functions.
Zip utility function.