Line data Source code
1 : // MOOSE includes
2 : #include "DelimitedFileReader.h"
3 : #include "LinearInterpolation.h"
4 :
5 : // MASTODON includes
6 : #include "HazardCurve.h"
7 : #include "MastodonUtils.h"
8 :
9 : registerMooseObject("MastodonApp", HazardCurve);
10 :
11 : InputParameters
12 25 : HazardCurve::validParams()
13 : {
14 25 : InputParameters params = GeneralUserObject::validParams();
15 25 : params.addClassDescription(
16 : "Reads the hazard curve file and creates ground motion bins for time-based assessment.");
17 25 : params.set<ExecFlagEnum>("execute_on") = EXEC_NONE;
18 25 : params.suppressParameter<ExecFlagEnum>("execute_on");
19 50 : params.addRequiredParam<UserObjectName>("ground_motions",
20 : "The GroundMotionReader object to extract ground motion "
21 : "data from to build the hazard curve.");
22 50 : params.addRequiredParam<std::string>("filename", "The hazard curve csv filename.");
23 50 : params.addParam<unsigned int>(
24 50 : "number_of_bins", 10, "The number of bins to create from the hazard curve data.");
25 50 : params.addRequiredParam<std::vector<Real>>("reference_acceleration",
26 : "Ground motion reference acceleration(s).");
27 25 : return params;
28 0 : }
29 :
30 13 : HazardCurve::HazardCurve(const InputParameters & parameters)
31 : : GeneralUserObject(parameters),
32 13 : _hazard_reader(getParam<std::string>("filename")),
33 26 : _ground_motion_reader(getUserObject<GroundMotionReader>("ground_motions"))
34 : {
35 13 : const unsigned int & n_bins = getParam<unsigned int>("number_of_bins");
36 26 : const std::vector<Real> & ref = getParam<std::vector<Real>>("reference_acceleration");
37 13 : if (ref.size() == 1)
38 12 : _reference.resize(n_bins, ref[0]);
39 1 : else if (ref.size() == n_bins)
40 0 : _reference = ref;
41 : else
42 1 : mooseError("The 'reference_acceleration' input must (size: ",
43 1 : ref.size(),
44 : ") in the '",
45 : name(),
46 : "' block should be a scalar or a vector equal to the length of the "
47 : "prescribed number of bins (",
48 : n_bins,
49 : ").");
50 :
51 12 : execute();
52 12 : }
53 :
54 : void
55 12 : HazardCurve::execute()
56 : {
57 12 : _hazard_reader.read();
58 24 : _ground_motion_data = HazardCurve::execute(
59 12 : name(), _reference, _hazard_reader, _ground_motion_reader.readers(), _hazard_sample);
60 12 : }
61 :
62 : const std::vector<Real> &
63 336 : HazardCurve::getData(const std::size_t & bin,
64 : const std::size_t & index,
65 : const GroundMotionReader::Component & comp) const
66 : {
67 336 : if (bin >= _ground_motion_data.size())
68 0 : mooseError("The supplied bin number (",
69 : bin,
70 : ") is out of range of the available number of bins (",
71 0 : _ground_motion_data.size(),
72 : ").");
73 336 : if (index >= _ground_motion_data[bin].size())
74 0 : mooseError("The supplied index number (",
75 : index,
76 : ") is out of range of the available number of ground motions (",
77 0 : _ground_motion_data[bin].size(),
78 : ").");
79 336 : return _ground_motion_data[bin][index].at(comp);
80 : }
81 :
82 : const std::vector<std::pair<Real, Real>> &
83 0 : HazardCurve::getSamples() const
84 : {
85 0 : return _hazard_sample;
86 : }
87 :
88 : std::vector<GroundMotionReader::Data>
89 13 : HazardCurve::execute(
90 : const std::string & name,
91 : const std::vector<Real> & reference,
92 : const MooseUtils::DelimitedFileReader & hazard_reader,
93 : const std::vector<std::unique_ptr<MooseUtils::DelimitedFileReader>> & ground_motion_readers,
94 : std::vector<std::pair<Real, Real>> & sample_data)
95 : {
96 : // Read hazard curve data
97 13 : const std::vector<std::vector<double>> & data = hazard_reader.getData();
98 : mooseAssert(!data.empty(), "The supplied hazard data is empty.");
99 :
100 : // Number of bins
101 13 : const unsigned int n_bins = reference.size();
102 :
103 : // Adjust the data for linear interpolation
104 13 : std::vector<Real> pga = data[1]; // x-axis: Peak ground acceleration
105 13 : std::vector<Real> mafe = MastodonUtils::log10(data[0]); // y-axis: fannual frequency of exceedence
106 13 : if (pga.front() > pga.back())
107 : {
108 0 : std::reverse(pga.begin(), pga.end());
109 0 : std::reverse(mafe.begin(), mafe.end());
110 : }
111 :
112 : // Build linear interpolation object
113 13 : LinearInterpolation linear_interp(pga, mafe);
114 :
115 : // Determine bin spacing
116 : std::vector<double>::const_iterator x_min = std::min_element(pga.begin(), pga.end());
117 : std::vector<double>::const_iterator x_max = std::max_element(pga.begin(), pga.end());
118 13 : double dx = (*x_max - *x_min) / n_bins;
119 :
120 : // Clear sample data
121 13 : sample_data.clear();
122 13 : sample_data.reserve(n_bins);
123 :
124 : // Populate ground motion data
125 13 : std::vector<GroundMotionReader::Data> ground_motion_data(n_bins);
126 13 : double x = (*x_min) + dx / 2.;
127 51 : for (unsigned int i = 0; i < n_bins; ++i)
128 : {
129 38 : Real scale = x / reference[i];
130 76 : ground_motion_data[i] = GroundMotionReader::getData(name, ground_motion_readers, scale);
131 :
132 38 : Real y = linear_interp.sample(x);
133 38 : sample_data.emplace_back(x, std::pow(10, y));
134 :
135 38 : x += dx;
136 : }
137 13 : return ground_motion_data;
138 13 : }
139 :
140 : unsigned int
141 9 : HazardCurve::count() const
142 : {
143 9 : check();
144 : unsigned int num = 0;
145 27 : for (std::size_t i = 0; i < bins(); ++i)
146 18 : num += count(i);
147 9 : return num;
148 : }
149 :
150 : std::size_t
151 348 : HazardCurve::count(const std::size_t & /*bin*/) const
152 : {
153 : // TODO: In the future it may be possible to have a different number of ground motions per
154 : // bin, this method will allow that to work without changing the API.
155 348 : check();
156 348 : return _ground_motion_reader.count();
157 : }
158 :
159 : std::size_t
160 144 : HazardCurve::bins() const
161 : {
162 144 : check();
163 144 : return _reference.size();
164 : }
165 :
166 : void
167 501 : HazardCurve::check() const
168 : {
169 501 : if (_ground_motion_data.empty())
170 0 : mooseError("The HazardCurve '",
171 : name(),
172 : "' does not contain data, please check the 'execute_on' settings to make sure the "
173 : "object was executed.");
174 501 : }
|