https://mooseframework.inl.gov
Loading...
Searching...
No Matches
GeneralSensorPostprocessor.C
Go to the documentation of this file.
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#include <vector>
10#include <cmath>
11#include <algorithm>
12#include <numeric>
13
15#include "Function.h"
16#include "MooseRandom.h"
17#include "LinearInterpolation.h"
18#include "SplineInterpolation.h"
19
21
24{
26 params.addRequiredParam<PostprocessorName>("input_signal", "The input signal postprocessor");
27 params.addParam<FunctionName>(
28 "drift_function", 0.0, "Drift function describing signal drift over time");
29 params.addParam<Real>("vector_size", 1000000000.0, "The maximum size of vector to be saved");
30 params.addClassDescription("This is a GeneralSensorPostprocessor, and functions as a base class "
31 "for other sensor postprocessors");
32 params.addParam<FunctionName>(
33 "efficiency_function", 0.8, "Efficiency function describing efficiency over time");
34 params.addParam<FunctionName>(
35 "noise_std_dev_function",
36 0.5,
37 "Standard deviation of noise function describing noise standard deviation over time");
38 params.addParam<FunctionName>(
39 "signalToNoise_function", 0.2, "Signal to noise ratio for the modeled sensor");
40 params.addParam<FunctionName>(
41 "delay_function", 0.1, "Delay function describing the delay over time");
42 params.addParam<FunctionName>(
43 "uncertainty_std_dev_function",
44 0.1,
45 "Standard deviation of uncertainty function describing uncertainty std dev over time");
46 params.addParam<FunctionName>("R_function", 1, "The function R for the integration term.");
47 params.addParam<Real>("proportional_weight", 1, "The weight assigned to the proportional term");
48 params.addParam<Real>("integral_weight", 0, "The weight assigned to the integral term");
49 params.addParam<unsigned int>("seed", 1, "Seed for the random number generator");
50 return params;
51}
52
54 : GeneralPostprocessor(parameters),
55 _input_signal(getPostprocessorValue("input_signal")),
56 _drift_function(getFunction("drift_function")),
57 _vector_size(getParam<Real>("vector_size")),
58 _pp_old(getPostprocessorValueOld("input_signal")),
59 _efficiency_function(getFunction("efficiency_function")),
60 _noise_std_dev_function(getFunction("noise_std_dev_function")),
61 _delay_function(getFunction("delay_function")),
62 _signalToNoise_function(getFunction("signalToNoise_function")),
63 _uncertainty_std_dev_function(getFunction("uncertainty_std_dev_function")),
64 _R_function(getFunction("R_function")),
65 _proportional_weight(getParam<Real>("proportional_weight")),
66 _integral_weight(getParam<Real>("integral_weight")),
67 _time_values(declareRestartableData<std::vector<Real>>("time_values")),
68 _input_signal_values(declareRestartableData<std::vector<Real>>("input_signal_values")),
69 _integrand(declareRestartableData<std::vector<Real>>("integrand")),
70 _R_function_values(declareRestartableData<std::vector<Real>>("R_function_values")),
71 _t_step_old(declareRestartableData<int>("gsp_t_step_old", -1)),
72 _seed(getParam<unsigned int>("seed")),
73 _delay_value(0) // Initialize delay_value at 0
74{
75}
76
77void
79{
80 Real drift_value = _drift_function.value(_t);
81 Real efficiency_value = _efficiency_function.value(_t);
82 Real signalToNoise_value = _signalToNoise_function.value(_t);
83 // setting seed for random number generator
85 Real noise_std_dev = _noise_std_dev_function.value(_t);
86 Real noise_value = _rng.randNormal(0, noise_std_dev);
87 Real uncertainty_std_dev = _uncertainty_std_dev_function.value(_t);
88 Real uncertainty_value = _rng.randNormal(0, uncertainty_std_dev);
89 // Added line to calculate delay_value from the delay function
91
92 // if the problem is steady-state
94 {
95 // output
96 _sensor_value = drift_value +
97 efficiency_value * (_input_signal + signalToNoise_value * noise_value) +
98 uncertainty_value;
99 }
100
101 // if the problem is transient
102 else
103 {
104 // Remove last element if we are repeating the timestep
105 mooseAssert(_t_step_old <= _t_step,
106 "The old time step needs to be behind or the same as the current time step.");
107 if (_t_step_old == _t_step)
108 {
109 _time_values.pop_back();
110 _input_signal_values.pop_back();
111 _integrand.pop_back();
112 _R_function_values.pop_back();
113 }
114
115 _time_values.push_back(_t);
117
118 // Check if the size is greater than _vector_size
120 {
121 // Remove the first 10 elements if size is larger
122 _time_values.erase(_time_values.begin(), _time_values.begin() + 10);
124 }
125 Real _input_signal_delayed = getDelayedInputSignal();
126
127 // computing integral term
128 Real term_for_integration = _input_signal + signalToNoise_value * noise_value;
129 _integrand.push_back(term_for_integration);
131
132 // output
133 Real proportional_value = _input_signal_delayed + signalToNoise_value * noise_value;
134 _sensor_value = drift_value +
135 efficiency_value * (_proportional_weight * proportional_value +
137 uncertainty_value;
138
139 // Update old time step
141 }
142}
143
149
150std::vector<Real>
151GeneralSensorPostprocessor::elementwiseMultiply(std::vector<Real> & vec1, std::vector<Real> & vec2)
152{
153 // Ensure both vectors have the same size
154 mooseAssert(vec1.size() == vec2.size(),
155 "Vectors must have the same size for element-wise multiplication.");
156 // Create a result vector
157 std::vector<Real> result;
158 // Perform element-wise multiplication
159 result.reserve(vec1.size());
160 for (const auto i : index_range(vec1))
161 result.push_back(vec1[i] * vec2[i]);
162 return result;
163}
164
165Real
167{
168 // delayed input signal
169 Real t_desired = _t - _delay_value;
170 Real input_signal_delayed;
171
172 if (t_desired < _time_values[0])
173 input_signal_delayed = 0;
174
175 // Modified cases where desired time isin the time value list
176 else if (t_desired == _time_values[0])
177 input_signal_delayed = _input_signal_values[0];
178
179 // linear interpolation
180 else if (t_desired > _time_values[0] && t_desired <= _t && t_desired >= _t - _dt)
181 input_signal_delayed = _input_signal + (t_desired - _t) * (_pp_old - _input_signal) / (-_dt);
182
183 else if (t_desired > _time_values[0] && t_desired < _t - _dt)
184 {
186 input_signal_delayed = time_and_input_signal.sample(t_desired);
187 }
188
189 else
190 mooseError("Unhandled case in interpolation values.");
191
192 return input_signal_delayed;
193}
194
195vector<Real>
201
202Real
203GeneralSensorPostprocessor::getIntegral(std::vector<Real> integrand)
204{
205 Real integration_value;
206 getRVector();
207 // calculate the total integrand vector including previous integrand and exponential terms
209
210 // if there are more than two datapoints, do simpson's 3/8 rule for integration
211 // else do trapezoidal rule
212 if (_time_values.size() > 2)
213 {
215 // number of intervals
216 Real n;
217
218 // if number of datapoints is less than 30, use spline interpolation to get 30 intervals
219 if (_time_values.size() < 30)
220 n = 30;
221 else
222 {
223 n = _time_values.size();
224 // if interval is not a multiple of 3, make it
225 while (static_cast<int>(n) % 3 != 0)
226 n = n + 1;
227 }
228
229 Real h = (_time_values.back() - _time_values[0]) / n; // distance between time values
230 // time vector for simpson integration
231 vector<Real> time_vec_simp;
232 // integrand vector for simpson integration
233 vector<Real> integrand_vec_simp;
234
235 for (Real i = 0; i < n + 1; i++)
236 {
237 Real new_time = _time_values[0] + i * h;
238 time_vec_simp.push_back(new_time);
239 Real new_integrand = spline.SplineInterpolation::sample(new_time);
240 integrand_vec_simp.push_back(new_integrand);
241 }
242
243 // initialize integral with endpoints
244 integration_value = integrand_vec_simp[0] + integrand_vec_simp[n];
245
246 // Sum for points not at endpoints
247 for (int i = 1; i < n; ++i)
248 {
249 if (i % 3 == 0)
250 // Every third point
251 integration_value += 2 * integrand_vec_simp[i];
252 else
253 integration_value += 3 * integrand_vec_simp[i];
254 }
255
256 // Multiply by 3h/8
257 integration_value *= (3 * h) / 8.0;
258 }
259
260 else
261 {
262 // performing integration by trapezoidal rule, not accurate
263 // LinearInterpolation object with two vectors
265 // integrate the vectors
266 integration_value = integral.integrate();
267 }
268
269 return integration_value;
270}
registerMooseObject("MiscApp", GeneralSensorPostprocessor)
Real PostprocessorValue
void ErrorVector unsigned int
virtual bool isTransient() const override
virtual Real value(Real t, const Point &p) const
static InputParameters validParams()
A generalized sensor Postprocessor.
const Function & _drift_function
The drift function to be evaluated and returned.
std::vector< Real > elementwiseMultiply(std::vector< Real > &vec1, std::vector< Real > &vec2)
Function for element-wise multiplication of vectors.
const Function & _R_function
Function R for integration term.
int & _t_step_old
The last time step this object was executed on.
std::vector< Real > & _R_function_values
vector to store R function values
const Real _proportional_weight
A weighing factor for the proportional term.
const Function & _signalToNoise_function
Signal to noise function.
Real _sensor_value
for getValue() output
virtual vector< Real > getRVector()
Function to calculate R vector.
std::vector< Real > & _input_signal_values
Input Signal vector for calculating delay.
const Real _integral_weight
A weighing factor for the integral term.
const PostprocessorValue & _input_signal
A postprocessor used as the sensor input signal.
const Function & _uncertainty_std_dev_function
Uncertainty std dev function.
const Function & _efficiency_function
Efficiency function.
const PostprocessorValue & _pp_old
The old value of the postprocessor.
std::vector< Real > & _time_values
Time vector for calculating delay.
const unsigned int _seed
To get fixed seed random numbers.
const Real _vector_size
Size of vector to be stored.
Real _delay_value
Variable to store delay value.
Real getIntegral(std::vector< Real > integrand)
Function to calculate integral term.
const Function & _delay_function
Delay function.
const Function & _noise_std_dev_function
Noise standard deviation function.
Real getDelayedInputSignal()
Function to calculate delayed input signal.
std::vector< Real > & _integrand
Vector to store integrand data for numerical integration.
virtual PostprocessorValue getValue() const override
GeneralSensorPostprocessor(const InputParameters &parameters)
static InputParameters validParams()
Real _integration_value
the output of the integrand
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T sample(const T &x) const
void mooseError(Args &&... args) const
void seed(std::size_t i, unsigned int seed)
Real randNormal(std::size_t i, Real mean, Real sigma)
FEProblemBase & _fe_problem
Real integrand(const Point &p)