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 "DirectPerturbationSampler.h" 11 : #include "DelimitedFileReader.h" 12 : 13 : registerMooseObject("StochasticToolsApp", DirectPerturbationSampler); 14 : 15 : InputParameters 16 410 : DirectPerturbationSampler::validParams() 17 : { 18 410 : InputParameters params = Sampler::validParams(); 19 410 : params.addClassDescription( 20 : "Sampler that creates samples for a direct perturbation-based sensitivity study."); 21 820 : params.addRequiredParam<std::vector<Real>>( 22 : "nominal_parameter_values", 23 : "The nominal values of the parameters around which we shall perturb them."); 24 820 : params.addParam<std::vector<Real>>( 25 : "relative_perturbation_intervals", 26 : {0.01}, 27 : "The numbers by which the nominal values are multiplied to get a perturbed value."); 28 820 : MooseEnum perturbation_type("central_difference forward_difference", "central_difference"); 29 820 : params.addParam<MooseEnum>("perturbation_method", 30 : perturbation_type, 31 : "The perturbation method to use for creating samples."); 32 : 33 410 : return params; 34 410 : } 35 : 36 238 : DirectPerturbationSampler::DirectPerturbationSampler(const InputParameters & parameters) 37 : : Sampler(parameters), 38 238 : _nominal_values(getParam<std::vector<Real>>("nominal_parameter_values")), 39 476 : _relative_intervals(getParam<std::vector<Real>>("relative_perturbation_intervals")), 40 952 : _perturbation_method(getParam<MooseEnum>("perturbation_method")) 41 : { 42 : // TODO: we need to add capability to do absolute intervals too, in case there is a material 43 : // property with a nominal value of 0.0 44 952 : for (const auto interval : _relative_intervals) 45 714 : if (interval <= 0.0 || interval >= 1.0) 46 0 : paramError("relative_perturbation_intervals", 47 : "The relative perturbation interval must be between 0 and 1!"); 48 : 49 : // The number of samples will always include an addition sample for the reference point 50 : dof_id_type num_samples = 0; 51 238 : if (_perturbation_method == "central_difference") 52 130 : num_samples = 2 * _nominal_values.size() + 1; 53 : else 54 108 : num_samples = _nominal_values.size() + 1; 55 : 56 : // Adjusting the sample matrix 57 238 : setNumberOfRows(num_samples); 58 238 : setNumberOfCols(_nominal_values.size()); 59 : 60 238 : _absolute_intervals = std::vector<Real>(num_samples - 1, 0); 61 476 : _parameter_vectors = std::vector<std::vector<Real>>(num_samples, _nominal_values); 62 : 63 : // Depending on what kind of perturbation we selected, the parameter values will change 64 238 : if (_perturbation_method == "central_difference") 65 520 : for (const auto i : index_range(_nominal_values)) 66 : { 67 390 : _absolute_intervals[i] = _nominal_values[i] * _relative_intervals[i]; 68 : // +1 because the first sample is the reference point 69 390 : _parameter_vectors[2 * i + 1][i] += _absolute_intervals[i] / 2; 70 390 : _parameter_vectors[2 * i + 2][i] -= _absolute_intervals[i] / 2; 71 : } 72 : else 73 432 : for (const auto i : index_range(_nominal_values)) 74 : { 75 324 : _absolute_intervals[i] = _nominal_values[i] * _relative_intervals[i]; 76 324 : _parameter_vectors[i + 1][i] += _absolute_intervals[i]; 77 : } 78 238 : } 79 : 80 : Real 81 768 : DirectPerturbationSampler::getAbsoluteInterval(const Real param_index) const 82 : { 83 : mooseAssert(param_index < _absolute_intervals.size(), 84 : "We don't have the required absolute interval!"); 85 768 : return _absolute_intervals[param_index]; 86 : } 87 : 88 : Real 89 192 : DirectPerturbationSampler::getRelativeInterval(const Real param_index) const 90 : { 91 : mooseAssert(param_index < _absolute_intervals.size(), 92 : "We don't have the required relative interval!"); 93 192 : return _relative_intervals[param_index]; 94 : } 95 : 96 : Real 97 0 : DirectPerturbationSampler::getNominalValue(const Real param_index) const 98 : { 99 : mooseAssert(param_index < _nominal_values.size(), 100 : "We don't have the required nominal values for the given parameter!"); 101 0 : return _nominal_values[param_index]; 102 : } 103 : 104 : Real 105 2190 : DirectPerturbationSampler::computeSample(dof_id_type row_index, dof_id_type col_index) 106 : { 107 2190 : return _parameter_vectors[row_index][col_index]; 108 : }