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 : }