libMesh
rb_parameters.C
Go to the documentation of this file.
1 // rbOOmit: An implementation of the Certified Reduced Basis method.
2 // Copyright (C) 2009, 2010 David J. Knezevic
3 
4 // This file is part of rbOOmit.
5 
6 // rbOOmit is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 
11 // rbOOmit is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
15 
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20 // libmesh includes
21 #include "libmesh/int_range.h"
22 #include "libmesh/libmesh_common.h"
23 #include "libmesh/rb_parameters.h"
24 #include "libmesh/utility.h"
25 
26 // C++ includes
27 #include <algorithm>
28 #include <sstream>
29 
30 namespace libMesh
31 {
32 
34  _n_samples(1)
35 {
36 }
37 
38 RBParameters::RBParameters(const std::map<std::string, Real> & parameter_map) :
39  _n_samples(1)
40 {
41  // Backwards compatible support for constructing an RBParameters
42  // object from a map<string, Real>. We store a single entry in each
43  // vector in the map.
44  for (const auto & [key, val] : parameter_map)
45  _parameters[key] = {{val}};
46 }
47 
49 {
50  _n_samples = 1;
51  _parameters.clear();
52  _extra_parameters.clear();
53 }
54 
55 bool RBParameters::has_value(const std::string & param_name) const
56 {
57  return _parameters.count(param_name);
58 }
59 
60 bool RBParameters::has_extra_value(const std::string & param_name) const
61 {
62  return _extra_parameters.count(param_name);
63 }
64 
65 Real RBParameters::get_value(const std::string & param_name) const
66 {
67  // Simply return the [0]th entry of the vector if possible, otherwise error.
68  libmesh_error_msg_if(this->n_samples() != 1,
69  "Requesting value for parameter " << param_name << ", but parameter contains multiple samples.");
70  return this->get_sample_value(param_name, /*sample_idx=*/0);
71 }
72 
73 const RBParameter& RBParameters::get_vector_value(const std::string & param_name) const
74 {
75  // Simply return the [0]th entry of the vector if possible, otherwise error.
76  libmesh_error_msg_if(this->n_samples() != 1,
77  "Requesting value for parameter " << param_name << ", but parameter contains multiple sample.");
78  return this->get_sample_vector_value(param_name, /*sample_idx=*/0);
79 }
80 
81 Real RBParameters::get_value(const std::string & param_name, const Real & default_val) const
82 {
83  // Simply return the [0]th entry of the vector if possible, otherwise error.
84  libmesh_error_msg_if(this->n_samples() != 1,
85  "Requesting value for parameter " << param_name << ", but parameter contains multiple samples.");
86  return this->get_sample_value(param_name, /*sample_idx=*/0, default_val);
87 }
88 
89 const RBParameter & RBParameters::get_vector_value(const std::string & param_name, const RBParameter & default_val) const
90 {
91  // Simply return the [0]th entry of the vector if possible, otherwise error.
92  libmesh_error_msg_if(this->n_samples() != 1,
93  "Requesting value for parameter " << param_name << ", but parameter contains multiple samples.");
94  return this->get_sample_vector_value(param_name, /*sample_idx=*/0, default_val);
95 }
96 
97 Real RBParameters::get_sample_value(const std::string & param_name, std::size_t sample_idx) const
98 {
99  const auto & sample_vec = libmesh_map_find(_parameters, param_name);
100  libmesh_error_msg_if(sample_idx >= sample_vec.size(), "Error getting value for parameter " << param_name);
101  libmesh_error_msg_if(sample_vec[sample_idx].size() != 1,
102  "Requesting Real value for parameter " << param_name << ", but parameter contains multiple values.");
103  return sample_vec[sample_idx][0];
104 }
105 
106 const RBParameter & RBParameters::get_sample_vector_value(const std::string & param_name, std::size_t sample_idx) const
107 {
108  const auto & sample_vec = libmesh_map_find(_parameters, param_name);
109  libmesh_error_msg_if(sample_idx >= sample_vec.size(), "Error getting value for parameter " << param_name);
110  return sample_vec[sample_idx];
111 }
112 
113 Real RBParameters::get_sample_value(const std::string & param_name, std::size_t sample_idx, const Real & default_val) const
114 {
115  auto it = _parameters.find(param_name);
116  if (it == _parameters.end() || sample_idx >= it->second.size())
117  return default_val;
118  libmesh_error_msg_if(it->second[sample_idx].size() != 1,
119  "Requesting Real value for parameter " << param_name << ", but parameter contains multiple values.");
120  return it->second[sample_idx][0];
121 }
122 
123 const RBParameter & RBParameters::get_sample_vector_value(const std::string & param_name, std::size_t sample_idx, const RBParameter & default_val) const
124 {
125  auto it = _parameters.find(param_name);
126  if (it == _parameters.end() || sample_idx >= it->second.size())
127  return default_val;
128  return it->second[sample_idx];
129 }
130 
131 void RBParameters::set_value(const std::string & param_name, Real value)
132 {
133  // This version of set_value() does not take an index and is provided
134  // for backwards compatibility. It creates a vector entry for the specified
135  // param_name, overwriting any value(s) that were present.
136  _parameters[param_name] = {{value}};
137 }
138 
139 void RBParameters::set_value(const std::string & param_name, const RBParameter & value)
140 {
141  // This version of set_value() does not take an index and is provided
142  // for backwards compatibility. It creates a vector entry for the specified
143  // param_name, overwriting any value(s) that were present.
144  _parameters[param_name] = {value};
145 }
146 
147 void
148 RBParameters::set_value_helper(std::map<std::string, std::vector<RBParameter>> & map,
149  const std::string & param_name,
150  const std::size_t index,
152 {
153  // Get reference to vector of values for this parameter, creating it
154  // if it does not already exist.
155  auto & sample_vec = map[param_name];
156 
157  // If vec is already big enough, just set the value
158  if (sample_vec.size() > index)
159  sample_vec[index] = std::move(value);
160 
161  // Otherwise push_back() if the vec is just barely not big enough
162  else if (sample_vec.size() == index)
163  sample_vec.emplace_back(std::move(value));
164 
165  // Otherwise, allocate more space (padding with 0s) if vector is not
166  // big enough to fit the user's requested index.
167  else
168  {
169  RBParameter zero_parameter(value.size(), 0.0);
170  sample_vec.resize(index+1, zero_parameter);
171  sample_vec[index] = std::move(value);
172  }
173 }
174 
175 void RBParameters::set_value(const std::string & param_name, std::size_t index, Real value)
176 {
177  this->set_value_helper(_parameters, param_name, index, {value});
178 }
179 
180 void RBParameters::set_value(const std::string & param_name, std::size_t index, const RBParameter & value)
181 {
182  this->set_value_helper(_parameters, param_name, index, value);
183 }
184 
185 void RBParameters::set_extra_value(const std::string & param_name, std::size_t index, Real value)
186 {
187  this->set_value_helper(_extra_parameters, param_name, index, {value});
188 }
189 
190 void RBParameters::set_extra_value(const std::string & param_name, std::size_t index, const RBParameter & value)
191 {
192  this->set_value_helper(_extra_parameters, param_name, index, value);
193 }
194 
195 void RBParameters::push_back_value(const std::string & param_name, Real value)
196 {
197  // Get reference to vector of values for this parameter, creating it
198  // if it does not already exist, and push back the specified value.
199  _parameters[param_name].push_back({value});
200 }
201 
202 void RBParameters::push_back_value(const std::string & param_name, const RBParameter & value)
203 {
204  // Get reference to vector of values for this parameter, creating it
205  // if it does not already exist, and push back the specified value.
206  _parameters[param_name].push_back(value);
207 }
208 
209 void RBParameters::push_back_extra_value(const std::string & param_name, Real value)
210 {
211  // Get reference to vector of values for this extra parameter, creating it
212  // if it does not already exist, and push back the specified value.
213  _extra_parameters[param_name].push_back({value});
214 }
215 
216 void RBParameters::push_back_extra_value(const std::string & param_name, const RBParameter & value)
217 {
218  // Get reference to vector of values for this extra parameter, creating it
219  // if it does not already exist, and push back the specified value.
220  _extra_parameters[param_name].push_back(value);
221 }
222 
223 Real RBParameters::get_extra_value(const std::string & param_name) const
224 {
225  // Same as get_value(param_name) but for the map of extra parameters
226  const auto & sample_vec = libmesh_map_find(_extra_parameters, param_name);
227  libmesh_error_msg_if(sample_vec.size() != 1,
228  "Requesting value for extra parameter " << param_name << ", but parameter contains multiple samples.");
229  libmesh_error_msg_if(sample_vec[0].size() != 1,
230  "Requesting Real value for extra parameter " << param_name << ", but parameter contains multiple values.");
231  return sample_vec[0][0];
232 }
233 
234 const RBParameter & RBParameters::get_extra_vector_value(const std::string & param_name) const
235 {
236  // Same as get_value(param_name) but for the map of extra parameters
237  const auto & sample_vec = libmesh_map_find(_extra_parameters, param_name);
238  libmesh_error_msg_if(sample_vec.size() == 0, "Error getting value for extra parameter " << param_name);
239  return sample_vec[0];
240 }
241 
242 Real RBParameters::get_extra_value(const std::string & param_name, const Real & default_val) const
243 {
244  // same as get_value(param_name, default_val) but for the map of extra parameters
245  auto it = _extra_parameters.find(param_name);
246  if (it == _extra_parameters.end())
247  return default_val;
248 
249  libmesh_error_msg_if(it->second.size() != 1,
250  "Requesting value for extra parameter " << param_name << ", but parameter contains multiple samples.");
251  libmesh_error_msg_if(it->second[0].size() != 1,
252  "Requesting Real value for extra parameter " << param_name << ", but parameter contains multiple values.");
253  return it->second[0][0];
254 }
255 
256 Real RBParameters::get_extra_sample_value(const std::string & param_name, std::size_t sample_idx) const
257 {
258  const auto & sample_vec = libmesh_map_find(_extra_parameters, param_name);
259  libmesh_error_msg_if(sample_idx >= sample_vec.size(), "Error getting value for extra parameter " << param_name);
260  libmesh_error_msg_if(sample_vec[sample_idx].size() != 1,
261  "Requesting Real value for extra parameter " << param_name << ", but parameter contains multiple values.");
262  return sample_vec[sample_idx][0];
263 }
264 
265 const RBParameter & RBParameters::get_extra_sample_vector_value(const std::string & param_name, std::size_t sample_idx) const
266 {
267  const auto & sample_vec = libmesh_map_find(_extra_parameters, param_name);
268  libmesh_error_msg_if(sample_idx >= sample_vec.size(), "Error getting value for extra parameter " << param_name);
269  return sample_vec[sample_idx];
270 }
271 
272 Real RBParameters::get_extra_sample_value(const std::string & param_name, std::size_t sample_idx, const Real & default_val) const
273 {
274  // same as get_sample_value(param_name, index, default_val) but for the map of extra parameters
275  auto it = _extra_parameters.find(param_name);
276  if (it==_extra_parameters.end() || sample_idx >= it->second.size())
277  return default_val;
278  libmesh_error_msg_if(it->second[sample_idx].size() != 1,
279  "Requesting Real value for extra parameter " << param_name << ", but parameter contains multiple values.");
280  return it->second[sample_idx][0];
281 }
282 
284  const std::string &param_name,
285  std::size_t sample_idx,
286  const RBParameter &default_val) const
287 {
288  auto it = _extra_parameters.find(param_name);
289  if (it == _extra_parameters.end() || sample_idx >= it->second.size())
290  return default_val;
291  return it->second[sample_idx];
292 }
293 
294 void RBParameters::set_extra_value(const std::string & param_name, Real value)
295 {
296  // This version of set_extra_value() does not take an index and is provided
297  // for backwards compatibility. It creates a vector entry for the specified
298  // param_name, overwriting any value(s) that were present.
299  _extra_parameters[param_name] = {{value}};
300 }
301 
302 void RBParameters::set_extra_value(const std::string & param_name, const RBParameter & value)
303 {
304  // This version of set_extra_value() does not take an index and is provided
305  // for backwards compatibility. It creates a vector entry for the specified
306  // param_name, overwriting any value(s) that were present.
307  _extra_parameters[param_name] = {value};
308 }
309 
310 unsigned int RBParameters::n_parameters() const
311 {
312  return cast_int<unsigned int>(_parameters.size());
313 }
314 
315 void RBParameters::set_n_samples(unsigned int n_samples)
316 {
318 }
319 
320 unsigned int RBParameters::n_samples() const
321 {
322  // Quick return if there are no parameters
323  if (_parameters.empty())
324  return _n_samples;
325 
326  // If _parameters is not empty, we can check the number of samples in the first param
327  auto size_first = _parameters.begin()->second.size();
328 
329 #ifdef DEBUG
330  // In debug mode, verify that all parameters have the same number of samples
331  for (const auto & pr : _parameters)
332  libmesh_assert_msg(pr.second.size() == size_first, "All parameters must have the same number of samples.");
333 #endif
334 
335  // If we made it here in DEBUG mode, then all parameters were
336  // verified to have the same number of samples.
337  return size_first;
338 }
339 
340 std::set<std::string> RBParameters::get_parameter_names() const
341 {
342  std::set<std::string> param_names;
343  for (const auto & pr : _parameters)
344  param_names.insert(pr.first);
345  return param_names;
346 }
347 
348 std::set<std::string> RBParameters::get_extra_parameter_names() const
349 {
350  std::set<std::string> param_names;
351  for (const auto & pr : _extra_parameters)
352  param_names.insert(pr.first);
353  return param_names;
354 }
355 
356 void RBParameters::erase_parameter(const std::string & param_name)
357 {
358  _parameters.erase(param_name);
359 }
360 
361 void RBParameters::erase_extra_parameter(const std::string & param_name)
362 {
363  _extra_parameters.erase(param_name);
364 }
365 
366 std::map<std::string,std::vector<RBParameter>>::const_iterator RBParameters::begin() const
367 {
368  return _parameters.cbegin();
369 }
370 
371 std::map<std::string,std::vector<RBParameter>>::const_iterator RBParameters::end() const
372 {
373  return _parameters.cend();
374 }
375 
376 std::map<std::string,std::vector<RBParameter>>::const_iterator RBParameters::extra_begin() const
377 {
378  return _extra_parameters.cbegin();
379 }
380 
381 std::map<std::string,std::vector<RBParameter>>::const_iterator RBParameters::extra_end() const
382 {
383  return _extra_parameters.cend();
384 }
385 
387 {
388  return {_parameters.cbegin(), 0, 0};
389 }
390 
392 {
393  // Note: the index 0 is irrelevant here since _parameters.end() does
394  // not refer to a valid vector entry in the map.
395  return {_parameters.cend(), 0, 0};
396 }
397 
399 {
400  return {_extra_parameters.cbegin(), 0, 0};
401 }
402 
404 {
405  // Note: the index 0 is irrelevant here since _parameters.end() does
406  // not refer to a valid vector entry in the map.
407  return {_extra_parameters.cend(), 0, 0};
408 }
409 
410 bool RBParameters::operator==(const RBParameters & rhs) const
411 {
412  return (this->_parameters == rhs._parameters &&
413  this->_extra_parameters == rhs._extra_parameters);
414 }
415 
416 bool RBParameters::operator!=(const RBParameters & rhs) const
417 {
418  return !(*this == rhs);
419 }
420 
422 {
423  libmesh_error_msg_if(this->n_samples() != rhs.n_samples(),
424  "Can only append RBParameters objects with matching numbers of samples.");
425 
426  // Overwrite or add each (key, vec) pair in rhs to *this.
427  for (const auto & [key, vec] : rhs._parameters)
428  _parameters[key] = vec;
429  for (const auto & [key, vec] : rhs._extra_parameters)
430  _extra_parameters[key] = vec;
431 
432  return *this;
433 }
434 
435 std::string RBParameters::get_string(unsigned precision, int max_values) const
436 {
437  std::stringstream param_stringstream;
438  param_stringstream << std::setprecision(static_cast<int>(precision)) << std::scientific;
439 
440  for (const auto & [param_name, sample_vec] : _parameters)
441  {
442  // Write the param name, followed by a comma-separated list of the sample/vector values.
443  param_stringstream << param_name << ": ";
444  std::string separator = "";
445  for (const auto & value_vec : sample_vec)
446  {
447  param_stringstream << separator;
448  if (value_vec.size() == 1)
449  param_stringstream << value_vec[0];
450  else
451  {
452  param_stringstream << "[ ";
453  for (const auto val_idx : index_range(value_vec))
454  {
455  if (max_values < 0 || val_idx < static_cast<unsigned>(max_values))
456  param_stringstream << value_vec[val_idx] << " ";
457  else
458  {
459  param_stringstream << "... ";
460  break;
461  }
462  }
463  param_stringstream << "]";
464  }
465  separator = ", ";
466  }
467  param_stringstream << std::endl;
468  }
469 
470  return param_stringstream.str();
471 }
472 
473 void RBParameters::print(unsigned precision, int max_values) const
474 {
475  libMesh::out << get_string(precision, max_values);
476 }
477 
478 }
Real get_value(const std::string &param_name) const
Get the value of the specified parameter, throw an error if it does not exist.
Definition: rb_parameters.C:65
bool operator!=(const RBParameters &rhs) const
Real get_extra_sample_value(const std::string &param_name, std::size_t sample_idx) const
Get the value of the specified "extra" parameter at the specified sample index, throwing an error if ...
bool has_value(const std::string &param_name) const
Definition: rb_parameters.C:55
std::set< std::string > get_parameter_names() const
void erase_extra_parameter(const std::string &param_name)
Erase param_name from _extra_parameters.
const RBParameter & get_extra_sample_vector_value(const std::string &param_name, std::size_t sample_idx) const
const_iterator begin_serialized() const
Get const_iterator access to the parameters stored in this RBParameters object.
std::map< std::string, std::vector< RBParameter > >::const_iterator extra_begin() const
std::map< std::string, std::vector< RBParameter > >::const_iterator end() const
std::map< std::string, std::vector< RBParameter > > _parameters
Actual parameter values (in std::vector<RBParameter> form) across a vector of samples.
unsigned int _n_samples
The number of samples represented by this RBParameters object, in the case where there are no paramet...
bool operator==(const RBParameters &rhs) const
Two RBParameters are equal if they have the same _parameters map.
const RBParameter & get_vector_value(const std::string &param_name) const
Definition: rb_parameters.C:73
std::map< std::string, std::vector< RBParameter > > _extra_parameters
Extra parameter vectors not used for RB training.
The libMesh namespace provides an interface to certain functionality in the library.
RBParameters & operator+=(const RBParameters &rhs)
Append "rhs" to "*this".
void print(unsigned precision=6, int max_values=5) const
Print the parameters.
const RBParameter & get_extra_vector_value(const std::string &param_name) const
RBParameters()
Constructor.
Definition: rb_parameters.C:33
std::map< std::string, std::vector< RBParameter > >::const_iterator extra_end() const
unsigned int n_parameters() const
Get the number of parameters that have been added.
std::set< std::string > get_extra_parameter_names() const
Define a constant iterator for iterating over the map of parameters.
Definition: rb_parameters.h:97
const RBParameter & get_sample_vector_value(const std::string &param_name, std::size_t sample_idx) const
std::vector< Real > RBParameter
Typedef for an individual RB parameter.
Definition: rb_parameters.h:39
std::string get_string(unsigned precision=6, int max_values=5) const
Get a string that specifies the contents of this RBParameters object.
This class is part of the rbOOmit framework.
Definition: rb_parameters.h:52
const_iterator end_serialized_extra() const
bool has_extra_value(const std::string &param_name) const
Definition: rb_parameters.C:60
void set_value_helper(std::map< std::string, std::vector< RBParameter >> &map, const std::string &param_name, const std::size_t index, RBParameter value)
Helper function for the 3-parameter versions of set_value() and set_extra_value().
unsigned int n_samples() const
Returns the number of samples stored for all parameters.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void set_extra_value(const std::string &param_name, Real value)
Set the value of the specified extra parameter.
Real get_sample_value(const std::string &param_name, std::size_t sample_idx) const
Get the value of the specified parameter at the specified sample, throwing an error if it does not ex...
Definition: rb_parameters.C:97
const_iterator begin_serialized_extra() const
Get const_iterator access to the extra parameters stored in this RBParameters object.
void push_back_extra_value(const std::string &param_name, Real value)
Same as push_back_value(), but for "extra" parameters.
void set_value(const std::string &param_name, Real value)
Set the value of the specified parameter.
OStreamProxy out
void clear()
Clear this object.
Definition: rb_parameters.C:48
static const bool value
Definition: xdr_io.C:54
const_iterator end_serialized() const
void erase_parameter(const std::string &param_name)
Erase param_name from _parameters.
Real get_extra_value(const std::string &param_name) const
Get the value of the specified extra parameter, throwing an error if it does not exist.
void push_back_value(const std::string &param_name, Real value)
Similar to set_value(name, index, value) but instead of specifying a particular index, just appends one more.
void set_n_samples(unsigned int n_samples)
Set the number of samples this RBParameters object is intended to represent, in the case that there a...
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
std::map< std::string, std::vector< RBParameter > >::const_iterator begin() const
Return const_iterators to the internal parameter map, as a convenient way to access the parameter nam...