https://mooseframework.inl.gov
GaussianProcessSurrogate.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 #ifdef MOOSE_LIBTORCH_ENABLED
10 
12 #include "Sampler.h"
13 
14 #include "CovarianceFunctionBase.h"
15 
16 registerMooseObject("StochasticToolsApp", GaussianProcessSurrogate);
17 
20 {
22  params.addClassDescription("Computes and evaluates Gaussian Process surrogate model.");
23  return params;
24 }
25 
27  : SurrogateModel(parameters),
28  CovarianceInterface(parameters),
29  _gp(declareModelData<StochasticTools::GaussianProcess>("_gp")),
30  _training_params(getModelData<torch::Tensor>("_training_params"))
31 {
32 }
33 
34 void
36 {
37  if (_gp.getCovarFunctionPtr() != nullptr)
38  ::mooseError("Attempting to redefine covariance function using setupCovariance.");
40 }
41 
42 Real
43 GaussianProcessSurrogate::evaluate(const std::vector<Real> & x) const
44 {
45  // Overlaod for evaluate to maintain general compatibility. Only returns mean
46  Real dummy = 0;
47  return this->evaluate(x, dummy);
48 }
49 
50 Real
51 GaussianProcessSurrogate::evaluate(const std::vector<Real> & x, Real & std_dev) const
52 {
53  std::vector<Real> y;
54  std::vector<Real> std;
55  this->evaluate(x, y, std);
56  std_dev = std[0];
57  return y[0];
58 }
59 
60 void
61 GaussianProcessSurrogate::evaluate(const std::vector<Real> & x, std::vector<Real> & y) const
62 {
63  // Overlaod for evaluate to maintain general compatibility. Only returns mean
64  std::vector<Real> std_dummy;
65  this->evaluate(x, y, std_dummy);
66 }
67 
68 void
69 GaussianProcessSurrogate::evaluate(const std::vector<Real> & x,
70  std::vector<Real> & y,
71  std::vector<Real> & std) const
72 {
73  const unsigned int n_dims = _training_params.sizes()[1];
74 
75  mooseAssert(x.size() == n_dims,
76  "Number of parameters provided for evaluation does not match number of parameters "
77  "used for training.");
78  const unsigned int n_outputs = _gp.getCovarFunction().numOutputs();
79 
80  y = std::vector<Real>(n_outputs, 0.0);
81  std = std::vector<Real>(n_outputs, 0.0);
82 
83  const auto options = _training_params.options().dtype(at::kDouble);
84 
85  torch::Tensor test_points = torch::empty({1, n_dims}, at::kDouble);
86  auto points_accessor = test_points.accessor<Real, 2>();
87  for (unsigned int ii = 0; ii < n_dims; ++ii)
88  points_accessor[0][ii] = x[ii];
89  test_points = test_points.to(options.device());
90 
92 
93  torch::Tensor K_train_test =
94  torch::empty({_training_params.sizes()[0] * n_outputs, n_outputs}, options);
95 
97  K_train_test, _training_params, test_points, false);
98  torch::Tensor K_test = torch::empty({n_outputs, n_outputs}, options);
99  _gp.getCovarFunction().computeCovarianceMatrix(K_test, test_points, test_points, true);
100 
101  // Compute the predicted mean value (centered)
102  torch::Tensor pred_value = torch::transpose(
103  torch::mm(torch::transpose(K_train_test, 0, 1), _gp.getKResultsSolve()), 0, 1);
104 
105  // De-center/scale the value and store for return
107 
108  torch::Tensor pred_var =
109  K_test - torch::mm(torch::transpose(K_train_test, 0, 1),
110  torch::cholesky_solve(K_train_test, _gp.getKCholeskyDecomp()));
111 
112  // Only the marginal variances are returned. Clamp tiny negative roundoff before sqrt.
113  torch::Tensor std_dev_vec =
114  torch::sqrt(torch::clamp_min(torch::diagonal(pred_var), 0.0)).unsqueeze(0);
115  _gp.getDataStandardizer().getDescaled(std_dev_vec);
116  const auto std_dev_cpu = LibtorchUtils::toCPUContiguous(std_dev_vec);
117  const auto pred_value_cpu = LibtorchUtils::toCPUContiguous(pred_value);
118  auto std_accessor = std_dev_cpu.accessor<Real, 2>();
119  auto pred_value_accessor = pred_value_cpu.accessor<Real, 2>();
120 
121  for (const auto output_i : make_range(n_outputs))
122  {
123  y[output_i] = pred_value_accessor[0][output_i];
124  std[output_i] = std_accessor[0][output_i];
125  }
126 }
127 
128 #endif
void linkCovarianceFunction(CovarianceFunctionBase *covariance_function)
Finds and links the covariance function to this object.
const torch::Tensor & getKResultsSolve() const
virtual void setupCovariance(UserObjectName _covar_name)
This function is called by LoadCovarianceDataAction when the surrogate is loading training data from ...
const torch::Tensor & _training_params
Paramaters (x) used for training.
const CovarianceFunctionBase & getCovarFunction() const
torch::Tensor toCPUContiguous(const torch::Tensor &tensor)
const std::vector< double > y
Enum for batch type in stochastic tools MultiApp.
static InputParameters validParams()
const std::vector< double > x
void getDescaled(torch::Tensor &input) const
De-scales the assumed scaled input.
Definition: Standardizer.C:103
const CovarianceFunctionBase * getCovarFunctionPtr() const
void getDestandardized(torch::Tensor &input) const
De-standardizes (de-centered and de-scaled) the assumed standardized input.
Definition: Standardizer.C:96
const torch::Tensor & getKCholeskyDecomp() const
const StochasticTools::Standardizer & getParamStandardizer() const
Get constant reference to the contained structures.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
registerMooseObject("StochasticToolsApp", GaussianProcessSurrogate)
NumberTensorValue Tensor
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
virtual Real evaluate(const std::vector< Real > &x) const
Evaluate surrogate model given a row of parameters.
void addClassDescription(const std::string &doc_string)
StochasticTools::GaussianProcess & _gp
unsigned int numOutputs() const
Return the number of outputs assumed for this covariance function.
const StochasticTools::Standardizer & getDataStandardizer() const
static InputParameters validParams()
void getStandardized(torch::Tensor &input) const
Returns the standardized (centered and scaled) of the provided input.
Definition: Standardizer.C:89
virtual void computeCovarianceMatrix(torch::Tensor &K, const torch::Tensor &x, const torch::Tensor &xp, const bool is_self_covariance) const =0
Generates the Covariance Matrix given two sets of points in the parameter space.
GaussianProcessSurrogate(const InputParameters &parameters)
CovarianceFunctionBase * getCovarianceFunctionByName(const UserObjectName &name) const
Lookup a CovarianceFunction object by name and return pointer.