47template <
typename real_t>
55 const std::vector<int64_t> &layers,
56 const std::vector<std::vector<std::any>> &activations,
58 assert(layers.size() == activations.size() + 1);
61 for (
auto i = 0; i < layers.size() - 1; ++i) {
63 register_module(
"layer[" + std::to_string(i) +
"]",
64 torch::nn::Linear(layers[i], layers[i + 1])));
65 layers_.back()->to(options.device(), options.dtype(),
true);
67 torch::nn::init::xavier_uniform_(
layers_.back()->weight);
68 torch::nn::init::constant_(
layers_.back()->bias, 0.0);
72 for (
const auto &a : activations)
81 throw std::runtime_error(
"Invalid number of parameters");
90 std::any_cast<torch::Tensor>(a[1]),
91 std::any_cast<torch::Tensor>(a[2]),
92 std::any_cast<torch::Tensor>(a[3]),
93 std::any_cast<torch::Tensor>(a[4]), std::any_cast<double>(a[5]),
94 std::any_cast<double>(a[6]), std::any_cast<bool>(a[7])});
98 std::any_cast<torch::Tensor>(a[1]),
99 std::any_cast<torch::Tensor>(a[2]),
100 std::any_cast<torch::Tensor>(a[3]),
101 std::any_cast<torch::Tensor>(a[4]), std::any_cast<double>(a[5]),
102 std::any_cast<double>(a[6])});
106 std::any_cast<torch::Tensor>(a[1]),
107 std::any_cast<torch::Tensor>(a[2]),
108 std::any_cast<torch::nn::functional::BatchNormFuncOptions>(
113 new BatchNorm{std::any_cast<torch::Tensor>(a[1]),
114 std::any_cast<torch::Tensor>(a[2])});
117 throw std::runtime_error(
"Invalid number of parameters");
126 new CELU{std::any_cast<double>(a[1]), std::any_cast<bool>(a[2])});
131 std::any_cast<torch::nn::functional::CELUFuncOptions>(a[1])});
133 activations_.emplace_back(
new CELU{std::any_cast<double>(a[1])});
140 throw std::runtime_error(
"Invalid number of parameters");
149 new ELU{std::any_cast<double>(a[1]), std::any_cast<bool>(a[2])});
154 std::any_cast<torch::nn::functional::ELUFuncOptions>(a[1])});
156 activations_.emplace_back(
new ELU{std::any_cast<double>(a[1])});
163 throw std::runtime_error(
"Invalid number of parameters");
174 throw std::runtime_error(
"Invalid number of parameters");
184 std::any_cast<torch::nn::functional::GLUFuncOptions>(a[1])});
186 activations_.emplace_back(
new GLU{std::any_cast<int64_t>(a[1])});
193 throw std::runtime_error(
"Invalid number of parameters");
202 std::any_cast<int64_t>(a[1]), std::any_cast<torch::Tensor>(a[2]),
203 std::any_cast<torch::Tensor>(a[3]), std::any_cast<double>(a[4])});
208 std::any_cast<torch::nn::functional::GroupNormFuncOptions>(
212 new GroupNorm{std::any_cast<int64_t>(a[1])});
216 throw std::runtime_error(
"Invalid number of parameters");
225 std::any_cast<double>(a[1]), std::any_cast<int>(a[2]),
226 std::any_cast<bool>(a[3])});
230 std::any_cast<torch::nn::functional::GumbelSoftmaxFuncOptions>(
237 throw std::runtime_error(
"Invalid number of parameters");
247 std::any_cast<torch::nn::functional::HardshrinkFuncOptions>(
251 new Hardshrink{std::any_cast<double>(a[1])});
258 throw std::runtime_error(
"Invalid number of parameters");
269 throw std::runtime_error(
"Invalid number of parameters");
280 throw std::runtime_error(
"Invalid number of parameters");
288 activations_.emplace_back(
new Hardtanh{std::any_cast<double>(a[1]),
289 std::any_cast<double>(a[2]),
290 std::any_cast<bool>(a[3])});
293 activations_.emplace_back(
new Hardtanh{std::any_cast<double>(a[1]),
294 std::any_cast<double>(a[2])});
298 std::any_cast<torch::nn::functional::HardtanhFuncOptions>(a[1])});
304 throw std::runtime_error(
"Invalid number of parameters");
313 std::any_cast<torch::Tensor>(a[1]),
314 std::any_cast<torch::Tensor>(a[2]),
315 std::any_cast<torch::Tensor>(a[3]),
316 std::any_cast<torch::Tensor>(a[4]), std::any_cast<double>(a[5]),
317 std::any_cast<double>(a[6]), std::any_cast<bool>(a[7])});
321 std::any_cast<torch::Tensor>(a[1]),
322 std::any_cast<torch::Tensor>(a[2]),
323 std::any_cast<torch::Tensor>(a[3]),
324 std::any_cast<torch::Tensor>(a[4]), std::any_cast<double>(a[5]),
325 std::any_cast<double>(a[6])});
329 std::any_cast<torch::nn::functional::InstanceNormFuncOptions>(
336 throw std::runtime_error(
"Invalid number of parameters");
345 std::any_cast<std::vector<int64_t>>(a[1]),
346 std::any_cast<torch::Tensor>(a[2]),
347 std::any_cast<torch::Tensor>(a[3]), std::any_cast<double>(a[4])});
352 std::any_cast<torch::nn::functional::LayerNormFuncOptions>(
356 new LayerNorm{std::any_cast<std::vector<int64_t>>(a[1])});
360 throw std::runtime_error(
"Invalid number of parameters");
368 activations_.emplace_back(
new LeakyReLU{std::any_cast<double>(a[1]),
369 std::any_cast<bool>(a[2])});
374 std::any_cast<torch::nn::functional::LeakyReLUFuncOptions>(
378 new LeakyReLU{std::any_cast<double>(a[1])});
385 throw std::runtime_error(
"Invalid number of parameters");
394 std::any_cast<int64_t>(a[1]), std::any_cast<double>(a[2]),
395 std::any_cast<double>(a[3]), std::any_cast<double>(a[4])});
399 activations_.emplace_back(
new LocalResponseNorm{std::any_cast<
400 torch::nn::functional::LocalResponseNormFuncOptions>(a[1])});
403 new LocalResponseNorm{std::any_cast<int64_t>(a[1])});
407 throw std::runtime_error(
"Invalid number of parameters");
418 throw std::runtime_error(
"Invalid number of parameters");
428 std::any_cast<torch::nn::functional::LogSoftmaxFuncOptions>(
432 new LogSoftmax{std::any_cast<int64_t>(a[1])});
436 throw std::runtime_error(
"Invalid number of parameters");
447 throw std::runtime_error(
"Invalid number of parameters");
456 std::any_cast<double>(a[1]), std::any_cast<double>(a[2]),
457 std::any_cast<int64_t>(a[3])});
461 std::any_cast<torch::nn::functional::NormalizeFuncOptions>(
468 throw std::runtime_error(
"Invalid number of parameters");
477 new PReLU{std::any_cast<torch::Tensor>(a[1])});
480 throw std::runtime_error(
"Invalid number of parameters");
490 std::any_cast<torch::nn::functional::ReLUFuncOptions>(a[1])});
492 activations_.emplace_back(
new ReLU{std::any_cast<bool>(a[1])});
499 throw std::runtime_error(
"Invalid number of parameters");
509 std::any_cast<torch::nn::functional::ReLU6FuncOptions>(a[1])});
511 activations_.emplace_back(
new ReLU6{std::any_cast<bool>(a[1])});
518 throw std::runtime_error(
"Invalid number of parameters");
526 activations_.emplace_back(
new RReLU{std::any_cast<double>(a[1]),
527 std::any_cast<double>(a[2]),
528 std::any_cast<bool>(a[3])});
531 activations_.emplace_back(
new RReLU{std::any_cast<double>(a[1]),
532 std::any_cast<double>(a[2])});
536 std::any_cast<torch::nn::functional::RReLUFuncOptions>(a[1])});
542 throw std::runtime_error(
"Invalid number of parameters");
552 std::any_cast<torch::nn::functional::SELUFuncOptions>(a[1])});
554 activations_.emplace_back(
new SELU{std::any_cast<bool>(a[1])});
561 throw std::runtime_error(
"Invalid number of parameters");
572 throw std::runtime_error(
"Invalid number of parameters");
583 throw std::runtime_error(
"Invalid number of parameters");
593 std::any_cast<torch::nn::functional::SoftmaxFuncOptions>(
597 new Softmax{std::any_cast<int64_t>(a[1])});
601 throw std::runtime_error(
"Invalid number of parameters");
611 std::any_cast<torch::nn::functional::SoftminFuncOptions>(
615 new Softmin{std::any_cast<int64_t>(a[1])});
619 throw std::runtime_error(
"Invalid number of parameters");
627 activations_.emplace_back(
new Softplus{std::any_cast<double>(a[1]),
628 std::any_cast<double>(a[2])});
632 std::any_cast<torch::nn::functional::SoftplusFuncOptions>(a[1])});
638 throw std::runtime_error(
"Invalid number of parameters");
648 std::any_cast<torch::nn::functional::SoftshrinkFuncOptions>(
652 new Softshrink{std::any_cast<double>(a[1])});
659 throw std::runtime_error(
"Invalid number of parameters");
670 throw std::runtime_error(
"Invalid number of parameters");
681 throw std::runtime_error(
"Invalid number of parameters");
692 throw std::runtime_error(
"Invalid number of parameters");
700 activations_.emplace_back(
new Threshold{std::any_cast<double>(a[1]),
701 std::any_cast<double>(a[2]),
702 std::any_cast<bool>(a[3])});
705 activations_.emplace_back(
new Threshold{std::any_cast<double>(a[1]),
706 std::any_cast<double>(a[2])});
710 std::any_cast<torch::nn::functional::ThresholdFuncOptions>(
714 throw std::runtime_error(
"Invalid number of parameters");
719 throw std::runtime_error(
"Invalid activation function");
725 torch::Tensor x_in = x.clone();
735 inline torch::serialize::OutputArchive &
736 write(torch::serialize::OutputArchive &archive,
737 const std::string &key =
"iganet")
const {
740 archive.write(key +
".layers", torch::full({1}, (int64_t)
layers_.size()));
741 for (std::size_t i = 0; i <
layers_.size(); ++i) {
743 key +
".layer[" + std::to_string(i) +
"].in_features",
744 torch::full({1}, (int64_t)
layers_[i]->options.in_features()));
746 key +
".layer[" + std::to_string(i) +
"].outputs_features",
747 torch::full({1}, (int64_t)
layers_[i]->options.out_features()));
748 archive.write(key +
".layer[" + std::to_string(i) +
"].bias",
749 torch::full({1}, (int64_t)
layers_[i]->options.bias()));
751 activations_[i]->write(archive, key +
".layer[" + std::to_string(i) +
759 inline torch::serialize::InputArchive &
760 read(torch::serialize::InputArchive &archive,
761 const std::string &key =
"iganet") {
762 torch::Tensor layers, in_features, outputs_features, bias,
activation;
764 archive.read(key +
".layers", layers);
765 for (int64_t i = 0; i < layers.item<int64_t>(); ++i) {
766 archive.read(key +
".layer[" + std::to_string(i) +
"].in_features",
768 archive.read(key +
".layer[" + std::to_string(i) +
"].outputs_features",
770 archive.read(key +
".layer[" + std::to_string(i) +
"].bias", bias);
771 layers_.emplace_back(register_module(
772 "layer[" + std::to_string(i) +
"]",
774 torch::nn::LinearOptions(in_features.item<int64_t>(),
775 outputs_features.item<int64_t>())
776 .bias(bias.item<
bool>()))));
778 archive.read(key +
".layer[" + std::to_string(i) +
"].activation.type",
786 new BatchNorm{torch::Tensor{}, torch::Tensor{}});
888 throw std::runtime_error(
"Invalid activation function");
890 activations_.back()->read(archive, key +
".layer[" + std::to_string(i) +
902 os <<
"activation[" << i++ <<
"] = " << *
activation <<
"\n";
919template <
typename real_t>
921 :
public torch::nn::ModuleHolder<IgANetGeneratorImpl<real_t>> {
931template <
typename Optimizer,
typename GeometryMap,
typename Variable,
952 std::unique_ptr<optimizer_type>
opt_;
973 template <std::
size_t NumCoeffs>
974 IgANet(
const std::vector<int64_t> &layers,
975 const std::vector<std::vector<std::any>> &activations,
976 std::array<int64_t, NumCoeffs> numCoeffs,
IgANetOptions defaults = {},
979 : IgANet(layers, activations,
std::tuple{numCoeffs},
std::tuple{numCoeffs},
982 template <std::size_t... NumCoeffs>
983 IgANet(
const std::vector<int64_t> &layers,
984 const std::vector<std::vector<std::any>> &activations,
985 std::tuple<std::array<int64_t, NumCoeffs>...> numCoeffs,
989 : IgANet(layers, activations, numCoeffs, numCoeffs, defaults,
options) {}
996 template <std::
size_t GeometryMapNumCoeffs, std::
size_t VariableNumCoeffs>
997 IgANet(
const std::vector<int64_t> &layers,
998 const std::vector<std::vector<std::any>> &activations,
999 std::array<int64_t, GeometryMapNumCoeffs> geometryMapNumCoeffs,
1000 std::array<int64_t, VariableNumCoeffs> variableNumCoeffs,
1004 : IgANet(layers, activations,
std::tuple{geometryMapNumCoeffs},
1005 std::tuple{variableNumCoeffs}, defaults,
options) {}
1007 template <std::size_t... GeometryMapNumCoeffs,
1008 std::size_t... VariableNumCoeffs>
1010 const std::vector<int64_t> &layers,
1011 const std::vector<std::vector<std::any>> &activations,
1012 std::tuple<std::array<int64_t, GeometryMapNumCoeffs>...>
1013 geometryMapNumCoeffs,
1014 std::tuple<std::array<int64_t, VariableNumCoeffs>...> variableNumCoeffs,
1019 Base(geometryMapNumCoeffs, variableNumCoeffs,
options),
1021 net_(utils::concat(
std::vector<int64_t>{
inputs( 0).size(0)},
1023 std::vector<int64_t>{
Base::u_.as_tensor_size()}),
1027 opt_(std::make_unique<optimizer_type>(
net_->parameters())),
1051 opt_ = std::make_unique<optimizer_type>(
net_->parameters());
1053 std::vector<optimizer_options_type>
options;
1054 for (
auto & group :
opt_->param_groups())
1056 opt_ = std::make_unique<optimizer_type>(
net_->parameters());
1069 if (param_group < opt_->param_groups().size())
1072 throw std::runtime_error(
"Index exceeds number of parameter groups");
1077 if (param_group < opt_->param_groups().size())
1080 throw std::runtime_error(
"Index exceeds number of parameter groups");
1085 for (
auto &group :
opt_->param_groups())
1091 for (
auto &group :
opt_->param_groups())
1097 if (param_group < opt_->param_groups().size())
1100 throw std::runtime_error(
"Index exceeds number of parameter groups");
1105 if (param_group < opt_->param_groups().size())
1108 throw std::runtime_error(
"Index exceeds number of parameter groups");
1131 return torch::empty({0});
1138 virtual torch::Tensor
loss(
const torch::Tensor &, int64_t) = 0;
1142#ifdef IGANET_WITH_MPI
1143 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
1144 c10d::ProcessGroupMPI::createProcessGroupMPI()
1157 auto closure = [&]() {
1168 loss.backward({},
true,
false);
1173#ifdef IGANET_WITH_MPI
1179 std::vector<c10::intrusive_ptr<::c10d::Work>> works;
1180 for (
auto ¶m :
net_->named_parameters()) {
1181 std::vector<torch::Tensor> tmp = {param.value().grad()};
1182 works.emplace_back(pg->allreduce(tmp));
1185 waitWork(pg, works);
1187 for (
auto ¶m :
net_->named_parameters()) {
1188 param.value().grad().data() =
1189 param.value().grad().data() / pg->getSize();
1194 opt_->step(closure);
1209 if (current_loss == previous_loss || std::abs(current_loss-previous_loss) < previous_loss/10) {
1216 if (
loss.isnan().template item<bool>()) {
1222 previous_loss = current_loss;
1227 template <
typename DataLoader>
1229#ifdef IGANET_WITH_MPI
1231 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
1232 c10d::ProcessGroupMPI::createProcessGroupMPI()
1243 for (
auto &batch : loader) {
1251 .slice(1,
Base::G_.as_tensor_size(),
1267 .slice(1,
Base::G_.as_tensor_size(),
1281 auto closure = [&]() {
1292 loss.backward({},
true,
false);
1298 opt_->step(closure);
1300 Loss +=
loss.template item<typename Base::value_type>();
1312 if (Loss == previous_loss) {
1317 previous_loss = Loss;
1328 torch::Tensor outputs =
net_->forward(
inputs);
1333 inline virtual nlohmann::json
to_json()
const override {
1334 return "Not implemented yet";
1339 return net_->parameters();
1344 inline torch::OrderedDict<std::string, torch::Tensor>
1346 return net_->named_parameters();
1351 std::size_t result = 0;
1352 for (
const auto ¶m : this->
parameters()) {
1353 result += param.numel();
1361 os <<
name() <<
"(\n"
1362 <<
"net = " <<
net_ <<
"\n";
1372 inline void save(
const std::string &filename,
1373 const std::string &key =
"iganet")
const {
1374 torch::serialize::OutputArchive archive;
1375 write(archive, key).save_to(filename);
1379 inline void load(
const std::string &filename,
1380 const std::string &key =
"iganet") {
1381 torch::serialize::InputArchive archive;
1382 archive.load_from(filename);
1387 inline torch::serialize::OutputArchive &
1388 write(torch::serialize::OutputArchive &archive,
1389 const std::string &key =
"iganet")
const {
1397 net_->write(archive, key +
".net");
1398 torch::serialize::OutputArchive archive_net;
1399 net_->save(archive_net);
1400 archive.write(key +
".net.data", archive_net);
1402 torch::serialize::OutputArchive archive_opt;
1403 opt_->save(archive_opt);
1404 archive.write(key +
".opt", archive_opt);
1410 inline torch::serialize::InputArchive &
1411 read(torch::serialize::InputArchive &archive,
1412 const std::string &key =
"iganet") {
1420 net_->read(archive, key +
".net");
1421 torch::serialize::InputArchive archive_net;
1422 archive.read(key +
".net.data", archive_net);
1423 net_->load(archive_net);
1425 opt_->add_parameters(
net_->parameters());
1426 torch::serialize::InputArchive archive_opt;
1427 archive.read(key +
".opt", archive_opt);
1428 opt_->load(archive_opt);
1450#ifdef IGANET_WITH_MPI
1453 static void waitWork(c10::intrusive_ptr<c10d::ProcessGroupMPI> pg,
1454 std::vector<c10::intrusive_ptr<c10d::Work>> works) {
1455 for (
auto &work : works) {
1458 }
catch (
const std::exception &ex) {
1459 Log(
log::error) <<
"Exception received during waitWork: " << ex.what()
1469 template <
typename Optimizer,
typename GeometryMap,
typename Variable>
1470 requires OptimizerType<Optimizer> && FunctionSpaceType<GeometryMap> && FunctionSpaceType<Variable>
1471inline std::ostream &
1483 template <
typename GeometryMap,
typename Variable>
1484 requires FunctionSpaceType<GeometryMap> && FunctionSpaceType<Variable>
1489 decltype(std::declval<GeometryMap>()
1490 .template find_knot_indices<functionspace::interior>(
1491 std::declval<typename GeometryMap::eval_type>()));
1495 decltype(std::declval<GeometryMap>()
1496 .template find_knot_indices<functionspace::boundary>(
1498 typename GeometryMap::boundary_eval_type>()));
1502 decltype(std::declval<Variable>()
1503 .template find_knot_indices<functionspace::interior>(
1504 std::declval<typename Variable::eval_type>()));
1508 decltype(std::declval<Variable>()
1509 .template find_knot_indices<functionspace::boundary>(
1510 std::declval<typename Variable::boundary_eval_type>()));
1514 decltype(std::declval<GeometryMap>()
1515 .template find_coeff_indices<functionspace::interior>(
1516 std::declval<typename GeometryMap::eval_type>()));
1520 decltype(std::declval<GeometryMap>()
1521 .template find_coeff_indices<functionspace::boundary>(
1523 typename GeometryMap::boundary_eval_type>()));
1527 decltype(std::declval<Variable>()
1528 .template find_coeff_indices<functionspace::interior>(
1529 std::declval<typename Variable::eval_type>()));
1533 decltype(std::declval<Variable>()
1534 .template find_coeff_indices<functionspace::boundary>(
1535 std::declval<typename Variable::boundary_eval_type>()));
1541template <
typename Optimizer,
typename Inputs,
typename Outputs,
typename CollPts =
void>
1561 std::unique_ptr<optimizer_type>
opt_;
1580 template <
typename NumCoeffs>
1582 const std::vector<std::vector<std::any>> &activations,
1583 const NumCoeffs &numCoeffs,
1588 : IgANet2(layers, activations, numCoeffs, numCoeffs,
init, defaults,
options)
1593 template <
typename NumCoeffsInputs,
typename NumCoeffsOutputs>
1595 const std::vector<std::vector<std::any>> &activations,
1596 const NumCoeffsInputs &numCoeffsInputs,
1597 const NumCoeffsOutputs &numCoeffsOutputs,
1605 net_(utils::concat(
std::vector<int64_t>{
inputs( 0).size(0)},
1607 std::vector<int64_t>{
outputs( 0).size(0)}),
1611 opt_(std::make_unique<optimizer_type>(
net_->parameters())),
1635 opt_ = std::make_unique<optimizer_type>(
net_->parameters());
1637 std::vector<optimizer_options_type>
options;
1638 for (
auto & group :
opt_->param_groups())
1640 opt_ = std::make_unique<optimizer_type>(
net_->parameters());
1653 if (param_group < opt_->param_groups().size())
1656 throw std::runtime_error(
"Index exceeds number of parameter groups");
1661 if (param_group < opt_->param_groups().size())
1664 throw std::runtime_error(
"Index exceeds number of parameter groups");
1669 for (
auto &group :
opt_->param_groups())
1675 for (
auto &group :
opt_->param_groups())
1681 if (param_group < opt_->param_groups().size())
1684 throw std::runtime_error(
"Index exceeds number of parameter groups");
1689 if (param_group < opt_->param_groups().size())
1692 throw std::runtime_error(
"Index exceeds number of parameter groups");
1712 virtual void inputs(
const torch::Tensor& tensor) {
1714 [](
const auto& obj){
return obj.as_tensor_size(); },
1715 [](
auto& obj,
const auto& tensor){
return obj.from_tensor(tensor); });
1719 virtual void outputs(
const torch::Tensor& tensor) {
1721 [](
const auto& obj){
return obj.as_tensor_size(); },
1722 [](
auto& obj,
const auto& tensor){
return obj.from_tensor(tensor); });
1729 virtual torch::Tensor
loss(
const torch::Tensor &, int64_t) = 0;
1733#ifdef IGANET_WITH_MPI
1734 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
1735 c10d::ProcessGroupMPI::createProcessGroupMPI()
1739 typename Base::value_type previous_loss(-1.0);
1748 auto closure = [&]() {
1759 loss.backward({},
true,
false);
1764#ifdef IGANET_WITH_MPI
1770 std::vector<c10::intrusive_ptr<::c10d::Work>> works;
1771 for (
auto ¶m :
net_->named_parameters()) {
1772 std::vector<torch::Tensor> tmp = {param.value().grad()};
1773 works.emplace_back(pg->allreduce(tmp));
1776 waitWork(pg, works);
1778 for (
auto ¶m :
net_->named_parameters()) {
1779 param.value().grad().data() =
1780 param.value().grad().data() / pg->getSize();
1785 opt_->step(closure);
1787 typename Base::value_type current_loss =
loss.template item<typename Base::value_type>();
1800 if (current_loss == previous_loss || std::abs(current_loss-previous_loss) < previous_loss/10) {
1807 if (
loss.isnan().template item<bool>()) {
1813 previous_loss = current_loss;
1818 template <
typename DataLoader>
1820#ifdef IGANET_WITH_MPI
1822 c10::intrusive_ptr<c10d::ProcessGroupMPI> pg =
1823 c10d::ProcessGroupMPI::createProcessGroupMPI()
1827 typename Base::value_type previous_loss(-1.0);
1832 typename Base::value_type Loss(0);
1834 for (
auto &batch : loader) {
1872 auto closure = [&]() {
1883 loss.backward({},
true,
false);
1889 opt_->step(closure);
1891 Loss +=
loss.template item<typename Base::value_type>();
1903 if (Loss == previous_loss) {
1908 previous_loss = Loss;
1924 inline virtual nlohmann::json
to_json()
const override {
1925 return "Not implemented yet";
1930 return net_->parameters();
1935 inline torch::OrderedDict<std::string, torch::Tensor>
1937 return net_->named_parameters();
1942 std::size_t result = 0;
1943 for (
const auto ¶m : this->
parameters()) {
1944 result += param.numel();
1952 os <<
name() <<
"(\n"
1953 <<
"net = " <<
net_ <<
"\n";
1963 inline void save(
const std::string &filename,
1964 const std::string &key =
"iganet")
const {
1965 torch::serialize::OutputArchive archive;
1966 write(archive, key).save_to(filename);
1970 inline void load(
const std::string &filename,
1971 const std::string &key =
"iganet") {
1972 torch::serialize::InputArchive archive;
1973 archive.load_from(filename);
1978 inline torch::serialize::OutputArchive &
1979 write(torch::serialize::OutputArchive &archive,
1980 const std::string &key =
"iganet")
const {
1988 net_->write(archive, key +
".net");
1989 torch::serialize::OutputArchive archive_net;
1990 net_->save(archive_net);
1991 archive.write(key +
".net.data", archive_net);
1993 torch::serialize::OutputArchive archive_opt;
1994 opt_->save(archive_opt);
1995 archive.write(key +
".opt", archive_opt);
2001 inline torch::serialize::InputArchive &
2002 read(torch::serialize::InputArchive &archive,
2003 const std::string &key =
"iganet") {
2011 net_->read(archive, key +
".net");
2012 torch::serialize::InputArchive archive_net;
2013 archive.read(key +
".net.data", archive_net);
2014 net_->load(archive_net);
2016 opt_->add_parameters(
net_->parameters());
2017 torch::serialize::InputArchive archive_opt;
2018 archive.read(key +
".opt", archive_opt);
2019 opt_->load(archive_opt);
2041#ifdef IGANET_WITH_MPI
2044 static void waitWork(c10::intrusive_ptr<c10d::ProcessGroupMPI> pg,
2045 std::vector<c10::intrusive_ptr<c10d::Work>> works) {
2046 for (
auto &work : works) {
2049 }
catch (
const std::exception &ex) {
2050 Log(
log::error) <<
"Exception received during waitWork: " << ex.what()
2060template <
typename Optimizer,
typename Inputs,
typename Outputs,
typename CollPts>
2061requires OptimizerType<Optimizer>
2062inline std::ostream &
2076template <
typename,
typename,
typename =
void>
2082 std::tuple<Outputs...>, void> {
2086 std::tuple<decltype(std::declval<Inputs>()
2087 .template find_knot_indices<functionspace::interior>(
2088 std::declval<typename Inputs::eval_type>()))...>;
2091 template<std::
size_t index>
2096 std::tuple<decltype(std::declval<Inputs>()
2097 .template find_knot_indices<functionspace::boundary>(
2099 typename Inputs::boundary_eval_type>()))...>;
2102 template<std::
size_t index>
2107 std::tuple<decltype(std::declval<Outputs>()
2108 .template find_knot_indices<functionspace::interior>(
2109 std::declval<typename Outputs::eval_type>()))...>;
2112 template<std::
size_t index>
2117 std::tuple<decltype(std::declval<Outputs>()
2118 .template find_knot_indices<functionspace::boundary>(
2120 typename Outputs::boundary_eval_type>()))...>;
2123 template<std::
size_t index>
2128 std::tuple<decltype(std::declval<Inputs>()
2129 .template find_coeff_indices<functionspace::interior>(
2130 std::declval<typename Inputs::eval_type>()))...>;
2133 template<std::
size_t index>
2138 std::tuple<decltype(std::declval<Inputs>()
2139 .template find_coeff_indices<functionspace::boundary>(
2141 typename Inputs::boundary_eval_type>()))...>;
2144 template<std::
size_t index>
2149 std::tuple<decltype(std::declval<Outputs>()
2150 .template find_coeff_indices<functionspace::interior>(
2151 std::declval<typename Outputs::eval_type>()))...>;
2154 template<std::
size_t index>
2159 std::tuple<decltype(std::declval<Outputs>()
2160 .template find_coeff_indices<functionspace::boundary>(
2162 typename Outputs::boundary_eval_type>()))...>;
2165 template<std::
size_t index>
2173 std::tuple<Outputs...>,
2175 std::tuple<Outputs...>, void> {
2179 std::tuple<decltype(std::declval<CollPts>()
2180 .template find_knot_indices<functionspace::interior>(
2181 std::declval<typename CollPts::eval_type>()))...>;
2185 std::tuple<decltype(std::declval<CollPts>()
2186 .template find_knot_indices<functionspace::boundary>(
2188 typename CollPts::boundary_eval_type>()))...>;
2192 std::tuple<decltype(std::declval<CollPts>()
2193 .template find_coeff_indices<functionspace::interior>(
2194 std::declval<typename CollPts::eval_type>()))...>;
2198 std::tuple<decltype(std::declval<CollPts>()
2199 .template find_coeff_indices<functionspace::boundary>(
2201 typename CollPts::boundary_eval_type>()))...>;
Batch Normalization as described in the paper.
Definition layer.hpp:134
Continuously Differentiable Exponential Linear Units activation function.
Definition layer.hpp:264
Exponential Linear Units activation function.
Definition layer.hpp:341
Gaussian Error Linear Units activation function.
Definition layer.hpp:417
Grated Linear Units activation function.
Definition layer.hpp:468
Group Normalization over a mini-batch of inputs as described in the paper Group Normalization,...
Definition layer.hpp:532
Gumbel-Softmax distribution activation function.
Definition layer.hpp:615
Hard shrinkish activation function.
Definition layer.hpp:692
Hardsigmoid activation function.
Definition layer.hpp:769
Hardswish activation function.
Definition layer.hpp:822
Hardtanh activation function.
Definition layer.hpp:875
namespace detail
Definition igabase.hpp:47
IgA base class.
Definition igabase.hpp:1195
Variable f_
Spline representation of the reference data.
Definition igabase.hpp:1226
typename Base::value_type value_type
Value type.
Definition igabase.hpp:1201
static bool constexpr has_GeometryMap
Indicates whether this class provides a geometry map.
Definition igabase.hpp:1216
static bool constexpr has_Solution
Indicates whether this class provides a solution.
Definition igabase.hpp:1222
static bool constexpr has_RefData
Indicates whether this class provides a reference solution.
Definition igabase.hpp:1219
GeometryMap G_
Spline representation of the geometry map.
Definition igabase.hpp:809
Variable u_
Spline representation of the solution.
Definition igabase.hpp:812
IgANet2.
Definition iganet.hpp:1545
virtual torch::Tensor inputs(int64_t epoch) const
Returns the network inputs as tensor.
Definition iganet.hpp:1702
optimizer_options_type & optimizerOptions(std::size_t param_group=0)
Returns a non-constant reference to the optimizer options.
Definition iganet.hpp:1652
void optimizerOptionsReset(optimizer_options_type &&options)
Resets the optimizer options.
Definition iganet.hpp:1674
void train(DataLoader &loader)
Trains the IgANet.
Definition iganet.hpp:1819
const auto & options() const
Returns a constant reference to the options structure.
Definition iganet.hpp:1696
IgANetOptions options_
Options.
Definition iganet.hpp:1564
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:1936
void optimizerOptionsReset(optimizer_options_type &&options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:1688
IgANet2(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:1581
void save(const std::string &filename, const std::string &key="iganet") const
Saves the IgANet to file.
Definition iganet.hpp:1963
const optimizer_options_type & optimizerOptions(std::size_t param_group=0) const
Returns a constant reference to the optimizer options.
Definition iganet.hpp:1660
std::unique_ptr< optimizer_type > opt_
Optimizer.
Definition iganet.hpp:1561
void optimizerOptionsReset(const optimizer_options_type &options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:1680
void eval()
Evaluate IgANet.
Definition iganet.hpp:1917
IgANetGenerator< typename Base::value_type > & net()
Returns a non-constant reference to the IgANet generator.
Definition iganet.hpp:1622
virtual void train()
Trains the IgANet.
Definition iganet.hpp:1732
auto & options()
Returns a non-constant reference to the options structure.
Definition iganet.hpp:1699
void load(const std::string &filename, const std::string &key="iganet")
Loads the IgANet from file.
Definition iganet.hpp:1970
typename optimizer_options_type< Optimizer >::type optimizer_options_type
Type of the optimizer options.
Definition iganet.hpp:1554
void optimizerReset(const optimizer_options_type &optimizerOptions)
Resets the optimizer.
Definition iganet.hpp:1647
const IgANetGenerator< typename Base::value_type > & net() const
Returns a constant reference to the IgANet generator.
Definition iganet.hpp:1617
virtual bool epoch(int64_t)=0
Initializes epoch.
void optimizerOptionsReset(const optimizer_options_type &options)
Resets the optimizer options.
Definition iganet.hpp:1668
bool operator==(const IgANet2 &other) const
Returns true if both IgANet objects are the same.
Definition iganet.hpp:2025
bool operator!=(const IgANet2 &other) const
Returns true if both IgANet objects are different.
Definition iganet.hpp:2039
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the IgANet object.
Definition iganet.hpp:1951
IgABase2< Inputs, Outputs, CollPts > Base
Base type.
Definition iganet.hpp:1548
const optimizer_type & optimizer() const
Returns a constant reference to the optimizer.
Definition iganet.hpp:1625
IgANet2(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:1594
optimizer_type & optimizer()
Returns a non-constant reference to the optimizer.
Definition iganet.hpp:1628
IgANetGenerator< typename Base::value_type > net_
IgANet generator.
Definition iganet.hpp:1558
std::vector< torch::Tensor > parameters() const noexcept
Returns a constant reference to the parameters of the IgANet object.
Definition iganet.hpp:1929
virtual void outputs(const torch::Tensor &tensor)
Attaches the given tensor to the outputs.
Definition iganet.hpp:1719
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:1979
virtual void inputs(const torch::Tensor &tensor)
Attaches the given tensor to the inputs.
Definition iganet.hpp:1712
Optimizer optimizer_type
Type of the optimizer.
Definition iganet.hpp:1551
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:2002
IgANet2(IgANetOptions defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Default constructor.
Definition iganet.hpp:1568
void optimizerReset(bool resetOptions=true)
Resets the optimizer.
Definition iganet.hpp:1633
virtual torch::Tensor outputs(int64_t epoch) const
Returns the network outputs as tensor.
Definition iganet.hpp:1707
virtual nlohmann::json to_json() const override
Returns the IgANet object as JSON object.
Definition iganet.hpp:1924
virtual torch::Tensor loss(const torch::Tensor &, int64_t)=0
Computes the loss function.
std::size_t nparameters() const noexcept
Returns the total number of parameters of the IgANet object.
Definition iganet.hpp:1941
IgANetGenerator.
Definition iganet.hpp:921
IgANetGeneratorImpl.
Definition iganet.hpp:48
torch::serialize::InputArchive & read(torch::serialize::InputArchive &archive, const std::string &key="iganet")
Reads the IgANet from a torch::serialize::InputArchive object.
Definition iganet.hpp:760
IgANetGeneratorImpl()=default
Default constructor.
IgANetGeneratorImpl(const std::vector< int64_t > &layers, const std::vector< std::vector< std::any > > &activations, Options< real_t > options=Options< real_t >{})
Constructor.
Definition iganet.hpp:54
std::vector< std::unique_ptr< iganet::ActivationFunction > > activations_
Vector of activation functions.
Definition iganet.hpp:911
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Definition iganet.hpp:897
torch::Tensor forward(torch::Tensor x)
Forward evaluation.
Definition iganet.hpp:724
std::vector< torch::nn::Linear > layers_
Vector of linear layers.
Definition iganet.hpp:908
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:736
IgANet.
Definition iganet.hpp:936
const auto & options() const
Returns a constant reference to the options structure.
Definition iganet.hpp:1112
void optimizerOptionsReset(optimizer_options_type &&options)
Resets the optimizer options.
Definition iganet.hpp:1090
void save(const std::string &filename, const std::string &key="iganet") const
Saves the IgANet to file.
Definition iganet.hpp:1372
void load(const std::string &filename, const std::string &key="iganet")
Loads the IgANet from file.
Definition iganet.hpp:1379
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:1345
void optimizerOptionsReset(const optimizer_options_type &options)
Resets the optimizer options.
Definition iganet.hpp:1084
virtual torch::Tensor loss(const torch::Tensor &, int64_t)=0
Computes the loss function.
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:974
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:1411
IgABase< GeometryMap, Variable > Base
Base type.
Definition iganet.hpp:939
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 >{})
Constructor: number of layers, activation functions, and number of spline coefficients (different for...
Definition iganet.hpp:1009
std::vector< torch::Tensor > parameters() const noexcept
Returns a constant reference to the parameters of the IgANet object.
Definition iganet.hpp:1338
std::unique_ptr< optimizer_type > opt_
Optimizer.
Definition iganet.hpp:952
std::size_t nparameters() const noexcept
Returns the total number of parameters of the IgANet object.
Definition iganet.hpp:1350
optimizer_type & optimizer()
Returns a non-constant reference to the optimizer.
Definition iganet.hpp:1044
virtual void train()
Trains the IgANet.
Definition iganet.hpp:1141
virtual void pretty_print(std::ostream &os=Log(log::info)) const noexcept override
Returns a string representation of the IgANet object.
Definition iganet.hpp:1360
Optimizer optimizer_type
Type of the optimizer.
Definition iganet.hpp:942
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:1388
void optimizerOptionsReset(optimizer_options_type &&options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:1104
virtual torch::Tensor inputs(int64_t epoch) const
Returns the network inputs.
Definition iganet.hpp:1123
auto & options()
Returns a non-constant reference to the options structure.
Definition iganet.hpp:1115
void optimizerReset(bool resetOptions=true)
Resets the optimizer.
Definition iganet.hpp:1049
IgANetGenerator< typename Base::value_type > & net()
Returns a non-constant reference to the IgANet generator.
Definition iganet.hpp:1038
const IgANetGenerator< typename Base::value_type > & net() const
Returns a constant reference to the IgANet generator.
Definition iganet.hpp:1033
const optimizer_options_type & optimizerOptions(std::size_t param_group=0) const
Returns a constant reference to the optimizer options.
Definition iganet.hpp:1076
virtual bool epoch(int64_t)=0
Initializes epoch.
IgANet(IgANetOptions defaults={}, iganet::Options< typename Base::value_type > options=iganet::Options< typename Base::value_type >{})
Default constructor.
Definition iganet.hpp:959
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:997
typename optimizer_options_type< Optimizer >::type optimizer_options_type
Type of the optimizer options.
Definition iganet.hpp:945
void train(DataLoader &loader)
Trains the IgANet.
Definition iganet.hpp:1228
IgANetOptions options_
Options.
Definition iganet.hpp:955
virtual nlohmann::json to_json() const override
Returns the IgANet object as JSON object.
Definition iganet.hpp:1333
IgANetGenerator< typename Base::value_type > net_
IgANet generator.
Definition iganet.hpp:949
void optimizerOptionsReset(const optimizer_options_type &options, std::size_t param_group)
Resets the optimizer options.
Definition iganet.hpp:1096
void eval()
Evaluate IgANet.
Definition iganet.hpp:1326
optimizer_options_type & optimizerOptions(std::size_t param_group=0)
Returns a non-constant reference to the optimizer options.
Definition iganet.hpp:1068
const optimizer_type & optimizer() const
Returns a constant reference to the optimizer.
Definition iganet.hpp:1041
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 >{})
Constructor: number of layers, activation functions, and number of spline coefficients (same for geom...
Definition iganet.hpp:983
bool operator==(const IgANet &other) const
Returns true if both IgANet objects are the same.
Definition iganet.hpp:1434
void optimizerReset(const optimizer_options_type &optimizerOptions)
Resets the optimizer.
Definition iganet.hpp:1063
bool operator!=(const IgANet &other) const
Returns true if both IgANet objects are different.
Definition iganet.hpp:1448
Instance Normalization as described in the paper.
Definition layer.hpp:958
Layer Normalization as described in the paper.
Definition layer.hpp:1064
Leaky ReLU activation function.
Definition layer.hpp:1159
Local response Normalization.
Definition layer.hpp:1234
LogSigmoid activation function.
Definition layer.hpp:1326
LogSoftmax activation function.
Definition layer.hpp:1377
Mish activation function.
Definition layer.hpp:1444
No-op activation function.
Definition layer.hpp:92
Lp Normalization.
Definition layer.hpp:1487
The Options class handles the automated determination of dtype from the template argument and the sel...
Definition options.hpp:107
PReLU activation function.
Definition layer.hpp:1562
Randomized ReLU activation function.
Definition layer.hpp:1764
ReLU6 activation function.
Definition layer.hpp:1692
ReLU activation function.
Definition layer.hpp:1624
SELU activation function.
Definition layer.hpp:1847
Sigmoid Linear Unit activation function.
Definition layer.hpp:1959
Sigmoid activation function.
Definition layer.hpp:1915
Softmax activation function.
Definition layer.hpp:2004
Softmin activation function.
Definition layer.hpp:2075
Softplus activation function.
Definition layer.hpp:2146
Softshrink activation function.
Definition layer.hpp:2228
Softsign activation function.
Definition layer.hpp:2300
Tanh activation function.
Definition layer.hpp:2344
Tanhshrink activation function.
Definition layer.hpp:2387
Threshold activation function.
Definition layer.hpp:2435
Full qualified name descriptor.
Definition fqn.hpp:26
virtual const std::string & name() const noexcept
Returns the full qualified name of the object.
Definition fqn.hpp:31
Concept to identify template parameters that are derived from iganet::details::FunctionSpaceType.
Definition functionspace.hpp:3118
Concept to identify template parameters that are derived from torch::optim::Optimizer.
Definition optimizer.hpp:21
Definition igabase.hpp:37
Container utility functions.
Full qualified name utility functions.
Isogeometric analysis base class.
auto zip(T &&...seqs)
Definition zip.hpp:97
void slice_tensor_into_tuple(std::tuple< Tensors... > &tuple, const torch::Tensor &tensor, FuncSize &&funcSize, FuncAssign &&funcAssign, int64_t &offset, int64_t dim=0)
Slices the given tensor into the objects of the std::tuple.
Definition tuple.hpp:61
torch::Tensor cat_tuple_into_tensor(const std::tuple< Tensors... > &tensors, int64_t dim=0)
Concatenates the entries of an std::tuple object into a single Torch tensor along the given dimension...
Definition tuple.hpp:26
Definition boundary.hpp:22
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:1504
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:1523
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:1510
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:1529
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:1498
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:1516
struct iganet::@0 Log
Logger.
init
Enumerator for specifying the initialization of B-spline coefficients.
Definition bspline.hpp:55
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:1535
activation
Enumerator for nonlinear activation functions.
Definition layer.hpp:23
std::ostream & operator<<(std::ostream &os, const Boundary< Spline > &obj)
Print (as string) a Boundary object.
Definition boundary.hpp:1963
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:1491
IgANetCustomizable.
Definition iganet.hpp:1485
IgANetCustomizable2.
Definition iganet.hpp:2077
IgANetOptions.
Definition iganet.hpp:32
TORCH_ARG(int64_t, batch_size)
TORCH_ARG(double, min_loss)
TORCH_ARG(int64_t, max_epoch)
Serialization prototype.
Definition serialize.hpp:31