https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SobolCalculators.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 "SobolCalculators.h"
10
11namespace StochasticTools
12{
13template <typename InType, typename OutType>
15 const std::string & name,
16 bool resample)
17 : Calculator<std::vector<InType>, std::vector<OutType>>(other, name), _resample(resample)
18{
19}
20
21template <typename InType, typename OutType>
22void
24{
25 _amat.resize(0, 0);
26}
27
28template <typename InType, typename OutType>
29void
31{
32 if (_amat.n() == 0)
33 {
34 _amat.resize(data.size(), data.size());
35 if (_amat.n() < 2 || (_resample && _amat.n() % 2 != 0))
36 mooseError("Size of input data is inconsistent with Sobol resampling scheme.");
37 }
38 mooseAssert(_amat.n() == data.size(), "Size of data updating SobolCalculator has changed.");
39
40 for (const auto & c : index_range(data))
41 for (const auto & r : make_range(c + 1))
42 _amat(r, c) += data[r] * data[c];
43}
44
45template <typename InType, typename OutType>
46void
48{
49 // The size of the A matrix
50 std::size_t s = _amat.n();
51
52 if (is_distributed)
53 {
54 this->_communicator.max(s);
55 if (_amat.n() == 0)
56 _amat.resize(s, s);
57 mooseAssert(_amat.n() == s, "Size of data updating SobolCalculator has changed.");
58 this->_communicator.sum(_amat.get_values());
59 }
60
61 // Number of independent parameters
62 const std::size_t n = (s - 2) / (_resample ? 2 : 1);
63
64 // The data to output
65 DenseMatrix<OutType> S(n, n);
66 std::vector<OutType> ST(n);
67
68 // First order
69 {
70 auto E = _amat(0, s - 1);
71 auto V = _amat(s - 1, s - 1) - E;
72 for (std::size_t i = 0; i < n; ++i)
73 {
74 auto U0 = _amat(i + 1, s - 1);
75 if (_resample)
76 {
77 auto U1 = _amat(0, i + n + 1);
78 S(i, i) = (((U0 + U1) / 2) - E) / V;
79 }
80 else
81 S(i, i) = (U0 - E) / V;
82 }
83 }
84
85 // Total-effect
86 {
87 auto E = _amat(0, s - 1);
88 auto V = _amat(0, 0) - E;
89 for (std::size_t i = 0; i < n; ++i)
90 {
91 auto U0 = _amat(0, i + 1);
92 if (_resample)
93 {
94 auto U1 = _amat(i + n + 1, s - 1);
95 ST[i] = 1 - (((U0 + U1) / 2) - E) / V;
96 }
97 else
98 ST[i] = 1 - (U0 - E) / V;
99 }
100 }
101
102 // Second-order
103 if (_resample)
104 {
105 for (std::size_t i = 0; i < n; ++i)
106 {
107 auto E = _amat(i + 1, i + n + 1);
108 for (std::size_t j = 0; j < i; ++j)
109 {
110 auto V = _amat(j + n + 1, j + n + 1) - E;
111 auto U0 = _amat(i + 1, j + n + 1);
112 auto U1 = _amat(j + 1, i + n + 1);
113 auto Sc = (((U0 + U1) / 2) - E) / V;
114 auto S2 = Sc - S(i, i) - S(j, j);
115 S(j, i) = S2;
116 }
117 }
118 }
119
120 // Output the data
121 _sobol.clear();
122 if (_resample)
123 _sobol.reserve(n * (n + 3) / 2);
124 else
125 _sobol.reserve(2 * n);
126
127 // First-order
128 for (std::size_t i = 0; i < n; ++i)
129 _sobol.push_back(S(i, i));
130
131 // Total-effect
132 for (std::size_t i = 0; i < n; ++i)
133 _sobol.push_back(ST[i]);
134
135 // Second-order
136 if (_resample)
137 {
138 for (std::size_t i = 0; i < n; ++i)
139 for (std::size_t j = i + 1; j < n; ++j)
140 _sobol.push_back(S(i, j));
141 }
142}
143
144template class SobolCalculator<std::vector<Real>, Real>;
145template class SobolCalculator<std::vector<std::vector<Real>>, std::vector<Real>>;
146} // namespace
void mooseError(Args &&... args)
const std::string name
Definition Setup.h:21
Calculator for computing Sobol sensitivity indices according to the paper by Saltelli (2002) https://...
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
virtual void initialize() override
This function is used to reset the calculator to its initial state and prepare it for another evaluat...
SobolCalculator(const libMesh::ParallelObject &other, const std::string &name, bool resample)
virtual void update(const InType &data) override
std::vector< T > resample(const std::vector< T > &data, MooseRandom &generator, const std::size_t seed_index=0)
Enum for batch type in stochastic tools MultiApp.