LCOV - code coverage report
Current view: top level - src/surrogates - ActiveLearningGaussianProcess.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: #33416 (b10b36) with base 9fbd27 Lines: 54 71 76.1 %
Date: 2026-07-23 16:21:17 Functions: 4 6 66.7 %
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             : #ifdef MOOSE_LIBTORCH_ENABLED
      10             : 
      11             : #include "ActiveLearningGaussianProcess.h"
      12             : 
      13             : #include <petsctao.h>
      14             : #include <petscdmda.h>
      15             : 
      16             : #include "libmesh/petsc_vector.h"
      17             : #include "libmesh/petsc_matrix.h"
      18             : 
      19             : #include <math.h>
      20             : 
      21             : registerMooseObject("StochasticToolsApp", ActiveLearningGaussianProcess);
      22             : 
      23             : InputParameters
      24         192 : ActiveLearningGaussianProcess::validParams()
      25             : {
      26         192 :   InputParameters params = SurrogateTrainerBase::validParams();
      27         192 :   params.addClassDescription(
      28             :       "Permit re-training Gaussian Process surrogate model for active learning.");
      29         384 :   params.addRequiredParam<UserObjectName>("covariance_function", "Name of covariance function.");
      30         384 :   params.addParam<bool>(
      31         384 :       "standardize_params", true, "Standardize (center and scale) training parameters (x values)");
      32         384 :   params.addParam<bool>(
      33         384 :       "standardize_data", true, "Standardize (center and scale) training data (y values)");
      34         384 :   params.addParam<unsigned int>("num_iters", 1000, "Tolerance value for Adam optimization");
      35         384 :   params.addParam<unsigned int>("batch_size", 0, "The batch size for Adam optimization");
      36         384 :   params.addParam<Real>("learning_rate", 0.001, "The learning rate for Adam optimization");
      37         384 :   params.addParam<MooseEnum>(
      38             :       "optimizer",
      39         576 :       MooseEnum("adam=0 legacy_adam=1", "adam"),
      40             :       "The Adam optimizer semantics to use for Gaussian process hyperparameter tuning.");
      41         384 :   params.addParam<unsigned int>(
      42             :       "show_every_nth_iteration",
      43         384 :       0,
      44             :       "Switch to show Adam optimization loss values at every nth step. If 0, nothing is showed.");
      45         384 :   params.addParam<std::vector<std::string>>(
      46             :       "tune_parameters", {}, "Select hyperparameters to be tuned");
      47         384 :   params.addParam<std::vector<Real>>("tuning_min", {}, "Minimum allowable tuning value");
      48         384 :   params.addParam<std::vector<Real>>("tuning_max", {}, "Maximum allowable tuning value");
      49         192 :   return params;
      50           0 : }
      51             : 
      52          96 : ActiveLearningGaussianProcess::ActiveLearningGaussianProcess(const InputParameters & parameters)
      53             :   : SurrogateTrainerBase(parameters),
      54             :     CovarianceInterface(parameters),
      55             :     SurrogateModelInterface(this),
      56         192 :     _gp(declareModelData<StochasticTools::GaussianProcess>("_gp")),
      57         192 :     _training_params(declareModelData<torch::Tensor>("_training_params")),
      58         192 :     _training_data(declareModelData<torch::Tensor>("_training_data")),
      59         192 :     _standardize_params(getParam<bool>("standardize_params")),
      60         192 :     _standardize_data(getParam<bool>("standardize_data")),
      61          96 :     _optimization_opts(StochasticTools::GaussianProcess::GPOptimizerOptions(
      62         192 :         getParam<unsigned int>("show_every_nth_iteration"),
      63         192 :         getParam<unsigned int>("num_iters"),
      64         192 :         getParam<unsigned int>("batch_size"),
      65         192 :         getParam<Real>("learning_rate"),
      66             :         0.9,
      67             :         0.999,
      68             :         1e-7,
      69             :         1e-4,
      70          96 :         getParam<MooseEnum>("optimizer")
      71          96 :             .getEnum<StochasticTools::GaussianProcess::OptimizerType>()))
      72             : {
      73         576 :   _gp.initialize(getCovarianceFunctionByName(getParam<UserObjectName>("covariance_function")),
      74             :                  getParam<std::vector<std::string>>("tune_parameters"),
      75             :                  getParam<std::vector<Real>>("tuning_min"),
      76             :                  getParam<std::vector<Real>>("tuning_max"));
      77          96 : }
      78             : 
      79             : void
      80         227 : ActiveLearningGaussianProcess::reTrain(const std::vector<std::vector<Real>> & inputs,
      81             :                                        const std::vector<Real> & outputs) const
      82             : {
      83             :   // Addtional error check for each re-train call of the GP surrogate
      84         227 :   if (inputs.size() != outputs.size())
      85           0 :     mooseError("Number of inputs (",
      86           0 :                inputs.size(),
      87             :                ") does not match number of outputs (",
      88           0 :                outputs.size(),
      89             :                ").");
      90         227 :   if (inputs.empty())
      91           0 :     mooseError("There is no data for retraining.");
      92             : 
      93             :   const auto input_size = inputs[0].size();
      94             :   std::vector<Real> flat_inputs;
      95         227 :   flat_inputs.reserve(outputs.size() * input_size);
      96             : 
      97        2576 :   for (const auto & input : inputs)
      98             :   {
      99        2349 :     if (input.size() != input_size)
     100           0 :       mooseError("All active learning retraining inputs must have the same dimension.");
     101        2349 :     flat_inputs.insert(flat_inputs.end(), input.begin(), input.end());
     102             :   }
     103             : 
     104         454 :   _training_params = LibtorchUtils::vectorToTensorCopy(
     105             :       flat_inputs, {cast_int<int64_t>(outputs.size()), cast_int<int64_t>(input_size)});
     106         227 :   _training_data =
     107         227 :       LibtorchUtils::vectorToTensorCopy(outputs, {cast_int<int64_t>(outputs.size()), 1});
     108             : 
     109         227 :   LibtorchUtils::moveToLibtorchDevice(_training_params, _app.getLibtorchDevice());
     110         227 :   LibtorchUtils::moveToLibtorchDevice(_training_data, _app.getLibtorchDevice());
     111             : 
     112             :   // Standardize (center and scale) training params
     113         227 :   if (_standardize_params)
     114         227 :     _gp.standardizeParameters(_training_params);
     115             :   // if not standardizing data set mean=0, std=1 for use in surrogate
     116             :   else
     117           0 :     _gp.paramStandardizer().set(0, 1, input_size);
     118             : 
     119             :   // Standardize (center and scale) training data
     120         227 :   if (_standardize_data)
     121         227 :     _gp.standardizeData(_training_data);
     122             :   // if not standardizing data set mean=0, std=1 for use in surrogate
     123             :   else
     124           0 :     _gp.dataStandardizer().set(0, 1);
     125             : 
     126             :   // Setup the covariance
     127         227 :   _gp.setupCovarianceMatrix(_training_params, _training_data, _optimization_opts);
     128         227 : }
     129             : 
     130             : const std::vector<Real> &
     131          86 : ActiveLearningGaussianProcess::getLengthScales() const
     132             : {
     133          86 :   return _gp.getLengthScales();
     134             : }
     135             : 
     136             : const StochasticTools::Standardizer &
     137           0 : ActiveLearningGaussianProcess::getTrainingStandardizer() const
     138             : {
     139           0 :   return _gp.getDataStandardizer();
     140             : }
     141             : 
     142             : void
     143           0 : ActiveLearningGaussianProcess::getNormTrainingOuts(std::vector<Real> & norm_training_outs) const
     144             : {
     145           0 :   norm_training_outs.resize(_training_data.size(0));
     146           0 :   const auto training_data = LibtorchUtils::toCPUContiguous(_training_data);
     147           0 :   const auto data_accessor = training_data.accessor<Real, 2>();
     148           0 :   for (unsigned int i = 0; i < norm_training_outs.size(); ++i)
     149           0 :     norm_training_outs[i] = data_accessor[i][0];
     150           0 : }
     151             : 
     152             : #endif

Generated by: LCOV version 1.14