LCOV - code coverage report
Current view: top level - src/samplers - DirectPerturbationSampler.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: f45d79 Lines: 37 40 92.5 %
Date: 2025-07-25 05:00:46 Functions: 5 6 83.3 %
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 "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             : }

Generated by: LCOV version 1.14