LCOV - code coverage report
Current view: top level - src/vectorpostprocessors - LeastSquaresFitHistory.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 59 62 95.2 %
Date: 2025-08-08 20:01:16 Functions: 5 5 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             : #include "LeastSquaresFitHistory.h"
      11             : #include "VectorPostprocessorInterface.h"
      12             : #include "PolynomialFit.h"
      13             : #include "Conversion.h"
      14             : 
      15             : registerMooseObject("MooseApp", LeastSquaresFitHistory);
      16             : 
      17             : InputParameters
      18       14343 : LeastSquaresFitHistory::validParams()
      19             : {
      20       14343 :   InputParameters params = GeneralVectorPostprocessor::validParams();
      21             : 
      22       14343 :   params.addRequiredParam<VectorPostprocessorName>(
      23             :       "vectorpostprocessor",
      24             :       "The vectorpostprocessor on whose values we perform a least squares fit");
      25       14343 :   params.addRequiredParam<std::string>("x_name", "The name of the independent variable");
      26       14343 :   params.addRequiredParam<std::string>("y_name", "The name of the dependent variable");
      27       14343 :   params.addRequiredParam<unsigned int>("order", "The order of the polynomial fit");
      28       43029 :   params.addParam<bool>(
      29             :       "truncate_order",
      30       28686 :       true,
      31             :       "Truncate the order of the fitted polynomial if an insufficient number of data points are "
      32             :       "provided. If this is set to false, an error will be generated in that case.");
      33       43029 :   params.addParam<Real>(
      34       28686 :       "x_scale", 1.0, "Value used to scale x values (scaling is done after shifting)");
      35       43029 :   params.addParam<Real>(
      36       28686 :       "x_shift", 0.0, "Value used to shift x values (shifting is done before scaling)");
      37       43029 :   params.addParam<Real>(
      38       28686 :       "y_scale", 1.0, "Value used to scale y values (scaling is done after shifting)");
      39       43029 :   params.addParam<Real>(
      40       28686 :       "y_shift", 0.0, "Value used to shift y values (shifting is done before scaling)");
      41       14343 :   params.addClassDescription(
      42             :       "Performs a polynomial least squares fit on the data contained in "
      43             :       "another VectorPostprocessor and stores the full time history of the coefficients");
      44             : 
      45       14343 :   params.set<bool>("contains_complete_history") = true;
      46       14343 :   params.addParamNamesToGroup("contains_complete_history", "Advanced");
      47             : 
      48       14343 :   return params;
      49           0 : }
      50             : 
      51          39 : LeastSquaresFitHistory::LeastSquaresFitHistory(const InputParameters & parameters)
      52             :   : GeneralVectorPostprocessor(parameters),
      53          39 :     _vpp_name(getParam<VectorPostprocessorName>("vectorpostprocessor")),
      54          39 :     _order(parameters.get<unsigned int>("order")),
      55          39 :     _truncate_order(parameters.get<bool>("truncate_order")),
      56          39 :     _x_name(getParam<std::string>("x_name")),
      57          39 :     _y_name(getParam<std::string>("y_name")),
      58          39 :     _x_values(getVectorPostprocessorValue("vectorpostprocessor", _x_name)),
      59          39 :     _y_values(getVectorPostprocessorValue("vectorpostprocessor", _y_name)),
      60          39 :     _x_scale(parameters.get<Real>("x_scale")),
      61          39 :     _x_shift(parameters.get<Real>("x_shift")),
      62          39 :     _y_scale(parameters.get<Real>("y_scale")),
      63          39 :     _y_shift(parameters.get<Real>("y_shift")),
      64          78 :     _last_t_step(declareRecoverableData<int>("ls_last_t_step", -1))
      65             : {
      66          39 :   _coeffs.resize(_order + 1);
      67         117 :   for (unsigned int i = 0; i < _coeffs.size(); ++i)
      68          78 :     _coeffs[i] = &declareVector("coef_" + Moose::stringify(i));
      69          39 :   _times = &declareVector("time");
      70          39 : }
      71             : 
      72             : void
      73         111 : LeastSquaresFitHistory::initialize()
      74             : {
      75             :   // no reset/clear needed since contains complete history
      76         111 : }
      77             : 
      78             : void
      79         111 : LeastSquaresFitHistory::execute()
      80             : {
      81         111 :   if (_x_values.size() != _y_values.size())
      82           0 :     mooseError("In LeastSquresFitTimeHistory size of data in x_values and y_values must be equal");
      83         111 :   if (_x_values.size() == 0)
      84           0 :     mooseError("In LeastSquresFitTimeHistory size of data in x_values and y_values must be > 0");
      85             : 
      86             :   // If we are repeating a timestep, make sure to clear the last entry
      87         111 :   if (_last_t_step == _t_step)
      88             :   {
      89           9 :     std::for_each(_coeffs.begin(), _coeffs.end(), [](auto coeff) { coeff->pop_back(); });
      90           3 :     _times->pop_back();
      91             :   }
      92             :   else
      93         108 :     _last_t_step = _t_step;
      94             : 
      95             :   // Create a copy of _x_values that we can modify.
      96         111 :   std::vector<Real> x_values(_x_values.begin(), _x_values.end());
      97         111 :   std::vector<Real> y_values(_y_values.begin(), _y_values.end());
      98             : 
      99        1332 :   for (MooseIndex(_x_values) i = 0; i < _x_values.size(); ++i)
     100             :   {
     101        1221 :     x_values[i] = (x_values[i] + _x_shift) * _x_scale;
     102        1221 :     y_values[i] = (y_values[i] + _y_shift) * _y_scale;
     103             :   }
     104             : 
     105         111 :   PolynomialFit pf(x_values, y_values, _order, _truncate_order);
     106         111 :   pf.generate();
     107             : 
     108         111 :   std::vector<Real> coeffs = pf.getCoefficients();
     109             :   mooseAssert(coeffs.size() == _coeffs.size(),
     110             :               "Sizes of current coefficients and vector of coefficient vectors must match");
     111         333 :   for (MooseIndex(coeffs) i = 0; i < coeffs.size(); ++i)
     112         222 :     _coeffs[i]->push_back(coeffs[i]);
     113             : 
     114         111 :   _times->push_back(_t);
     115         111 : }

Generated by: LCOV version 1.14