LCOV - code coverage report
Current view: top level - src/vectorpostprocessors - LeastSquaresFit.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 86 94 91.5 %
Date: 2025-07-17 01:28:37 Functions: 4 4 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 "LeastSquaresFit.h"
      11             : #include "VectorPostprocessorInterface.h"
      12             : #include "PolynomialFit.h"
      13             : 
      14             : registerMooseObject("MooseApp", LeastSquaresFit);
      15             : 
      16             : InputParameters
      17       14477 : LeastSquaresFit::validParams()
      18             : {
      19       14477 :   InputParameters params = GeneralVectorPostprocessor::validParams();
      20             : 
      21       14477 :   params.addRequiredParam<VectorPostprocessorName>(
      22             :       "vectorpostprocessor",
      23             :       "The vectorpostprocessor on whose values we perform a least squares fit");
      24       14477 :   params.addRequiredParam<std::string>("x_name", "The name of the independent variable");
      25       14477 :   params.addRequiredParam<std::string>("y_name", "The name of the dependent variable");
      26       14477 :   params.addRequiredParam<unsigned int>("order", "The order of the polynomial fit");
      27       43431 :   params.addParam<bool>(
      28             :       "truncate_order",
      29       28954 :       true,
      30             :       "Truncate the order of the fitted polynomial if an insufficient number of data points are "
      31             :       "provided. If this is set to false, an error will be generated in that case.");
      32       14477 :   params.addParam<unsigned int>("num_samples", "The number of samples to be output");
      33       43431 :   params.addParam<Real>(
      34       28954 :       "x_scale", 1.0, "Value used to scale x values (scaling is done after shifting)");
      35       43431 :   params.addParam<Real>(
      36       28954 :       "x_shift", 0.0, "Value used to shift x values (shifting is done before scaling)");
      37       43431 :   params.addParam<Real>(
      38       28954 :       "y_scale", 1.0, "Value used to scale y values (scaling is done after shifting)");
      39       43431 :   params.addParam<Real>(
      40       28954 :       "y_shift", 0.0, "Value used to shift y values (shifting is done before scaling)");
      41       14477 :   params.addParam<Real>("sample_x_min", "The minimum x value of the of samples to be output");
      42       14477 :   params.addParam<Real>("sample_x_max", "The maximum x value of the of samples to be output");
      43       14477 :   MooseEnum output_type("Coefficients Samples", "Coefficients");
      44       14477 :   params.addParam<MooseEnum>(
      45       28954 :       "output", output_type, "The quantity to output.  Options are: " + output_type.getRawNames());
      46       14477 :   params.addClassDescription("Performs a polynomial least squares fit on the data contained in "
      47             :                              "another VectorPostprocessor");
      48             : 
      49       28954 :   return params;
      50       14477 : }
      51             : 
      52         106 : LeastSquaresFit::LeastSquaresFit(const InputParameters & parameters)
      53             :   : GeneralVectorPostprocessor(parameters),
      54         106 :     _vpp_name(getParam<VectorPostprocessorName>("vectorpostprocessor")),
      55         106 :     _order(parameters.get<unsigned int>("order")),
      56         106 :     _truncate_order(parameters.get<bool>("truncate_order")),
      57         106 :     _x_name(getParam<std::string>("x_name")),
      58         106 :     _y_name(getParam<std::string>("y_name")),
      59         106 :     _x_values(getVectorPostprocessorValue("vectorpostprocessor", _x_name)),
      60         106 :     _y_values(getVectorPostprocessorValue("vectorpostprocessor", _y_name)),
      61         106 :     _output_type(getParam<MooseEnum>("output")),
      62         106 :     _num_samples(0),
      63         106 :     _x_scale(parameters.get<Real>("x_scale")),
      64         106 :     _x_shift(parameters.get<Real>("x_shift")),
      65         106 :     _y_scale(parameters.get<Real>("y_scale")),
      66         106 :     _y_shift(parameters.get<Real>("y_shift")),
      67         106 :     _have_sample_x_min(isParamValid("sample_x_min")),
      68         106 :     _have_sample_x_max(isParamValid("sample_x_max")),
      69         106 :     _sample_x(NULL),
      70         106 :     _sample_y(NULL),
      71         106 :     _coeffs(NULL)
      72             : {
      73         106 :   if (_output_type == "Samples")
      74             :   {
      75          36 :     if (isParamValid("num_samples"))
      76          36 :       _num_samples = getParam<unsigned int>("num_samples");
      77             :     else
      78           0 :       mooseError("In LeastSquaresFit num_samples parameter must be provided with output=Samples");
      79             : 
      80          36 :     if (_have_sample_x_min)
      81           0 :       _sample_x_min = getParam<Real>("sample_x_min");
      82          36 :     if (_have_sample_x_max)
      83           0 :       _sample_x_max = getParam<Real>("sample_x_max");
      84             : 
      85          36 :     _sample_x = &declareVector(_x_name);
      86          36 :     _sample_y = &declareVector(_y_name);
      87             :   }
      88             :   else
      89             :   {
      90          70 :     if (isParamValid("num_samples"))
      91           0 :       mooseWarning("In LeastSquaresFit num_samples parameter is unused with output=Coefficients");
      92          70 :     _coeffs = &declareVector("coefficients");
      93             :   }
      94             : 
      95         106 :   if (_output_type == "Samples")
      96             :   {
      97          36 :     _sample_x->resize(_num_samples);
      98          36 :     _sample_y->resize(_num_samples);
      99             :   }
     100             :   else
     101          70 :     _coeffs->resize(_order + 1);
     102         106 : }
     103             : 
     104             : void
     105         100 : LeastSquaresFit::initialize()
     106             : {
     107         100 :   if (_output_type == "Samples")
     108             :   {
     109          33 :     _sample_x->clear();
     110          33 :     _sample_y->clear();
     111             :   }
     112             :   else
     113          67 :     _coeffs->clear();
     114         100 : }
     115             : 
     116             : void
     117         100 : LeastSquaresFit::execute()
     118             : {
     119         100 :   if (_x_values.size() != _y_values.size())
     120           0 :     mooseError("Size of data in x_values and y_values must be equal");
     121         100 :   if (_x_values.size() == 0)
     122           0 :     mooseError("Size of data in x_values and y_values must be > 0");
     123             : 
     124             :   // Create a copy of _x_values that we can modify.
     125         100 :   std::vector<Real> x_values(_x_values.begin(), _x_values.end());
     126         100 :   std::vector<Real> y_values(_y_values.begin(), _y_values.end());
     127             : 
     128         898 :   for (MooseIndex(_x_values) i = 0; i < _x_values.size(); ++i)
     129             :   {
     130         798 :     x_values[i] = (x_values[i] + _x_shift) * _x_scale;
     131         798 :     y_values[i] = (y_values[i] + _y_shift) * _y_scale;
     132             :   }
     133             : 
     134         100 :   PolynomialFit pf(x_values, y_values, _order, _truncate_order);
     135          96 :   pf.generate();
     136             : 
     137          96 :   if (_output_type == "Samples")
     138             :   {
     139             :     Real x_min;
     140          33 :     if (_have_sample_x_min)
     141           0 :       x_min = _sample_x_min;
     142             :     else
     143          33 :       x_min = *(std::min_element(x_values.begin(), x_values.end()));
     144             : 
     145             :     Real x_max;
     146          33 :     if (_have_sample_x_max)
     147           0 :       x_max = _sample_x_max;
     148             :     else
     149          33 :       x_max = *(std::max_element(x_values.begin(), x_values.end()));
     150             : 
     151          33 :     Real x_span = x_max - x_min;
     152             : 
     153         693 :     for (unsigned int i = 0; i < _num_samples; ++i)
     154             :     {
     155         660 :       Real x = x_min + static_cast<Real>(i) / _num_samples * x_span;
     156         660 :       _sample_x->push_back(x);
     157         660 :       _sample_y->push_back(pf.sample(x));
     158             :     }
     159             :   }
     160             :   else
     161          63 :     *_coeffs = pf.getCoefficients();
     162          96 : }

Generated by: LCOV version 1.14