LCOV - code coverage report
Current view: top level - src/vectorpostprocessors - LeastSquaresFitHistory.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 59 62 95.2 %
Date: 2026-05-29 20:35:17 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        3133 : LeastSquaresFitHistory::validParams()
      19             : {
      20        3133 :   InputParameters params = GeneralVectorPostprocessor::validParams();
      21             : 
      22       12532 :   params.addRequiredParam<VectorPostprocessorName>(
      23             :       "vectorpostprocessor",
      24             :       "The vectorpostprocessor on whose values we perform a least squares fit");
      25       12532 :   params.addRequiredParam<std::string>("x_name", "The name of the independent variable");
      26       12532 :   params.addRequiredParam<std::string>("y_name", "The name of the dependent variable");
      27       12532 :   params.addRequiredParam<unsigned int>("order", "The order of the polynomial fit");
      28        9399 :   params.addParam<bool>(
      29             :       "truncate_order",
      30        6266 :       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        9399 :   params.addParam<Real>(
      34        6266 :       "x_scale", 1.0, "Value used to scale x values (scaling is done after shifting)");
      35        9399 :   params.addParam<Real>(
      36        6266 :       "x_shift", 0.0, "Value used to shift x values (shifting is done before scaling)");
      37        9399 :   params.addParam<Real>(
      38        6266 :       "y_scale", 1.0, "Value used to scale y values (scaling is done after shifting)");
      39        9399 :   params.addParam<Real>(
      40        6266 :       "y_shift", 0.0, "Value used to shift y values (shifting is done before scaling)");
      41        6266 :   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        6266 :   params.set<bool>("contains_complete_history") = true;
      46        9399 :   params.addParamNamesToGroup("contains_complete_history", "Advanced");
      47             : 
      48        3133 :   return params;
      49           0 : }
      50             : 
      51          36 : LeastSquaresFitHistory::LeastSquaresFitHistory(const InputParameters & parameters)
      52             :   : GeneralVectorPostprocessor(parameters),
      53          36 :     _vpp_name(getParam<VectorPostprocessorName>("vectorpostprocessor")),
      54          36 :     _order(parameters.get<unsigned int>("order")),
      55          36 :     _truncate_order(parameters.get<bool>("truncate_order")),
      56          72 :     _x_name(getParam<std::string>("x_name")),
      57          72 :     _y_name(getParam<std::string>("y_name")),
      58          72 :     _x_values(getVectorPostprocessorValue("vectorpostprocessor", _x_name)),
      59          72 :     _y_values(getVectorPostprocessorValue("vectorpostprocessor", _y_name)),
      60          36 :     _x_scale(parameters.get<Real>("x_scale")),
      61          36 :     _x_shift(parameters.get<Real>("x_shift")),
      62          36 :     _y_scale(parameters.get<Real>("y_scale")),
      63          36 :     _y_shift(parameters.get<Real>("y_shift")),
      64         144 :     _last_t_step(declareRecoverableData<int>("ls_last_t_step", -1))
      65             : {
      66          36 :   _coeffs.resize(_order + 1);
      67         108 :   for (unsigned int i = 0; i < _coeffs.size(); ++i)
      68          72 :     _coeffs[i] = &declareVector("coef_" + Moose::stringify(i));
      69          72 :   _times = &declareVector("time");
      70          36 : }
      71             : 
      72             : void
      73         102 : LeastSquaresFitHistory::initialize()
      74             : {
      75             :   // no reset/clear needed since contains complete history
      76         102 : }
      77             : 
      78             : void
      79         102 : LeastSquaresFitHistory::execute()
      80             : {
      81         102 :   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         102 :   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         102 :   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          99 :     _last_t_step = _t_step;
      94             : 
      95             :   // Create a copy of _x_values that we can modify.
      96         204 :   std::vector<Real> x_values(_x_values.begin(), _x_values.end());
      97         102 :   std::vector<Real> y_values(_y_values.begin(), _y_values.end());
      98             : 
      99        1224 :   for (MooseIndex(_x_values) i = 0; i < _x_values.size(); ++i)
     100             :   {
     101        1122 :     x_values[i] = (x_values[i] + _x_shift) * _x_scale;
     102        1122 :     y_values[i] = (y_values[i] + _y_shift) * _y_scale;
     103             :   }
     104             : 
     105         102 :   PolynomialFit pf(x_values, y_values, _order, _truncate_order);
     106         102 :   pf.generate();
     107             : 
     108         102 :   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         306 :   for (MooseIndex(coeffs) i = 0; i < coeffs.size(); ++i)
     112         204 :     _coeffs[i]->push_back(coeffs[i]);
     113             : 
     114         102 :   _times->push_back(_t);
     115         102 : }

Generated by: LCOV version 1.14