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::v1 {
29
33 TORCH_ARG(int64_t, max_epoch) = 100;
35 TORCH_ARG(int64_t, batch_size) = 1000;
37 TORCH_ARG(double, min_loss) = 1e-4;
39 TORCH_ARG(double, min_loss_change) = 0;
41 TORCH_ARG(double, min_loss_rel_change) = 1e-3;
42 };
43
48template <typename GeometryMap, typename Variable>
50class [[deprecated("Use novel IgANet implementation")]] IgABaseNoRefData {
51public:
53 using value_type = std::common_type_t<typename GeometryMap::value_type,
54 typename Variable::value_type>;
55
57 using geometryMap_type = GeometryMap;
58
60 using variable_type = Variable;
61
64 std::pair<typename GeometryMap::eval_type,
65 typename GeometryMap::boundary_eval_type>;
66
69 std::pair<typename Variable::eval_type,
70 typename Variable::boundary_eval_type>;
71
73 bool static constexpr has_GeometryMap = true;
74
76 bool static constexpr has_RefData = false;
77
79 bool static constexpr has_Solution = true;
80
81protected:
83 GeometryMap G_;
84
86 Variable u_;
87
88private:
91 template <std::size_t... GeometryMapNumCoeffs, std::size_t... Is,
92 std::size_t... VariableNumCoeffs, std::size_t... Js>
94 std::tuple<std::array<int64_t, GeometryMapNumCoeffs>...>
95 geometryMapNumCoeffs,
96 std::index_sequence<Is...>,
97 std::tuple<std::array<int64_t, VariableNumCoeffs>...> variableNumCoeffs,
98 std::index_sequence<Js...>,
100 : // Construct the different spline objects individually
101 G_(std::get<Is>(geometryMapNumCoeffs)..., init::greville, options),
102 u_(std::get<Js>(variableNumCoeffs)..., init::random, options) {}
103
104public:
109 : G_(), u_() {}
110
117 template <std::size_t NumCoeffs>
119 std::array<int64_t, NumCoeffs> numCoeffs,
121 : IgABaseNoRefData(std::tuple{numCoeffs}, std::tuple{numCoeffs},
122 options) {}
123
128 template <std::size_t... NumCoeffs>
130 std::tuple<std::array<int64_t, NumCoeffs>...> numCoeffs,
132 : IgABaseNoRefData(numCoeffs, numCoeffs, options) {}
134
143 template <std::size_t GeometryMapNumCoeffs, std::size_t VariableNumCoeffs>
145 std::array<int64_t, GeometryMapNumCoeffs> geometryMapNumCoeffs,
146 std::array<int64_t, VariableNumCoeffs> variableNumCoeffs,
148 : IgABaseNoRefData(std::tuple{geometryMapNumCoeffs},
149 std::tuple{variableNumCoeffs}, options) {}
150
155 template <std::size_t... GeometryMapNumCoeffs,
156 std::size_t... VariableNumCoeffs>
158 std::tuple<std::array<int64_t, GeometryMapNumCoeffs>...>
159 geometryMapNumCoeffs,
160 std::tuple<std::array<int64_t, VariableNumCoeffs>...> variableNumCoeffs,
163 geometryMapNumCoeffs,
164 std::make_index_sequence<sizeof...(GeometryMapNumCoeffs)>{},
165 variableNumCoeffs,
166 std::make_index_sequence<sizeof...(VariableNumCoeffs)>{}, options) {
167 }
169
171 virtual ~IgABaseNoRefData() = default;
172
176 inline const GeometryMap &G() const { return G_; }
177
181 inline GeometryMap &G() { return G_; }
182
186 inline const Variable &u() const { return u_; }
187
191 inline Variable &u() { return u_; }
192
193private:
200 template <std::size_t... Is>
201 geometryMap_collPts_type
202 geometryMap_collPts(enum collPts collPtsType,
203 std::index_sequence<Is...>) const {
205
206 switch (collPtsType) {
207
208 case collPts::greville:
209 // Get Greville abscissae inside the domain and at the boundary
210 ((std::get<Is>(collPts.first) =
211 G_.template space<Is>().greville(/* interior */ false)),
212 ...);
213
214 // Get Greville abscissae at the domain
215 ((std::get<Is>(collPts.second) = G_.template boundary<Is>().greville()),
216 ...);
217 break;
218
219 case collPts::greville_interior:
220 // Get Greville abscissae inside the domain
221 ((std::get<Is>(collPts.first) =
222 G_.template space<Is>().greville(/* interior */ true)),
223 ...);
224
225 // Get Greville abscissae at the domain
226 ((std::get<Is>(collPts.second) = G_.template boundary<Is>().greville()),
227 ...);
228 break;
229
230 case collPts::greville_ref1:
231 // Get Greville abscissae inside the domain and at the boundary
232 ((std::get<Is>(collPts.first) =
233 G_.template space<Is>().clone().uniform_refine().greville(
234 /* interior */ false)),
235 ...);
236
237 // Get Greville abscissae at the domain
238 ((std::get<Is>(collPts.second) =
239 G_.template boundary<Is>().clone().uniform_refine().greville()),
240 ...);
241 break;
242
243 case collPts::greville_interior_ref1:
244 // Get Greville abscissae inside the domain
245 ((std::get<Is>(collPts.first) =
246 G_.template space<Is>().clone().uniform_refine().greville(
247 /* interior */ true)),
248 ...);
249
250 // Get Greville abscissae at the domain
251 ((std::get<Is>(collPts.second) =
252 G_.template boundary<Is>().clone().uniform_refine().greville()),
253 ...);
254 break;
255
256 case collPts::greville_ref2:
257 // Get Greville abscissae inside the domain and at the boundary
258 ((std::get<Is>(collPts.first) =
259 G_.template space<Is>().clone().uniform_refine(2, -1).greville(
260 /* interior */ false)),
261 ...);
262
263 // Get Greville abscissae at the domain
264 ((std::get<Is>(collPts.second) = G_.template boundary<Is>()
265 .clone()
266 .uniform_refine(2, -1)
267 .greville()),
268 ...);
269 break;
270
271 case collPts::greville_interior_ref2:
272 // Get Greville abscissae inside the domain
273 ((std::get<Is>(collPts.first) =
274 G_.template space<Is>().clone().uniform_refine(2, -1).greville(
275 /* interior */ true)),
276 ...);
277
278 // Get Greville abscissae at the domain
279 ((std::get<Is>(collPts.second) = G_.template boundary<Is>()
280 .clone()
281 .uniform_refine(2, -1)
282 .greville()),
283 ...);
284 break;
285
286 case collPts::greville_ref3:
287 // Get Greville abscissae inside the domain and at the boundary
288 ((std::get<Is>(collPts.first) =
289 G_.template space<Is>().clone().uniform_refine(3, -1).greville(
290 /* interior */ false)),
291 ...);
292
293 // Get Greville abscissae at the domain
294 ((std::get<Is>(collPts.second) = G_.template boundary<Is>()
295 .clone()
296 .uniform_refine(3, -1)
297 .greville()),
298 ...);
299 break;
300
301 case collPts::greville_interior_ref3:
302 // Get Greville abscissae inside the domain
303 ((std::get<Is>(collPts.first) =
304 G_.template space<Is>().clone().uniform_refine(3, -1).greville(
305 /* interior */ true)),
306 ...);
307
308 // Get Greville abscissae at the domain
309 ((std::get<Is>(collPts.second) = G_.template boundary<Is>()
310 .clone()
311 .uniform_refine(3, -1)
312 .greville()),
313 ...);
314 break;
315
316 default:
317 throw std::runtime_error("Invalid collocation point specifier");
318 }
319
320 return collPts;
321 }
322
329 template <std::size_t... Is>
331 std::index_sequence<Is...>) const {
333
334 switch (collPtsType) {
335
336 case collPts::greville:
337 // Get Greville abscissae inside the domain and at the boundary
338 ((std::get<Is>(collPts.first) =
339 u_.template space<Is>().greville(/* interior */ false)),
340 ...);
341
342 // Get Greville abscissae at the domain
343 ((std::get<Is>(collPts.second) = u_.template boundary<Is>().greville()),
344 ...);
345 break;
346
347 case collPts::greville_interior:
348 // Get Greville abscissae inside the domain and at the boundary
349 ((std::get<Is>(collPts.first) =
350 u_.template space<Is>().greville(/* interior */ true)),
351 ...);
352
353 // Get Greville abscissae at the domain
354 ((std::get<Is>(collPts.second) = u_.template boundary<Is>().greville()),
355 ...);
356 break;
357
358 case collPts::greville_ref1:
359 // Get Greville abscissae inside the domain and at the boundary
360 ((std::get<Is>(collPts.first) =
361 u_.template space<Is>().clone().uniform_refine().greville(
362 /* interior */ false)),
363 ...);
364
365 // Get Greville abscissae at the domain
366 ((std::get<Is>(collPts.second) =
367 u_.template boundary<Is>().clone().uniform_refine().greville()),
368 ...);
369 break;
370
371 case collPts::greville_interior_ref1:
372 // Get Greville abscissae inside the domain and at the boundary
373 ((std::get<Is>(collPts.first) =
374 u_.template space<Is>().clone().uniform_refine().greville(
375 /* interior */ true)),
376 ...);
377
378 // Get Greville abscissae at the domain
379 ((std::get<Is>(collPts.second) =
380 u_.template boundary<Is>().clone().uniform_refine().greville()),
381 ...);
382 break;
383
384 case collPts::greville_ref2:
385 // Get Greville abscissae inside the domain and at the boundary
386 ((std::get<Is>(collPts.first) =
387 u_.template space<Is>().clone().uniform_refine(2, -1).greville(
388 /* interior */ false)),
389 ...);
390
391 // Get Greville abscissae at the domain
392 ((std::get<Is>(collPts.second) = u_.template boundary<Is>()
393 .clone()
394 .uniform_refine(2, -1)
395 .greville()),
396 ...);
397 break;
398
399 case collPts::greville_interior_ref2:
400 // Get Greville abscissae inside the domain and at the boundary
401 ((std::get<Is>(collPts.first) =
402 u_.template space<Is>().clone().uniform_refine(2, -1).greville(
403 /* interior */ true)),
404 ...);
405
406 // Get Greville abscissae at the domain
407 ((std::get<Is>(collPts.second) = u_.template boundary<Is>()
408 .clone()
409 .uniform_refine(2, -1)
410 .greville()),
411 ...);
412 break;
413
414 case collPts::greville_ref3:
415 // Get Greville abscissae inside the domain and at the boundary
416 ((std::get<Is>(collPts.first) =
417 u_.template space<Is>().clone().uniform_refine(3, -1).greville(
418 /* interior */ false)),
419 ...);
420
421 // Get Greville abscissae at the domain
422 ((std::get<Is>(collPts.second) = u_.template boundary<Is>()
423 .clone()
424 .uniform_refine(3, -1)
425 .greville()),
426 ...);
427 break;
428
429 case collPts::greville_interior_ref3:
430 // Get Greville abscissae inside the domain and at the boundary
431 ((std::get<Is>(collPts.first) =
432 u_.template space<Is>().clone().uniform_refine(3, -1).greville(
433 /* interior */ true)),
434 ...);
435
436 // Get Greville abscissae at the domain
437 ((std::get<Is>(collPts.second) = u_.template boundary<Is>()
438 .clone()
439 .uniform_refine(3, -1)
440 .greville()),
441 ...);
442 break;
443
444 default:
445 throw std::runtime_error("Invalid collocation point specifier");
446 }
447
448 return collPts;
449 }
450
451public:
460 virtual geometryMap_collPts_type
462 if constexpr (GeometryMap::nspaces() == 1)
463
464 switch (collPts) {
465
466 case collPts::greville:
467 return {G_.space().greville(/* interior */ false),
468 G_.boundary().greville()};
469
470 case collPts::greville_interior:
471 return {G_.space().greville(/* interior */ true),
472 G_.boundary().greville()};
473
474 case collPts::greville_ref1:
475 return {
476 G_.space().clone().uniform_refine().greville(/* interior */ false),
477 G_.boundary().clone().uniform_refine().greville()};
478
479 case collPts::greville_interior_ref1:
480 return {
481 G_.space().clone().uniform_refine().greville(/* interior */ true),
482 G_.boundary().clone().uniform_refine().greville()};
483
484 case collPts::greville_ref2:
485 return {G_.space().clone().uniform_refine(2, -1).greville(
486 /* interior */ false),
487 G_.boundary().clone().uniform_refine(2, -1).greville()};
488
489 case collPts::greville_interior_ref2:
490 return {G_.space().clone().uniform_refine(2, -1).greville(
491 /* interior */ true),
492 G_.boundary().clone().uniform_refine(2, -1).greville()};
493
494 case collPts::greville_ref3:
495 return {G_.space().clone().uniform_refine(3, -1).greville(
496 /* interior */ false),
497 G_.boundary().clone().uniform_refine(3, -1).greville()};
498
499 case collPts::greville_interior_ref3:
500 return {G_.space().clone().uniform_refine(3, -1).greville(
501 /* interior */ true),
502 G_.boundary().clone().uniform_refine(3, -1).greville()};
503
504 default:
505 throw std::runtime_error("Invalid collocation point specifier");
506 }
507
508 else
509 return geometryMap_collPts(
510 collPts, std::make_index_sequence<GeometryMap::nspaces()>{});
511 }
512
522 if constexpr (Variable::nspaces() == 1)
523
524 switch (collPts) {
525
526 case collPts::greville:
527 return {u_.space().greville(/* interior */ false),
528 u_.boundary().greville()};
529
530 case collPts::greville_interior:
531 return {u_.space().greville(/* interior */ true),
532 u_.boundary().greville()};
533
534 case collPts::greville_ref1:
535 return {
536 u_.space().clone().uniform_refine().greville(/* interior */ false),
537 u_.boundary().clone().uniform_refine().greville()};
538
539 case collPts::greville_interior_ref1:
540 return {
541 u_.space().clone().uniform_refine().greville(/* interior */ true),
542 u_.boundary().clone().uniform_refine().greville()};
543
544 case collPts::greville_ref2:
545 return {u_.space().clone().uniform_refine(2, -1).greville(
546 /* interior */ false),
547 u_.boundary().clone().uniform_refine(2, -1).greville()};
548
549 case collPts::greville_interior_ref2:
550 return {u_.space().clone().uniform_refine(2, -1).greville(
551 /* interior */ true),
552 u_.boundary().clone().uniform_refine(2, -1).greville()};
553
554 case collPts::greville_ref3:
555 return {u_.space().clone().uniform_refine(3, -1).greville(
556 /* interior */ false),
557 u_.boundary().clone().uniform_refine(3, -1).greville()};
558
559 case collPts::greville_interior_ref3:
560 return {u_.space().clone().uniform_refine(3, -1).greville(
561 /* interior */ true),
562 u_.boundary().clone().uniform_refine(3, -1).greville()};
563
564 default:
565 throw std::runtime_error("Invalid collocation point specifier");
566 }
567
568 else
569 return variable_collPts(collPts,
570 std::make_index_sequence<Variable::nspaces()>{});
571 }
572};
573
577template <typename GeometryMap, typename Variable>
579class [[deprecated("Use novel IgANet implementation")]] IgABase : public IgABaseNoRefData<GeometryMap, Variable> {
580public:
583
586
588 using geometryMap_type = GeometryMap;
589
591 using variable_type = Variable;
592
595
598
600 bool static constexpr has_GeometryMap = true;
601
603 bool static constexpr has_RefData = true;
604
606 bool static constexpr has_Solution = true;
607
608protected:
610 Variable f_;
611
612private:
615 template <std::size_t... GeometryMapNumCoeffs, std::size_t... Is,
616 std::size_t... VariableNumCoeffs, std::size_t... Js>
618 std::tuple<std::array<int64_t, GeometryMapNumCoeffs>...>
619 geometryMapNumCoeffs,
620 std::index_sequence<Is...>,
621 std::tuple<std::array<int64_t, VariableNumCoeffs>...> variableNumCoeffs,
622 std::index_sequence<Js...>,
624 : // Construct the different spline objects individually
625 Base(geometryMapNumCoeffs, variableNumCoeffs, options),
626 f_(std::get<Js>(variableNumCoeffs)..., init::zeros, options) {}
627
628public:
631 explicit IgABase(
633 : Base(), f_() {}
634
641 template <std::size_t NumCoeffs>
642 explicit IgABase(
643 std::array<int64_t, NumCoeffs> numCoeffs,
645 : IgABase(std::tuple{numCoeffs}, std::tuple{numCoeffs}, options) {}
646
651 template <std::size_t... NumCoeffs>
652 explicit IgABase(
653 std::tuple<std::array<int64_t, NumCoeffs>...> numCoeffs,
655 : IgABase(numCoeffs, numCoeffs, options) {}
657
666 template <std::size_t GeometryMapNumCoeffs, std::size_t VariableNumCoeffs>
667 IgABase(std::array<int64_t, GeometryMapNumCoeffs> geometryMapNumCoeffs,
668 std::array<int64_t, VariableNumCoeffs> variableNumCoeffs,
670 : IgABase(std::tuple{geometryMapNumCoeffs}, std::tuple{variableNumCoeffs},
671 options) {}
672
677 template <std::size_t... GeometryMapNumCoeffs,
678 std::size_t... VariableNumCoeffs>
680 std::tuple<std::array<int64_t, GeometryMapNumCoeffs>...>
681 geometryMapNumCoeffs,
682 std::tuple<std::array<int64_t, VariableNumCoeffs>...> variableNumCoeffs,
684 : IgABase(geometryMapNumCoeffs,
685 std::make_index_sequence<sizeof...(GeometryMapNumCoeffs)>{},
686 variableNumCoeffs,
687 std::make_index_sequence<sizeof...(VariableNumCoeffs)>{},
688 options) {}
690
694 inline const Variable &f() const { return f_; }
695
699 inline Variable &f() { return f_; }
700};
701
705template <typename Optimizer, typename GeometryMap, typename Variable,
706 template <typename, typename> typename IgABase = IgABase>
709class [[deprecated("Use novel IgANet implementation")]] IgANet : public IgABase<GeometryMap, Variable>,
712public:
715
717 using optimizer_type = Optimizer;
718
721
722protected:
725
727 std::unique_ptr<optimizer_type> opt_;
728
731
732public:
736 explicit IgANet(const IgANetOptions &defaults = {},
739 : // Construct the base class
740 Base(),
741 // Construct the optimizer
742 opt_(std::make_unique<optimizer_type>(net_->parameters())),
743 // Set options
744 options_(defaults) {}
745
756 template <std::size_t NumCoeffs>
757 IgANet(const std::vector<int64_t> &layers,
758 const std::vector<std::vector<std::any>> &activations,
759 std::array<int64_t, NumCoeffs> numCoeffs, IgANetOptions defaults = {},
762 : IgANet(layers, activations, std::tuple{numCoeffs},
763 std::tuple{numCoeffs}, defaults, options) {}
764
772 template <std::size_t... NumCoeffs>
773 IgANet(const std::vector<int64_t> &layers,
774 const std::vector<std::vector<std::any>> &activations,
775 std::tuple<std::array<int64_t, NumCoeffs>...> numCoeffs,
776 IgANetOptions defaults = {},
779 : IgANet(layers, activations, numCoeffs, numCoeffs, defaults, options) {}
781
794 template <std::size_t GeometryMapNumCoeffs, std::size_t VariableNumCoeffs>
795 IgANet(const std::vector<int64_t> &layers,
796 const std::vector<std::vector<std::any>> &activations,
797 std::array<int64_t, GeometryMapNumCoeffs> geometryMapNumCoeffs,
798 std::array<int64_t, VariableNumCoeffs> variableNumCoeffs,
799 IgANetOptions defaults = {},
802 : IgANet(layers, activations, std::tuple{geometryMapNumCoeffs},
803 std::tuple{variableNumCoeffs}, defaults, options) {}
804
812 template <std::size_t... GeometryMapNumCoeffs,
813 std::size_t... VariableNumCoeffs>
815 const std::vector<int64_t> &layers,
816 const std::vector<std::vector<std::any>> &activations,
817 std::tuple<std::array<int64_t, GeometryMapNumCoeffs>...>
818 geometryMapNumCoeffs,
819 std::tuple<std::array<int64_t, VariableNumCoeffs>...> variableNumCoeffs,
820 IgANetOptions defaults = {},
823 : // Construct the base class
824 Base(geometryMapNumCoeffs, variableNumCoeffs, options),
825 // Construct the deep neural network
826 net_(utils::concat(std::vector<int64_t>{inputs(/* epoch */ 0).size(0)},
827 layers,
828 std::vector<int64_t>{Base::u_.as_tensor_size()}),
829 activations, options),
830
831 // Construct the optimizer
832 opt_(std::make_unique<optimizer_type>(net_->parameters())),
833
834 // Set options
835 options_(defaults) {}
836
840 return net_;
841 }
842
846
849 inline const optimizer_type &optimizer() const { return *opt_; }
850
853 inline optimizer_type &optimizer() { return *opt_; }
854
859 inline void optimizerReset(bool resetOptions = true) {
860 if (resetOptions)
861 opt_ = std::make_unique<optimizer_type>(net_->parameters());
862 else {
863 std::vector<optimizer_options_type> options;
864 for (auto &group : opt_->param_groups())
865 options.push_back(
866 static_cast<optimizer_options_type &>(group.options()));
867 opt_ = std::make_unique<optimizer_type>(net_->parameters());
868 for (auto [group, options] : utils::zip(opt_->param_groups(), options))
869 static_cast<optimizer_options_type &>(group.options()) = options;
870 }
871 }
872
875 inline void optimizerReset(const optimizer_options_type &optimizerOptions) {
876 opt_ =
877 std::make_unique<optimizer_type>(net_->parameters(), optimizerOptions);
878 }
879
883 inline optimizer_options_type &optimizerOptions(std::size_t param_group = 0) {
884 if (param_group < opt_->param_groups().size())
885 return static_cast<optimizer_options_type &>(
886 opt_->param_groups()[param_group].options());
887 else
888 throw std::runtime_error("Index exceeds number of parameter groups");
889 }
890
894 inline const optimizer_options_type &
895 optimizerOptions(std::size_t param_group = 0) const {
896 if (param_group < opt_->param_groups().size())
897 return static_cast<optimizer_options_type &>(
898 opt_->param_groups()[param_group].options());
899 else
900 throw std::runtime_error("Index exceeds number of parameter groups");
901 }
902
905 inline void optimizerOptionsReset(const optimizer_options_type &options) {
906 for (auto &group : opt_->param_groups())
907 static_cast<optimizer_options_type &>(group.options()) = options;
908 }
909
913 for (auto &group : opt_->param_groups())
914 static_cast<optimizer_options_type &>(group.options()) = options;
915 }
916
921 std::size_t param_group) {
922 if (param_group < opt_->param_groups().size())
923 static_cast<optimizer_options_type &>(opt_->param_group().options()) =
924 options;
925 else
926 throw std::runtime_error("Index exceeds number of parameter groups");
927 }
928
933 std::size_t param_group) {
934 if (param_group < opt_->param_groups().size())
935 static_cast<optimizer_options_type &>(opt_->param_group().options()) =
936 options;
937 else
938 throw std::runtime_error("Index exceeds number of parameter groups");
939 }
940
943 inline const auto &options() const { return options_; }
944
947 inline auto &options() { return options_; }
948
957 virtual torch::Tensor inputs(int64_t epoch) const {
958 if constexpr (Base::has_GeometryMap && Base::has_RefData)
959 return torch::cat({Base::G_.as_tensor(), Base::f_.as_tensor()});
960 else if constexpr (Base::has_GeometryMap && !Base::has_RefData)
961 return Base::G_.as_tensor();
962 else if constexpr (!Base::has_GeometryMap && Base::has_RefData)
963 return Base::f_.as_tensor();
964 else
965 return torch::empty({0});
966 }
967
970 virtual bool epoch(int64_t) = 0;
971
974 virtual torch::Tensor loss(const torch::Tensor &, int64_t) = 0;
975
977 virtual void train(
978#ifdef IGANET_WITH_MPI
979 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
980 c10d::ProcessGroupMPI::createProcessGroupMPI()
981#endif
982 ) {
983 torch::Tensor inputs, outputs, loss;
984 typename Base::value_type previous_loss(-1.0);
985
986 // Loop over epochs
987 for (int64_t epoch = 0; epoch != options_.max_epoch(); ++epoch) {
988
989 // Update epoch and inputs
990 if (this->epoch(epoch))
991 inputs = this->inputs(epoch);
992
993 auto closure = [&]() {
994 // Reset gradients
995 net_->zero_grad();
996
997 // Execute the model on the inputs
998 outputs = net_->forward(inputs);
999
1000 // Compute the loss value
1001 loss = this->loss(outputs, epoch);
1002
1003 // Compute gradients of the loss w.r.t. the model parameters
1004 loss.backward({}, true, false);
1005
1006 return loss;
1007 };
1008
1009#ifdef IGANET_WITH_MPI
1010 // Averaging the gradients of the parameters in all the processors
1011 // Note: This may lag behind DistributedDataParallel (DDP) in performance
1012 // since this synchronizes parameters after backward pass while DDP
1013 // overlaps synchronizing parameters and computing gradients in backward
1014 // pass
1015 std::vector<c10::intrusive_ptr<::c10d::Work>> works;
1016 for (auto &param : net_->named_parameters()) {
1017 std::vector<torch::Tensor> tmp = {param.value().grad()};
1018 works.emplace_back(pg->allreduce(tmp));
1019 }
1020
1021 waitWork(pg, works);
1022
1023 for (auto &param : net_->named_parameters()) {
1024 param.value().grad().data() =
1025 param.value().grad().data() / pg->getSize();
1026 }
1027#endif
1028
1029 // Update the parameters based on the calculated gradients
1030 opt_->step(closure);
1031
1032 typename Base::value_type current_loss =
1033 loss.item<typename Base::value_type>();
1034 Log(log::verbose) << "Epoch " << std::to_string(epoch) << ": "
1035 << current_loss << std::endl;
1036
1037 if (current_loss < options_.min_loss() ||
1038 std::abs(current_loss - previous_loss) < options_.min_loss_change() ||
1039 std::abs(current_loss - previous_loss) / current_loss <
1040 options_.min_loss_rel_change() ||
1041 loss.isnan().item<bool>()) {
1042 Log(log::info) << "Total epochs: " << epoch
1043 << ", loss: " << current_loss << std::endl;
1044 return;
1045 }
1046 previous_loss = current_loss;
1047 }
1048 Log(log::info) << "Max epochs reached: " << options_.max_epoch()
1049 << ", loss: " << previous_loss << std::endl;
1050 }
1051
1055#ifdef IGANET_WITH_MPI
1057#endif
1058 template <typename DataLoader>
1059 void train(DataLoader &loader
1060#ifdef IGANET_WITH_MPI
1061 ,
1062 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
1063 c10d::ProcessGroupMPI::createProcessGroupMPI()
1064#endif
1065 ) {
1066 torch::Tensor inputs, outputs, loss;
1067 typename Base::value_type previous_loss(-1.0);
1068
1069 // Loop over epochs
1070 for (int64_t epoch = 0; epoch != options_.max_epoch(); ++epoch) {
1071
1072 typename Base::value_type current_loss(0);
1073
1074 for (auto &batch : loader) {
1075 inputs = batch.data;
1076
1077 if (inputs.dim() > 0) {
1078 if constexpr (Base::has_GeometryMap && Base::has_RefData) {
1079 Base::G_.from_tensor(
1080 inputs.slice(1, 0, Base::G_.as_tensor_size()).t());
1081 Base::f_.from_tensor(inputs
1082 .slice(1, Base::G_.as_tensor_size(),
1083 Base::G_.as_tensor_size() +
1084 Base::f_.as_tensor_size())
1085 .t());
1086 } else if constexpr (Base::has_GeometryMap && !Base::has_RefData)
1087 Base::G_.from_tensor(
1088 inputs.slice(1, 0, Base::G_.as_tensor_size()).t());
1089 else if constexpr (!Base::has_GeometryMap && Base::has_RefData)
1090 Base::f_.from_tensor(
1091 inputs.slice(1, 0, Base::f_.as_tensor_size()).t());
1092
1093 } else {
1094 if constexpr (Base::has_GeometryMap && Base::has_RefData) {
1095 Base::G_.from_tensor(
1096 inputs.slice(1, 0, Base::G_.as_tensor_size()).flatten());
1097 Base::f_.from_tensor(inputs
1098 .slice(1, Base::G_.as_tensor_size(),
1099 Base::G_.as_tensor_size() +
1100 Base::f_.as_tensor_size())
1101 .flatten());
1102 } else if constexpr (Base::has_GeometryMap && !Base::has_RefData)
1103 Base::G_.from_tensor(
1104 inputs.slice(1, 0, Base::G_.as_tensor_size()).flatten());
1105 else if constexpr (!Base::has_GeometryMap && Base::has_RefData)
1106 Base::f_.from_tensor(
1107 inputs.slice(1, 0, Base::f_.as_tensor_size()).flatten());
1108 }
1109
1110 this->epoch(epoch);
1111
1112 auto closure = [&]() {
1113 // Reset gradients
1114 net_->zero_grad();
1115
1116 // Execute the model on the inputs
1117 outputs = net_->forward(inputs);
1118
1119 // Compute the loss value
1120 loss = this->loss(outputs, epoch);
1121
1122 // Compute gradients of the loss w.r.t. the model parameters
1123 loss.backward({}, true, false);
1124
1125 return loss;
1126 };
1127
1128 // Update the parameters based on the calculated gradients
1129 opt_->step(closure);
1130
1131 current_loss += loss.item<typename Base::value_type>();
1132 }
1133 Log(log::verbose) << "Epoch " << std::to_string(epoch) << ": "
1134 << current_loss << std::endl;
1135
1136 if (current_loss < options_.min_loss() ||
1137 std::abs(current_loss - previous_loss) < options_.min_loss_change() ||
1138 std::abs(current_loss - previous_loss) / current_loss <
1139 options_.min_loss_rel_change() ||
1140 loss.isnan().item<bool>()) {
1141 Log(log::info) << "Total epochs: " << epoch
1142 << ", loss: " << current_loss << std::endl;
1143 return;
1144 }
1145 previous_loss = current_loss;
1146 }
1147 Log(log::info) << "Max epochs reached: " << options_.max_epoch()
1148 << ", loss: " << previous_loss << std::endl;
1149 }
1150
1152 void eval() {
1153 torch::Tensor inputs = this->inputs(0);
1154 torch::Tensor outputs = net_->forward(inputs);
1155 Base::u_.from_tensor(outputs);
1156 }
1157
1160 inline nlohmann::json to_json() const override {
1161 return "Not implemented yet";
1162 }
1163
1166 inline std::vector<torch::Tensor> parameters() const noexcept {
1167 return net_->parameters();
1168 }
1169
1173 inline torch::OrderedDict<std::string, torch::Tensor>
1174 named_parameters() const noexcept {
1175 return net_->named_parameters();
1176 }
1177
1180 inline std::size_t nparameters() const noexcept {
1181 std::size_t result = 0;
1182 for (const auto &param : this->parameters()) {
1183 result += param.numel();
1184 }
1185 return result;
1186 }
1187
1193 torch::Tensor& register_parameter(std::string name, torch::Tensor tensor, bool requires_grad = true) {
1194 return net_->register_parameter(name, tensor, requires_grad);
1195 }
1196
1199 inline void pretty_print(std::ostream &os) const noexcept override {
1200 os << name() << "(\n"
1201 << "net = " << net_ << "\n";
1202 if constexpr (Base::has_GeometryMap)
1203 os << "G = " << Base::G_ << "\n";
1204 if constexpr (Base::has_RefData)
1205 os << "f = " << Base::f_ << "\n";
1206 if constexpr (Base::has_Solution)
1207 os << "u = " << Base::u_ << "\n)";
1208 }
1209
1213 inline void save(const std::string &filename,
1214 const std::string &key = "iganet") const {
1215 torch::serialize::OutputArchive archive;
1216 write(archive, key).save_to(filename);
1217 }
1218
1222 inline void load(const std::string &filename,
1223 const std::string &key = "iganet") {
1224 torch::serialize::InputArchive archive;
1225 archive.load_from(filename);
1226 read(archive, key);
1227 }
1228
1233 inline torch::serialize::OutputArchive &
1234 write(torch::serialize::OutputArchive &archive,
1235 const std::string &key = "iganet") const {
1236 if constexpr (Base::has_GeometryMap)
1237 Base::G_.write(archive, key + ".geo");
1238 if constexpr (Base::has_RefData)
1239 Base::f_.write(archive, key + ".ref");
1240 if constexpr (Base::has_Solution)
1241 Base::u_.write(archive, key + ".out");
1242
1243 net_->write(archive, key + ".net");
1244 torch::serialize::OutputArchive archive_net;
1245 net_->save(archive_net);
1246 archive.write(key + ".net.data", archive_net);
1247
1248 torch::serialize::OutputArchive archive_opt;
1249 opt_->save(archive_opt);
1250 archive.write(key + ".opt", archive_opt);
1251
1252 return archive;
1253 }
1254
1259 inline torch::serialize::InputArchive &
1260 read(torch::serialize::InputArchive &archive,
1261 const std::string &key = "iganet") {
1262 if constexpr (Base::has_GeometryMap)
1263 Base::G_.read(archive, key + ".geo");
1264 if constexpr (Base::has_RefData)
1265 Base::f_.read(archive, key + ".ref");
1266 if constexpr (Base::has_Solution)
1267 Base::u_.read(archive, key + ".out");
1268
1269 net_->read(archive, key + ".net");
1270 torch::serialize::InputArchive archive_net;
1271 archive.read(key + ".net.data", archive_net);
1272 net_->load(archive_net);
1273
1274 opt_->add_parameters(net_->parameters());
1275 torch::serialize::InputArchive archive_opt;
1276 archive.read(key + ".opt", archive_opt);
1277 opt_->load(archive_opt);
1278
1279 return archive;
1280 }
1281
1285 bool operator==(const IgANet &other) const {
1286 bool result(true);
1287
1288 if constexpr (Base::has_GeometryMap)
1289 result *= (Base::G_ == other.G());
1290 if constexpr (Base::has_RefData)
1291 result *= (Base::f_ == other.f());
1292 if constexpr (Base::has_Solution)
1293 result *= (Base::u_ == other.u());
1294
1295 return result;
1296 }
1297
1301 bool operator!=(const IgANet &other) const { return *this != other; }
1302
1303#ifdef IGANET_WITH_MPI
1304private:
1306 static void waitWork(c10::intrusive_ptr<c10d::ProcessGroupMPI> pg,
1307 std::vector<c10::intrusive_ptr<c10d::Work>> works) {
1308 for (auto &work : works) {
1309 try {
1310 work->wait();
1311 } catch (const std::exception &ex) {
1312 Log(log::error) << "Exception received during waitWork: " << ex.what()
1313 << std::endl;
1314 pg->abort();
1315 }
1316 }
1317 }
1318#endif
1319};
1320
1328template <typename Optimizer, typename GeometryMap, typename Variable>
1329 requires OptimizerType<Optimizer> && FunctionSpaceType<GeometryMap> &&
1330 FunctionSpaceType<Variable>
1331inline std::ostream &
1332operator<<(std::ostream &os,
1334 obj.pretty_print(os);
1335 return os;
1336}
1337
1343template <typename GeometryMap, typename Variable>
1345class [[deprecated("Use novel IgANetCustomizable implementation")]] IgANetCustomizable {
1346public:
1349 decltype(std::declval<GeometryMap>()
1350 .template find_knot_indices<functionspace::interior>(
1351 std::declval<typename GeometryMap::eval_type>()));
1352
1355 decltype(std::declval<GeometryMap>()
1356 .template find_knot_indices<functionspace::boundary>(
1357 std::declval<
1358 typename GeometryMap::boundary_eval_type>()));
1359
1362 decltype(std::declval<Variable>()
1363 .template find_knot_indices<functionspace::interior>(
1364 std::declval<typename Variable::eval_type>()));
1365
1368 decltype(std::declval<Variable>()
1369 .template find_knot_indices<functionspace::boundary>(
1370 std::declval<typename Variable::boundary_eval_type>()));
1371
1374 decltype(std::declval<GeometryMap>()
1375 .template find_coeff_indices<functionspace::interior>(
1376 std::declval<typename GeometryMap::eval_type>()));
1377
1380 decltype(std::declval<GeometryMap>()
1381 .template find_coeff_indices<functionspace::boundary>(
1382 std::declval<
1383 typename GeometryMap::boundary_eval_type>()));
1384
1387 decltype(std::declval<Variable>()
1388 .template find_coeff_indices<functionspace::interior>(
1389 std::declval<typename Variable::eval_type>()));
1390
1393 decltype(std::declval<Variable>()
1394 .template find_coeff_indices<functionspace::boundary>(
1395 std::declval<typename Variable::boundary_eval_type>()));
1396};
1397
1398} // namespace iganet::v1
Boundary treatment.
IgA base class.
Definition iganet.hpp:51
IgANetGenerator.
Definition generator.hpp:940
IgANet.
Definition iganet.hpp:615
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
IgA base class.
Definition iganet.hpp:579
Base::variable_collPts_type variable_collPts_type
Type of the variable collocation points.
Definition iganet.hpp:597
IgABase(std::tuple< std::array< int64_t, GeometryMapNumCoeffs >... > geometryMapNumCoeffs, std::tuple< std::array< int64_t, VariableNumCoeffs >... > variableNumCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Provides the IgABase operation.
Definition iganet.hpp:679
GeometryMap geometryMap_type
Type of the geometry map function space(s).
Definition iganet.hpp:588
Variable & f()
Returns a non-constant reference to the spline representation of the reference data.
Definition iganet.hpp:699
Base::value_type value_type
Value type.
Definition iganet.hpp:585
IgABase(std::array< int64_t, GeometryMapNumCoeffs > geometryMapNumCoeffs, std::array< int64_t, VariableNumCoeffs > variableNumCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor: number of spline coefficients (different for geometry map and variables)
Definition iganet.hpp:667
IgABase(iganet::Options< value_type > options=iganet::Options< value_type >{})
Default constructor.
Definition iganet.hpp:631
const Variable & f() const
Returns a constant reference to the spline representation of the reference data.
Definition iganet.hpp:694
IgABase(std::tuple< std::array< int64_t, NumCoeffs >... > numCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Provides the IgABase operation.
Definition iganet.hpp:652
IgABase(std::tuple< std::array< int64_t, GeometryMapNumCoeffs >... > geometryMapNumCoeffs, std::index_sequence< Is... >, std::tuple< std::array< int64_t, VariableNumCoeffs >... > variableNumCoeffs, std::index_sequence< Js... >, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor: number of spline coefficients (different for Geometry and Variable types).
Definition iganet.hpp:617
Variable f_
Spline representation of the reference data.
Definition iganet.hpp:610
Variable variable_type
Type of the variable function space(s).
Definition iganet.hpp:591
Base::geometryMap_collPts_type geometryMap_collPts_type
Type of the geometry map collocation points.
Definition iganet.hpp:594
IgABase(std::array< int64_t, NumCoeffs > numCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor: number of spline coefficients (same for geometry map and variables)
Definition iganet.hpp:642
IgA base class (no reference data).
Definition iganet.hpp:50
virtual ~IgABaseNoRefData()=default
Destructor.
std::pair< typename Variable::eval_type, typename Variable::boundary_eval_type > variable_collPts_type
Type of the variable collocation points.
Definition iganet.hpp:70
IgABaseNoRefData(std::array< int64_t, GeometryMapNumCoeffs > geometryMapNumCoeffs, std::array< int64_t, VariableNumCoeffs > variableNumCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor: number of spline coefficients (different for geometry map and variables)
Definition iganet.hpp:144
GeometryMap G_
Spline representation of the geometry map.
Definition iganet.hpp:83
Variable variable_type
Type of the variable function space(s).
Definition iganet.hpp:60
Variable & u()
Returns a non-constant reference to the spline representation of the solution.
Definition iganet.hpp:191
GeometryMap & G()
Returns a non-constant reference to the spline representation of the geometry map.
Definition iganet.hpp:181
variable_collPts_type variable_collPts(enum collPts collPtsType, std::index_sequence< Is... >) const
Returns the variable collocation points.
Definition iganet.hpp:330
virtual geometryMap_collPts_type geometryMap_collPts(enum collPts collPts) const
Returns the geometry map collocation points.
Definition iganet.hpp:461
IgABaseNoRefData(iganet::Options< value_type > options=iganet::Options< value_type >{})
Default constructor.
Definition iganet.hpp:107
Variable u_
Spline representation of the solution.
Definition iganet.hpp:86
virtual variable_collPts_type variable_collPts(enum collPts collPts) const
Returns the variable collocation points.
Definition iganet.hpp:521
IgABaseNoRefData(std::tuple< std::array< int64_t, NumCoeffs >... > numCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Provides the IgABaseNoRefData operation.
Definition iganet.hpp:129
std::pair< typename GeometryMap::eval_type, typename GeometryMap::boundary_eval_type > geometryMap_collPts_type
Type of the geometry map collocation points.
Definition iganet.hpp:65
GeometryMap geometryMap_type
Type of the geometry map function space(s).
Definition iganet.hpp:57
const GeometryMap & G() const
Returns a constant reference to the spline representation of the geometry map.
Definition iganet.hpp:176
const Variable & u() const
Returns a constant reference to the spline representation of the solution.
Definition iganet.hpp:186
IgABaseNoRefData(std::array< int64_t, NumCoeffs > numCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor: number of spline coefficients (same for geometry map and variables)
Definition iganet.hpp:118
IgABaseNoRefData(std::tuple< std::array< int64_t, GeometryMapNumCoeffs >... > geometryMapNumCoeffs, std::index_sequence< Is... >, std::tuple< std::array< int64_t, VariableNumCoeffs >... > variableNumCoeffs, std::index_sequence< Js... >, iganet::Options< value_type > options=iganet::Options< value_type >{})
Constructor: number of spline coefficients (different for Geometry and Variable types).
Definition iganet.hpp:93
geometryMap_collPts_type geometryMap_collPts(enum collPts collPtsType, std::index_sequence< Is... >) const
Returns the geometry map collocation points.
Definition iganet.hpp:202
std::common_type_t< typename GeometryMap::value_type, typename Variable::value_type > value_type
Value type.
Definition iganet.hpp:54
IgABaseNoRefData(std::tuple< std::array< int64_t, GeometryMapNumCoeffs >... > geometryMapNumCoeffs, std::tuple< std::array< int64_t, VariableNumCoeffs >... > variableNumCoeffs, iganet::Options< value_type > options=iganet::Options< value_type >{})
Provides the IgABaseNoRefData operation.
Definition iganet.hpp:157
IgANetCustomizable.
Definition iganet.hpp:1345
decltype(std::declval< GeometryMap >() .template find_knot_indices< functionspace::boundary >(std::declval< typename GeometryMap::boundary_eval_type >())) geometryMap_boundary_knot_indices_type
Type of the knot indices of the geometry map at the boundary.
Definition iganet.hpp:1358
decltype(std::declval< Variable >() .template find_coeff_indices< functionspace::interior >(std::declval< typename Variable::eval_type >())) variable_interior_coeff_indices_type
Type of the coefficient indices of variable type in the interior.
Definition iganet.hpp:1389
decltype(std::declval< GeometryMap >() .template find_coeff_indices< functionspace::interior >(std::declval< typename GeometryMap::eval_type >())) geometryMap_interior_coeff_indices_type
Type of the coefficient indices of geometry type in the interior.
Definition iganet.hpp:1376
decltype(std::declval< Variable >() .template find_coeff_indices< functionspace::boundary >(std::declval< typename Variable::boundary_eval_type >())) variable_boundary_coeff_indices_type
Type of the coefficient indices of variable type at the boundary.
Definition iganet.hpp:1395
decltype(std::declval< Variable >() .template find_knot_indices< functionspace::interior >(std::declval< typename Variable::eval_type >())) variable_interior_knot_indices_type
Type of the knot indices of the variables in the interior.
Definition iganet.hpp:1364
decltype(std::declval< GeometryMap >() .template find_coeff_indices< functionspace::boundary >(std::declval< typename GeometryMap::boundary_eval_type >())) geometryMap_boundary_coeff_indices_type
Type of the coefficient indices of geometry type at the boundary.
Definition iganet.hpp:1383
decltype(std::declval< GeometryMap >() .template find_knot_indices< functionspace::interior >(std::declval< typename GeometryMap::eval_type >())) geometryMap_interior_knot_indices_type
Type of the knot indices of the geometry map in the interior.
Definition iganet.hpp:1351
decltype(std::declval< Variable >() .template find_knot_indices< functionspace::boundary >(std::declval< typename Variable::boundary_eval_type >())) variable_boundary_knot_indices_type
Type of the knot indices of boundary_eval_type type at the boundary.
Definition iganet.hpp:1370
IgANet.
Definition iganet.hpp:711
auto & options()
Returns a non-constant reference to the options structure.
Definition iganet.hpp:947
virtual torch::Tensor inputs(int64_t epoch) const
Returns the network inputs.
Definition iganet.hpp:957
void optimizerOptionsReset(optimizer_options_type &&options)
Resets the optimizer options.
Definition iganet.hpp:912
Optimizer optimizer_type
Type of the optimizer.
Definition iganet.hpp:717
IgANetOptions options_
Options.
Definition iganet.hpp:730
bool operator==(const IgANet &other) const
Returns true if both IgANet objects are the same.
Definition iganet.hpp:1285
optimizer_options_type & optimizerOptions(std::size_t param_group=0)
Returns a non-constant reference to the optimizer options.
Definition iganet.hpp:883
void train(DataLoader &loader)
Trains the IgANet.
Definition iganet.hpp:1059
torch::Tensor & register_parameter(std::string name, torch::Tensor tensor, bool requires_grad=true)
Registers a parameter.
Definition iganet.hpp:1193
virtual void train()
Trains the IgANet.
Definition iganet.hpp:977
nlohmann::json to_json() const override
Returns the IgANet object as JSON object.
Definition iganet.hpp:1160
optimizer_type & optimizer()
Returns a non-constant reference to the optimizer.
Definition iganet.hpp:853
void eval()
Evaluate IgANet.
Definition iganet.hpp:1152
IgANet(const IgANetOptions &defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Default constructor.
Definition iganet.hpp:736
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:1234
IgANet(const std::vector< int64_t > &layers, const std::vector< std::vector< std::any > > &activations, std::array< int64_t, GeometryMapNumCoeffs > geometryMapNumCoeffs, std::array< int64_t, VariableNumCoeffs > variableNumCoeffs, 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 (different for...
Definition iganet.hpp:795
const IgANetGenerator< typename Base::value_type > & net() const
Returns a constant reference to the IgANet generator.
Definition iganet.hpp:839
void load(const std::string &filename, const std::string &key="iganet")
Loads the IgANet from file.
Definition iganet.hpp:1222
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:1174
IgANet(const std::vector< int64_t > &layers, const std::vector< std::vector< std::any > > &activations, std::array< int64_t, NumCoeffs > numCoeffs, 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 geom...
Definition iganet.hpp:757
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:1260
IgANetGenerator< typename Base::value_type > & net()
Returns a non-constant reference to the IgANet generator.
Definition iganet.hpp:845
const optimizer_options_type & optimizerOptions(std::size_t param_group=0) const
Returns a constant reference to the optimizer options.
Definition iganet.hpp:895
optimizer_options_type< Optimizer >::type optimizer_options_type
Type of the optimizer options.
Definition iganet.hpp:720
std::unique_ptr< optimizer_type > opt_
Optimizer.
Definition iganet.hpp:727
void optimizerReset(const optimizer_options_type &optimizerOptions)
Resets the optimizer.
Definition iganet.hpp:875
bool operator!=(const IgANet &other) const
Returns true if both IgANet objects are different.
Definition iganet.hpp:1301
virtual bool epoch(int64_t)=0
Initializes epoch.
void optimizerReset(bool resetOptions=true)
Resets the optimizer.
Definition iganet.hpp:859
IgANetGenerator< typename Base::value_type > net_
IgANet generator.
Definition iganet.hpp:724
std::size_t nparameters() const noexcept
Returns the total number of parameters of the IgANet object.
Definition iganet.hpp:1180
IgANet(const std::vector< int64_t > &layers, const std::vector< std::vector< std::any > > &activations, std::tuple< std::array< int64_t, GeometryMapNumCoeffs >... > geometryMapNumCoeffs, std::tuple< std::array< int64_t, VariableNumCoeffs >... > variableNumCoeffs, IgANetOptions defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Provides the IgANet operation.
Definition iganet.hpp:814
IgANet(const std::vector< int64_t > &layers, const std::vector< std::vector< std::any > > &activations, std::tuple< std::array< int64_t, NumCoeffs >... > numCoeffs, IgANetOptions defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Provides the IgANet operation.
Definition iganet.hpp:773
void optimizerOptionsReset(const optimizer_options_type &options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:920
void optimizerOptionsReset(optimizer_options_type &&options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:932
void pretty_print(std::ostream &os) const noexcept override
Returns a string representation of the IgANet object.
Definition iganet.hpp:1199
virtual torch::Tensor loss(const torch::Tensor &, int64_t)=0
Computes the loss function.
const optimizer_type & optimizer() const
Returns a constant reference to the optimizer.
Definition iganet.hpp:849
void optimizerOptionsReset(const optimizer_options_type &options)
Resets the optimizer options.
Definition iganet.hpp:905
std::vector< torch::Tensor > parameters() const noexcept
Returns a constant reference to the parameters of the IgANet object.
Definition iganet.hpp:1166
const auto & options() const
Returns a constant reference to the options structure.
Definition iganet.hpp:943
void save(const std::string &filename, const std::string &key="iganet") const
Saves the IgANet to file.
Definition iganet.hpp:1213
Isogeometric analysis base class.
Concept to identify template parameters that are derived from iganet::details::FunctionSpaceType.
Definition functionspace.hpp:3646
Concept to identify template parameters that are derived from torch::optim::Optimizer.
Definition optimizer.hpp:26
Container utility functions.
Full qualified name utility functions.
Function spaces.
Network generator.
Definition iganet.hpp:28
std::ostream & operator<<(std::ostream &os, const IgANet< Optimizer, GeometryMap, Variable > &obj)
Prints an IgANet object.
Definition iganet.hpp:1332
collPts
Enumerator for the collocation point specifier.
Definition collocation.hpp:21
struct iganet::@0 Log
Logger.
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:58
Type trait for the optimizer options type.
Definition optimizer.hpp:32
STL namespace.
Optimizier type traits.
Options.
Serialization prototype.
Definition serialize.hpp:29
IgANetOptions.
Definition iganet.hpp:31
TORCH_ARG(double, min_loss_rel_change)
Provides the TORCH_ARG operation.
TORCH_ARG(int64_t, max_epoch)
Provides the TORCH_ARG operation.
TORCH_ARG(int64_t, batch_size)
Provides the TORCH_ARG operation.
TORCH_ARG(double, min_loss_change)=0
Provides the TORCH_ARG operation.
TORCH_ARG(double, min_loss)
Provides the TORCH_ARG operation.
Tuple utility functions.
Zip utility function.