libMesh
rb_parameters_test.C
Go to the documentation of this file.
1 // libMesh includes
2 #include "libmesh/libmesh_exceptions.h"
3 #include "libmesh/rb_parameters.h"
4 #include "libmesh/rb_parametrized.h"
5 #include "libmesh/simple_range.h"
6 #include "libmesh/int_range.h"
7 
8 // CPPUnit includes
9 #include "libmesh_cppunit.h"
10 #include <cppunit/TestAssert.h>
11 
12 using namespace libMesh;
13 
14 class RBParametersTest : public CppUnit::TestCase
15 {
16 public:
17  LIBMESH_CPPUNIT_TEST_SUITE ( RBParametersTest );
18  CPPUNIT_TEST( testScalar );
19  CPPUNIT_TEST( testOldConstructor );
20  CPPUNIT_TEST( testIterators );
21  CPPUNIT_TEST( testIteratorsWithSamples );
22  CPPUNIT_TEST( testAppend );
23  CPPUNIT_TEST( testNSamples );
24  CPPUNIT_TEST( testMultiValued );
25  CPPUNIT_TEST( testRBParametrized );
26  CPPUNIT_TEST_SUITE_END();
27 
28 public:
29 
30  // virtual void setUp()
31  // {}
32 
33  // virtual void tearDown()
34  // {}
35 
36  void testScalar()
37  {
38  LOG_UNIT_TEST;
39 
40  // Test scalar-valued interfaces
41  RBParameters params;
42  params.set_value("a", 1.);
43  params.set_value("b", 2.);
44  params.set_value("c", 3.);
45 
46  // Expected result
47  // a: 1.000000e+00
48  // b: 2.000000e+00
49  // c: 3.000000e+00
50  CPPUNIT_ASSERT(params.has_value("a"));
51  CPPUNIT_ASSERT(params.has_value("b"));
52  CPPUNIT_ASSERT(params.has_value("c"));
53  CPPUNIT_ASSERT_EQUAL(params.get_value("a"), Real(1));
54  CPPUNIT_ASSERT_EQUAL(params.get_value("b"), Real(2));
55  CPPUNIT_ASSERT_EQUAL(params.get_value("c"), Real(3));
56  }
57 
59  {
60  LOG_UNIT_TEST;
61 
62  // Test constructing an RBParameters object from a std::map
63  std::map<std::string, Real> in = {{"a", 1.}, {"b", 2.}, {"c", 3.}};
64  RBParameters params(in);
65 
66  // Expected result
67  // a: 1.000000e+00
68  // b: 2.000000e+00
69  // c: 3.000000e+00
70  CPPUNIT_ASSERT(params.has_value("a"));
71  CPPUNIT_ASSERT(params.has_value("b"));
72  CPPUNIT_ASSERT(params.has_value("c"));
73  CPPUNIT_ASSERT_EQUAL(params.get_value("a"), Real(1));
74  CPPUNIT_ASSERT_EQUAL(params.get_value("b"), Real(2));
75  CPPUNIT_ASSERT_EQUAL(params.get_value("c"), Real(3));
76 
77  // Test that RBParameters objects constructed with the old
78  // constructor have the correct number of samples.
79  CPPUNIT_ASSERT_EQUAL(params.n_samples(), 1u);
80  }
81 
83  {
84  LOG_UNIT_TEST;
85 
86  // Test creating a std::map using RBParameters iterators
87  RBParameters params;
88  params.set_value("a", 1.);
89  params.set_value("b", 2.);
90  params.set_value("c", 3.);
91 
92  std::map<std::string, Real> m;
93  m.insert(params.begin_serialized(), params.end_serialized());
94 
95  // Expected result
96  // a: 1.000000e+00
97  // b: 2.000000e+00
98  // c: 3.000000e+00
99  CPPUNIT_ASSERT(m.count("a"));
100  CPPUNIT_ASSERT(m.count("b"));
101  CPPUNIT_ASSERT(m.count("c"));
102  CPPUNIT_ASSERT_EQUAL(m["a"], Real(1));
103  CPPUNIT_ASSERT_EQUAL(m["b"], Real(2));
104  CPPUNIT_ASSERT_EQUAL(m["c"], Real(3));
105  }
106 
108  {
109  LOG_UNIT_TEST;
110 
111  RBParameters params;
112  params.set_value("a", 2, 1.); // "a" : [0,0,1]
113  params.set_value("b", 2, 2.); // "b" : [0,0,2]
114  params.set_value("c", 2, 3.); // "c" : [0,0,3]
115 
116  // The iterators work on a serialized version of the map, meaning we see an
117  // iterator for each sample of each parameter, e.g. {a,0}, {a,0}, {a,1}.
118  // map.insert(begin(),end()) says "it is unspecified which element is inserted" in this case,
119  // so instead we manually iterate and overwrite with the value from the latest sample.
120  std::map<std::string, Real> m;
121  // m.insert(params.begin(), params.end()); // unspecified behavior
122  for (const auto & [key,val] : as_range(params.begin_serialized(), params.end_serialized()))
123  m[key] = val;
124 
125  // Expected result
126  // a: 1.000000e+00
127  // b: 2.000000e+00
128  // c: 3.000000e+00
129  CPPUNIT_ASSERT(m.count("a"));
130  CPPUNIT_ASSERT(m.count("b"));
131  CPPUNIT_ASSERT(m.count("c"));
132  CPPUNIT_ASSERT_EQUAL(m["a"], Real(1));
133  CPPUNIT_ASSERT_EQUAL(m["b"], Real(2));
134  CPPUNIT_ASSERT_EQUAL(m["c"], Real(3));
135  }
136 
137  void testAppend()
138  {
139  LOG_UNIT_TEST;
140 
141  // Create first multi-sample RBParameters object
142  RBParameters params1;
143  for (int i=0; i<3; ++i)
144  params1.push_back_value("a", Real(i));
145 
146  // Create second multi-sample RBParameters object
147  // (must have same number of samples)
148  RBParameters params2;
149  for (int i=0; i<3; ++i)
150  {
151  params2.push_back_value("b", Real(i+3));
152  params2.push_back_extra_value("c", Real(i*i));
153  }
154 
155  // Append second onto first
156  params1 += params2;
157 
158  // Print result
159  // params1.print();
160 
161  // Check that the desired appending happened
162  CPPUNIT_ASSERT(params1.has_value("b"));
163  CPPUNIT_ASSERT(params1.has_extra_value("c"));
164  for (int i=0; i<3; ++i)
165  {
166  CPPUNIT_ASSERT_EQUAL(params1.get_sample_value("b", i), static_cast<Real>(i+3));
167  CPPUNIT_ASSERT_EQUAL(params1.get_extra_sample_value("c", i), static_cast<Real>(i*i));
168  }
169  }
170 
172  {
173  LOG_UNIT_TEST;
174 
175  // A default-constructed RBparameters object has 1 sample by definition
176  RBParameters params;
177  CPPUNIT_ASSERT_EQUAL(params.n_samples(), static_cast<unsigned int>(1));
178 
179  // Set the number of samples to use in the no-parameters case
180  params.set_n_samples(10);
181  CPPUNIT_ASSERT_EQUAL(params.n_samples(), static_cast<unsigned int>(10));
182 
183  // Define multiple samples for a single parameter. Now we no longer
184  // use the set_n_samples() value, since we have actual samples.
185  params.push_back_value("a", 0.);
186  params.push_back_value("a", 1.);
187  params.push_back_value("a", 2.);
188  params.push_back_value("a", 3.);
189  CPPUNIT_ASSERT_EQUAL(params.n_samples(), static_cast<unsigned int>(4));
190  CPPUNIT_ASSERT_EQUAL(params.get_sample_value("a", 2), static_cast<Real>(2.));
191 
192  // Test set_value() with an index.
193  params.set_value("b", 3, 0.);
194  params.set_value("b", 2, 1.);
195  params.set_value("b", 1, 2.);
196  params.set_value("b", 0, 3.);
197  CPPUNIT_ASSERT_EQUAL(params.n_samples(), static_cast<unsigned int>(4));
198  CPPUNIT_ASSERT_EQUAL(params.n_parameters(), static_cast<unsigned int>(2));
199  CPPUNIT_ASSERT_EQUAL(params.get_sample_value("a", 2), static_cast<Real>(2.));
200  CPPUNIT_ASSERT_EQUAL(params.get_sample_value("b", 2), static_cast<Real>(1.));
201 
202  // Test the default getters.
203  CPPUNIT_ASSERT_EQUAL(params.get_sample_value("a", 5, 100.), static_cast<Real>(100.));
204  CPPUNIT_ASSERT_EQUAL(params.get_sample_value("b", 5, 200.), static_cast<Real>(200.));
205  CPPUNIT_ASSERT_EQUAL(params.get_sample_value("c", 5, 300.), static_cast<Real>(300.));
206 
207  // Test some errors.
208 #ifdef LIBMESH_ENABLE_EXCEPTIONS
209  CPPUNIT_ASSERT_THROW(params.get_sample_value("b", 5), libMesh::LogicError); // sample_idx 5 does not exist.
210  CPPUNIT_ASSERT_THROW(params.get_sample_value("c", 0), libMesh::LogicError); // parameter "c" does not exist.
211  CPPUNIT_ASSERT_THROW(params.get_value("a"), libMesh::LogicError); // a has multiple samples.
212  CPPUNIT_ASSERT_THROW(params.get_value("a", 1.0), libMesh::LogicError); // a has multiple samples.
213 #endif
214  }
215 
217  {
218  LOG_UNIT_TEST;
219 
220  RBParameters params;
221  std::vector<Real> test_vec1 = {2.1, 2.2, 2.3};
222  params.set_value("a", 0, {1.1, 1.2, 1.3});
223  params.set_value("a", 1, test_vec1);
224  params.set_value("a", 2, {3.1, 3.2, 3.3});
225  params.set_value("b", 2, {3.1, 3.2, 3.3});
226 
227 #ifdef LIBMESH_ENABLE_EXCEPTIONS
228  // Test some errors.
229  CPPUNIT_ASSERT_THROW(params.get_sample_value("b", 0), libMesh::LogicError); // single-value requested, but multi-valued.
230  CPPUNIT_ASSERT_THROW(params.get_sample_value("b", 5), libMesh::LogicError); // sample_idx 5 does not exist.
231  CPPUNIT_ASSERT_THROW(params.get_sample_value("c", 0), libMesh::LogicError); // parameter "c" does not exist.
232  CPPUNIT_ASSERT_THROW(params.get_value("a"), libMesh::LogicError); // a has multiple samples.
233  CPPUNIT_ASSERT_THROW(params.get_value("a", 1.0), libMesh::LogicError); // a has multiple samples.
234  CPPUNIT_ASSERT_THROW(params.get_sample_vector_value("a", 3), libMesh::LogicError); // sample_idx 3 does not exist.
235  CPPUNIT_ASSERT_THROW(params.get_sample_vector_value("c", 0), libMesh::LogicError); // parameter "c" does not exist.
236 #endif
237 
238  const auto & vector_value_1 = params.get_sample_vector_value("a", 1);
239  for (const auto index : index_range(vector_value_1))
240  CPPUNIT_ASSERT_EQUAL(vector_value_1[index], test_vec1[index]);
241  const auto & vector_value_2 = params.get_sample_vector_value("a", 3, test_vec1);
242  for (const auto index : index_range(vector_value_2))
243  CPPUNIT_ASSERT_EQUAL(vector_value_2[index], test_vec1[index]);
244 
245  std::vector<Real> test_vec2 = {5.1, 5.2, 5.3};
246  params.push_back_value("a", test_vec2);
247  params.push_back_value("b", test_vec2);
248  const auto & vector_value_3 = params.get_sample_vector_value("a", 3);
249  for (const auto index : index_range(vector_value_3))
250  CPPUNIT_ASSERT_EQUAL(vector_value_3[index], test_vec2[index]);
251  }
252 
254  {
255  LOG_UNIT_TEST;
256 
257  RBParameters mu_min, mu_max;
258 
259  mu_min.set_value("a", -10.);
260  mu_max.set_value("a", -11.);
261 
262  RBParametrized rb_parametrized;
263  // rb_parametrized.verbose_mode = true; // Enable for more printed details.
264 
265 #ifdef LIBMESH_ENABLE_EXCEPTIONS
266  // Throw an error due to invalid min/max.
267  CPPUNIT_ASSERT_THROW(rb_parametrized.initialize_parameters(mu_min, mu_max, {}), libMesh::LogicError);
268 #endif
269 
270  // Define an invalid max RBParameter with multiple steps.
271  mu_max.set_value("a", 2, -40.);
272 
273 #ifdef LIBMESH_ENABLE_EXCEPTIONS
274  // Throw an error due to invalid max value.
275  CPPUNIT_ASSERT_THROW(rb_parametrized.initialize_parameters(mu_min,mu_max, {}), libMesh::LogicError);
276 #endif
277 
278  // Set the max value correctly and initialize the RBParametrized object
279  mu_max = RBParameters();
280  mu_max.set_value("a", 10.);
281  rb_parametrized.initialize_parameters(mu_min, mu_max, {});
282 
283  RBParameters params;
284 
285  // Value == min --> OK.
286  params.set_value("a", 0, 0.);
287  params.set_value("a", 1, -10.);
288  CPPUNIT_ASSERT(rb_parametrized.set_parameters(params));
289 
290  // Value == max --> OK.
291  params.set_value("a", 2, 10.);
292  CPPUNIT_ASSERT(rb_parametrized.set_parameters(params));
293 
294  // Value < min --> not OK.
295  params.set_value("a", 3, -40.);
296  CPPUNIT_ASSERT(!rb_parametrized.set_parameters(params));
297 
298 #ifdef LIBMESH_ENABLE_EXCEPTIONS
299  // Throw an error due to different number of parameters.
300  mu_max.set_value("b", 3, 40.);
301  CPPUNIT_ASSERT_THROW(rb_parametrized.initialize_parameters(mu_min, mu_max, {}), libMesh::LogicError);
302 #endif
303  }
304 
305 };
306 
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
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
CPPUNIT_TEST_SUITE_REGISTRATION(RBParametersTest)
const_iterator begin_serialized() const
Get const_iterator access to the parameters stored in this RBParameters object.
The libMesh namespace provides an interface to certain functionality in the library.
unsigned int n_parameters() const
Get the number of parameters that have been added.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
const RBParameter & get_sample_vector_value(const std::string &param_name, std::size_t sample_idx) const
This class is part of the rbOOmit framework.
Definition: rb_parameters.h:52
bool has_extra_value(const std::string &param_name) const
Definition: rb_parameters.C:60
bool set_parameters(const RBParameters &params)
Set the current parameters to params The parameters are checked for validity; an error is thrown if t...
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
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
void push_back_extra_value(const std::string &param_name, Real value)
Same as push_back_value(), but for "extra" parameters.
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
void set_value(const std::string &param_name, Real value)
Set the value of the specified parameter.
This class is part of the rbOOmit framework.
const_iterator end_serialized() const
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 initialize_parameters(const RBParameters &mu_min_in, const RBParameters &mu_max_in, const std::map< std::string, std::vector< Real >> &discrete_parameter_values)
Initialize the parameter ranges and set current_parameters.
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