LCOV - code coverage report
Current view: top level - src/actions - LoadCovarianceDataAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: #33416 (b10b36) with base 9fbd27 Lines: 54 61 88.5 %
Date: 2026-07-23 16:21:17 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #ifdef MOOSE_LIBTORCH_ENABLED
      11             : 
      12             : #include "LoadCovarianceDataAction.h"
      13             : #include "CovarianceFunctionBase.h"
      14             : #include "GaussianProcessSurrogate.h"
      15             : #include "FEProblem.h"
      16             : #include "StochasticToolsApp.h"
      17             : 
      18             : registerMooseAction("StochasticToolsApp", LoadCovarianceDataAction, "load_covariance_data");
      19             : 
      20             : namespace
      21             : {
      22             : 
      23             : using HyperParameterMap = CovarianceFunctionBase::HyperParameterMap;
      24             : 
      25             : std::vector<Real>
      26          16 : exportHyperParameter(const torch::Tensor & tensor)
      27             : {
      28          16 :   const auto flattened = tensor.reshape({-1}).contiguous();
      29          48 :   return {flattened.data_ptr<Real>(), flattened.data_ptr<Real>() + flattened.numel()};
      30             : }
      31             : 
      32             : void
      33          32 : assignRequiredHyperParameter(InputParameters & params,
      34             :                              const std::string & param_name,
      35             :                              const torch::Tensor & tensor)
      36             : {
      37          32 :   if (params.have_parameter<Real>(param_name))
      38             :   {
      39          16 :     if (!CovarianceFunctionBase::isScalarHyperParameter(tensor))
      40           0 :       mooseError("Expected scalar hyperparameter for ", param_name, ".");
      41          16 :     params.set<Real>(param_name) = tensor.item<Real>();
      42             :   }
      43          16 :   else if (params.have_parameter<unsigned int>(param_name))
      44             :   {
      45           0 :     if (!CovarianceFunctionBase::isScalarHyperParameter(tensor))
      46           0 :       mooseError("Expected scalar hyperparameter for ", param_name, ".");
      47           0 :     params.set<unsigned int>(param_name) = cast_int<unsigned int>(tensor.item<Real>());
      48             :   }
      49          16 :   else if (params.have_parameter<std::vector<Real>>(param_name))
      50             :   {
      51          16 :     if (!CovarianceFunctionBase::isVectorHyperParameter(tensor))
      52           0 :       mooseError("Expected vector hyperparameter for ", param_name, ".");
      53          32 :     params.set<std::vector<Real>>(param_name) = exportHyperParameter(tensor);
      54             :   }
      55             :   else
      56           0 :     mooseError("Unsupported hyperparameter type for ", param_name, ".");
      57          32 : }
      58             : 
      59             : void
      60          48 : loadRequiredHyperParameter(InputParameters & params,
      61             :                            const UserObjectName & object_name,
      62             :                            const std::string & param_name,
      63             :                            const HyperParameterMap & hyperparameters)
      64             : {
      65         144 :   const auto expected_name = std::string(object_name) + ":" + param_name;
      66             :   const auto hyperparam_it = hyperparameters.find(expected_name);
      67          48 :   if (hyperparam_it != hyperparameters.end())
      68          32 :     assignRequiredHyperParameter(params, param_name, hyperparam_it->second);
      69          48 : }
      70             : 
      71             : } // namespace
      72             : 
      73             : InputParameters
      74        3008 : LoadCovarianceDataAction::validParams()
      75             : {
      76        3008 :   InputParameters params = Action::validParams();
      77        3008 :   params.addClassDescription("Calls load method on SurrogateModel objects contained within the "
      78             :                              "`[Surrogates]` input block, if a filename is given.");
      79        3008 :   return params;
      80           0 : }
      81             : 
      82        3008 : LoadCovarianceDataAction::LoadCovarianceDataAction(const InputParameters & params) : Action(params)
      83             : {
      84        3008 : }
      85             : 
      86             : void
      87        3006 : LoadCovarianceDataAction::act()
      88             : {
      89             :   std::vector<SurrogateModel *> objects;
      90        6012 :   _app.theWarehouse().query().condition<AttribSystem>("SurrogateModel").queryInto(objects);
      91        3302 :   for (auto model_ptr : objects)
      92             :   {
      93         296 :     auto * gp_gen = dynamic_cast<GaussianProcessSurrogate *>(model_ptr);
      94         760 :     if (gp_gen && model_ptr->isParamValid("filename"))
      95          16 :       load(*gp_gen);
      96             :   }
      97        3006 : }
      98             : 
      99             : void
     100          16 : LoadCovarianceDataAction::load(GaussianProcessSurrogate & model)
     101             : {
     102             :   // We grab all the necessary information that is needed to reconstruct the
     103             :   // covariance structure for the GP
     104             :   const std::string & covar_type = model.getGP().getCovarType();
     105             :   const std::string & covar_name = model.getGP().getCovarName();
     106             :   const std::map<UserObjectName, std::string> & dep_covar_types =
     107             :       model.getGP().getDependentCovarTypes();
     108             :   const std::vector<UserObjectName> & dep_covar_names = model.getGP().getDependentCovarNames();
     109             : 
     110             :   // This is for the covariance on the very top, the lower-level covariances are
     111             :   // all assumed to have num_outputs=1.
     112          16 :   const unsigned int num_outputs = model.getGP().getCovarNumOutputs();
     113             :   const HyperParameterMap & hyperparameters = model.getGP().getHyperParamMap();
     114             : 
     115             :   // We start by creating and loading the lower-level covariances if they need
     116             :   // to be present. Right now we can only load a complex covariance which has
     117             :   // a one-level dependency depth.
     118             :   // TODO: Extend this to arbitrary dependency depths. Maybe we could use a graph.
     119          24 :   for (const auto & it : dep_covar_types)
     120             :   {
     121           8 :     const auto & name = it.first;
     122           8 :     const auto & type = it.second;
     123           8 :     InputParameters covar_params = _factory.getValidParams(type);
     124             : 
     125             :     // We make sure that every required parameter is added so that the object
     126             :     // can be constructed. The non-required hyperparameters (if present in the
     127             :     // parameter maps) will be inserted later.
     128           8 :     const auto param_list = covar_params.getParametersList();
     129         184 :     for (const auto & param : param_list)
     130         176 :       if (covar_params.isParamRequired(param))
     131          16 :         loadRequiredHyperParameter(covar_params, name, param, hyperparameters);
     132             : 
     133          16 :     _problem->addObject<CovarianceFunctionBase>(type, name, covar_params, /*threaded=*/false);
     134           8 :   }
     135             : 
     136          16 :   InputParameters covar_params = _factory.getValidParams(covar_type);
     137          16 :   covar_params.set<unsigned int>("num_outputs") = num_outputs;
     138          16 :   covar_params.set<std::vector<UserObjectName>>("covariance_functions") = dep_covar_names;
     139             : 
     140          16 :   const auto param_list = covar_params.getParametersList();
     141         352 :   for (const auto & param : param_list)
     142             :     // We make sure that every required parameter is added so that the object
     143             :     // can be constructed. The non-required hyperparameters (if present in the
     144             :     // parameter maps) will be inserted later.
     145         336 :     if (covar_params.isParamRequired(param))
     146          64 :       loadRequiredHyperParameter(covar_params, covar_name, param, hyperparameters);
     147             : 
     148          16 :   auto covar_object = _problem->addObject<CovarianceFunctionBase>(
     149          32 :       covar_type, covar_name, covar_params, /* threaded = */ false);
     150          16 :   covar_object[0]->loadHyperParamMap(hyperparameters);
     151             : 
     152          16 :   model.setupCovariance(covar_name);
     153          32 : }
     154             : 
     155             : #endif

Generated by: LCOV version 1.14