https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LoadCovarianceDataAction.C
Go to the documentation of this file.
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
15#include "FEProblem.h"
16#include "StochasticToolsApp.h"
17
18registerMooseAction("StochasticToolsApp", LoadCovarianceDataAction, "load_covariance_data");
19
20namespace
21{
22
23using HyperParameterMap = CovarianceFunctionBase::HyperParameterMap;
24
25std::vector<Real>
26exportHyperParameter(const torch::Tensor & tensor)
27{
28 const auto flattened = tensor.reshape({-1}).contiguous();
29 return {flattened.data_ptr<Real>(), flattened.data_ptr<Real>() + flattened.numel()};
30}
31
32void
33assignRequiredHyperParameter(InputParameters & params,
34 const std::string & param_name,
35 const torch::Tensor & tensor)
36{
37 if (params.have_parameter<Real>(param_name))
38 {
40 mooseError("Expected scalar hyperparameter for ", param_name, ".");
41 params.set<Real>(param_name) = tensor.item<Real>();
42 }
43 else if (params.have_parameter<unsigned int>(param_name))
44 {
46 mooseError("Expected scalar hyperparameter for ", param_name, ".");
47 params.set<unsigned int>(param_name) = cast_int<unsigned int>(tensor.item<Real>());
48 }
49 else if (params.have_parameter<std::vector<Real>>(param_name))
50 {
52 mooseError("Expected vector hyperparameter for ", param_name, ".");
53 params.set<std::vector<Real>>(param_name) = exportHyperParameter(tensor);
54 }
55 else
56 mooseError("Unsupported hyperparameter type for ", param_name, ".");
57}
58
59void
60loadRequiredHyperParameter(InputParameters & params,
61 const UserObjectName & object_name,
62 const std::string & param_name,
63 const HyperParameterMap & hyperparameters)
64{
65 const auto expected_name = std::string(object_name) + ":" + param_name;
66 const auto hyperparam_it = hyperparameters.find(expected_name);
67 if (hyperparam_it != hyperparameters.end())
68 assignRequiredHyperParameter(params, param_name, hyperparam_it->second);
69}
70
71} // namespace
72
75{
77 params.addClassDescription("Calls load method on SurrogateModel objects contained within the "
78 "`[Surrogates]` input block, if a filename is given.");
79 return params;
80}
81
85
86void
88{
89 std::vector<SurrogateModel *> objects;
90 _app.theWarehouse().query().condition<AttribSystem>("SurrogateModel").queryInto(objects);
91 for (auto model_ptr : objects)
92 {
93 auto * gp_gen = dynamic_cast<GaussianProcessSurrogate *>(model_ptr);
94 if (gp_gen && model_ptr->isParamValid("filename"))
95 load(*gp_gen);
96 else if (gp_gen && _app.isRecovering() && gp_gen->getGP().getCovarFunctionPtr())
97 // After surrogate model data has been restored from checkpoint (load_surrogate_data ran
98 // first), push the recovered hyperparameters into the freshly-constructed covariance object
99 gp_gen->gp().covarFunction().loadHyperParamMap(gp_gen->getGP().getHyperParamMap());
100 }
101}
102
103void
105{
106 // We grab all the necessary information that is needed to reconstruct the
107 // covariance structure for the GP
108 const std::string & covar_type = model.getGP().getCovarType();
109 const std::string & covar_name = model.getGP().getCovarName();
110 const std::map<UserObjectName, std::string> & dep_covar_types =
111 model.getGP().getDependentCovarTypes();
112 const std::vector<UserObjectName> & dep_covar_names = model.getGP().getDependentCovarNames();
113
114 // This is for the covariance on the very top, the lower-level covariances are
115 // all assumed to have num_outputs=1.
116 const unsigned int num_outputs = model.getGP().getCovarNumOutputs();
117 const HyperParameterMap & hyperparameters = model.getGP().getHyperParamMap();
118
119 // We start by creating and loading the lower-level covariances if they need
120 // to be present. Right now we can only load a complex covariance which has
121 // a one-level dependency depth.
122 // TODO: Extend this to arbitrary dependency depths. Maybe we could use a graph.
123 for (const auto & it : dep_covar_types)
124 {
125 const auto & name = it.first;
126 const auto & type = it.second;
128
129 // We make sure that every required parameter is added so that the object
130 // can be constructed. The non-required hyperparameters (if present in the
131 // parameter maps) will be inserted later.
132 const auto param_list = covar_params.getParametersList();
133 for (const auto & param : param_list)
134 if (covar_params.isParamRequired(param))
135 loadRequiredHyperParameter(covar_params, name, param, hyperparameters);
136
137 _problem->addObject<CovarianceFunctionBase>(type, name, covar_params, /*threaded=*/false);
138 }
139
140 InputParameters covar_params = _factory.getValidParams(covar_type);
141 covar_params.set<unsigned int>("num_outputs") = num_outputs;
142 covar_params.set<std::vector<UserObjectName>>("covariance_functions") = dep_covar_names;
143
144 const auto param_list = covar_params.getParametersList();
145 for (const auto & param : param_list)
146 // We make sure that every required parameter is added so that the object
147 // can be constructed. The non-required hyperparameters (if present in the
148 // parameter maps) will be inserted later.
149 if (covar_params.isParamRequired(param))
150 loadRequiredHyperParameter(covar_params, covar_name, param, hyperparameters);
151
152 auto covar_object = _problem->addObject<CovarianceFunctionBase>(
153 covar_type, covar_name, covar_params, /* threaded = */ false);
154 covar_object[0]->loadHyperParamMap(hyperparameters);
155
156 model.setupCovariance(covar_name);
157}
158
159#endif
const PertinentGeochemicalSystem model(database, {"H2O", "H+", "HCO3-", "O2(aq)", "Ca++", ">(s)FeOH", "radius_neg1", "radius_neg1.5"}, {"Calcite"}, {}, {"Calcite_asdf"}, {"CH4(aq)"}, {">(s)FeOCa+"}, "O2(aq)", "e-")
registerMooseAction("StochasticToolsApp", LoadCovarianceDataAction, "load_covariance_data")
void mooseError(Args &&... args)
static InputParameters validParams()
MooseApp & _app
std::shared_ptr< FEProblemBase > & _problem
Base class for covariance functions that are used in Gaussian Processes.
void loadHyperParamMap(const HyperParameterMap &map)
Load some hyperparameters into the local map contained in this object.
static bool isVectorHyperParameter(const torch::Tensor &tensor)
Return true if a hyperparameter tensor stores a vector of values.
static bool isScalarHyperParameter(const torch::Tensor &tensor)
Return true if a hyperparameter tensor stores one scalar value.
std::unordered_map< std::string, torch::Tensor > HyperParameterMap
InputParameters getValidParams(const std::string &name) const
StochasticTools::GaussianProcess & gp()
bool have_parameter(std::string_view name) const
bool isParamRequired(const std::string &name) const
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
std::set< std::string > getParametersList() const
static InputParameters validParams()
void load(GaussianProcessSurrogate &model)
LoadCovarianceDataAction(const InputParameters &params)
bool isRecovering() const
TheWarehouse & theWarehouse()
const std::string & type() const
const std::string & name() const
Factory & _factory
CovarianceFunctionBase & covarFunction()
Query query()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real