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