libMesh
Loading...
Searching...
No Matches
rb_parametrized.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/simple_range.h"
23#include "libmesh/xdr_cxx.h"
24
25// rbOOmit includes
26#include "libmesh/rb_parametrized.h"
27
28// C++ includes
29#include <sstream>
30#include <fstream>
31#include <algorithm> // std::min_element
32
33namespace libMesh
34{
35
37 :
38 verbose_mode(false),
39 parameters_initialized(false)
40{
41}
42
44
52
54 const RBParameters & mu_max_in,
55 const std::map<std::string, std::vector<Real>> & discrete_parameter_values)
56{
57 // Check that the min/max vectors have the same size.
58 libmesh_error_msg_if(mu_min_in.n_parameters() != mu_max_in.n_parameters(),
59 "Error: Invalid mu_min/mu_max in initialize_parameters(), different number of parameters.");
60 libmesh_error_msg_if(mu_min_in.n_samples() != 1 ||
61 mu_max_in.n_samples() != 1,
62 "Error: Invalid mu_min/mu_max in initialize_parameters(), only 1 sample supported.");
63
64 // Ensure all the values are valid for min and max.
65 auto pr_min = mu_min_in.begin_serialized();
66 auto pr_max = mu_max_in.begin_serialized();
67 for (; pr_min != mu_min_in.end_serialized(); ++pr_min, ++pr_max)
68 libmesh_error_msg_if((*pr_min).second > (*pr_max).second,
69 "Error: Invalid mu_min/mu_max in RBParameters constructor.");
70
71 parameters_min = mu_min_in;
72 parameters_max = mu_max_in;
73
74 // Add in min/max values due to the discrete parameters
75 for (const auto & [name, vals] : discrete_parameter_values)
76 {
77 libmesh_error_msg_if(vals.empty(), "Error: List of discrete parameters for " << name << " is empty.");
78
79 Real min_val = *std::min_element(vals.begin(), vals.end());
80 Real max_val = *std::max_element(vals.begin(), vals.end());
81
82 libmesh_assert_less_equal(min_val, max_val);
83
84 parameters_min.set_value(name, min_val);
85 parameters_max.set_value(name, max_val);
86 }
87
88 _discrete_parameter_values = discrete_parameter_values;
89
91
92 // Initialize the current parameters to parameters_min
94}
95
97{
99 rb_parametrized.get_parameters_max(),
100 rb_parametrized.get_discrete_parameter_values());
101}
102
104{
105 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_n_params");
106
107 libmesh_assert_equal_to ( parameters_min.n_parameters(), parameters_max.n_parameters() );
108
110}
111
113{
114 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_n_continuous_params");
115
117
118 return static_cast<unsigned int>(get_n_params() - get_n_discrete_params());
119}
120
122{
123 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_n_discrete_params");
124
125 return cast_int<unsigned int>
127}
128
130{
131 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::set_parameters");
132
133 // Terminate if params has the wrong number of parameters or samples.
134 // If the parameters are outside the min/max range, return false.
135 const bool valid_params = check_if_valid_params(params);
136
137 // Make a copy of params (default assignment operator just does memberwise copy, which is sufficient here)
138 this->parameters = params;
139
140 return valid_params;
141}
142
144{
145 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_parameters");
146
147 return parameters;
148}
149
151{
152 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_parameters_min");
153
154 return parameters_min;
155}
156
158{
159 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_parameters_max");
160
161 return parameters_max;
162}
163
164Real RBParametrized::get_parameter_min(const std::string & param_name) const
165{
166 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_parameter_min");
167
168 return parameters_min.get_value(param_name);
169}
170
171Real RBParametrized::get_parameter_max(const std::string & param_name) const
172{
173 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_parameter_max");
174
175 return parameters_max.get_value(param_name);
176}
177
179{
180 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::print_current_parameters");
181
183}
184
185void RBParametrized::write_parameter_data_to_files(const std::string & continuous_param_file_name,
186 const std::string & discrete_param_file_name,
187 const bool write_binary_data)
188{
189 write_parameter_ranges_to_file(continuous_param_file_name, write_binary_data);
190 write_discrete_parameter_values_to_file(discrete_param_file_name, write_binary_data);
191}
192
193void RBParametrized::write_parameter_ranges_to_file(const std::string & file_name,
194 const bool write_binary_data)
195{
196 // The writing mode: ENCODE for binary, WRITE for ASCII
197 XdrMODE mode = write_binary_data ? ENCODE : WRITE;
198
199 // Write out the parameter ranges
200 Xdr parameter_ranges_out(file_name, mode);
201 unsigned int n_continuous_params = get_n_continuous_params();
202 parameter_ranges_out << n_continuous_params;
203
204 // Note: the following loops are not candidates for structured
205 // bindings syntax because the Xdr APIs which they call are not
206 // defined for const references. We must therefore make copies to
207 // call these functions.
208 for (const auto & pr : get_parameters_min())
209 {
210 std::string param_name = pr.first;
211 if (!is_discrete_parameter(param_name))
212 {
213 Real param_value = get_parameters_min().get_value(param_name);
214 parameter_ranges_out << param_name << param_value;
215 }
216 }
217 for (const auto & pr : get_parameters_max())
218 {
219 std::string param_name = pr.first;
220 if (!is_discrete_parameter(param_name))
221 {
222 Real param_value = get_parameters_max().get_value(param_name);
223 parameter_ranges_out << param_name << param_value;
224 }
225 }
226
227 parameter_ranges_out.close();
228}
229
231 const bool write_binary_data)
232{
233 // write out the discrete parameters, if we have any
234 if (get_n_discrete_params() > 0)
235 {
236 // The writing mode: ENCODE for binary, WRITE for ASCII
237 XdrMODE mode = write_binary_data ? ENCODE : WRITE;
238
239 Xdr discrete_parameters_out(file_name, mode);
240 unsigned int n_discrete_params = get_n_discrete_params();
241 discrete_parameters_out << n_discrete_params;
242
243 // Note: the following loops are not candidates for structured
244 // bindings syntax because the Xdr APIs which they call are not
245 // defined for const references. We must therefore make copies
246 // to call these functions.
247 for (const auto & pr : get_discrete_parameter_values())
248 {
249 std::string param_name = pr.first;
250 auto n_discrete_values = cast_int<unsigned int>(pr.second.size());
251 discrete_parameters_out << param_name << n_discrete_values;
252
253 for (unsigned int i=0; i<n_discrete_values; i++)
254 {
255 Real discrete_value = pr.second[i];
256 discrete_parameters_out << discrete_value;
257 }
258 }
259 }
260}
261
262void RBParametrized::read_parameter_data_from_files(const std::string & continuous_param_file_name,
263 const std::string & discrete_param_file_name,
264 const bool read_binary_data)
265{
266 RBParameters param_min;
267 RBParameters param_max;
268 read_parameter_ranges_from_file(continuous_param_file_name,
269 read_binary_data,
270 param_min,
271 param_max);
272
273 std::map<std::string, std::vector<Real>> discrete_parameter_values_in;
274 read_discrete_parameter_values_from_file(discrete_param_file_name,
275 read_binary_data,
276 discrete_parameter_values_in);
277
278 initialize_parameters(param_min, param_max, discrete_parameter_values_in);
279}
280
281void RBParametrized::read_parameter_ranges_from_file(const std::string & file_name,
282 const bool read_binary_data,
283 RBParameters & param_min,
284 RBParameters & param_max)
285{
286 // The reading mode: DECODE for binary, READ for ASCII
287 XdrMODE mode = read_binary_data ? DECODE : READ;
288
289 // Read in the parameter ranges
290 Xdr parameter_ranges_in(file_name, mode);
291 unsigned int n_continuous_params;
292 parameter_ranges_in >> n_continuous_params;
293
294 for (unsigned int i=0; i<n_continuous_params; i++)
295 {
296 std::string param_name;
297 Real param_value;
298
299 parameter_ranges_in >> param_name;
300 parameter_ranges_in >> param_value;
301
302 param_min.set_value(param_name, param_value);
303 }
304 for (unsigned int i=0; i<n_continuous_params; i++)
305 {
306 std::string param_name;
307 Real param_value;
308
309 parameter_ranges_in >> param_name;
310 parameter_ranges_in >> param_value;
311
312 param_max.set_value(param_name, param_value);
313 }
314
315 parameter_ranges_in.close();
316}
317
319 const bool read_binary_data,
320 std::map<std::string, std::vector<Real>> & discrete_parameter_values)
321{
322 // read in the discrete parameters, if we have any
323 std::ifstream check_if_file_exists(file_name.c_str());
324 if (check_if_file_exists.good())
325 {
326 // The reading mode: DECODE for binary, READ for ASCII
327 XdrMODE mode = read_binary_data ? DECODE : READ;
328
329 // Read in the parameter ranges
330 Xdr discrete_parameter_values_in(file_name, mode);
331 unsigned int n_discrete_params;
332 discrete_parameter_values_in >> n_discrete_params;
333
334 for (unsigned int i=0; i<n_discrete_params; i++)
335 {
336 std::string param_name;
337 discrete_parameter_values_in >> param_name;
338
339 unsigned int n_discrete_values;
340 discrete_parameter_values_in >> n_discrete_values;
341
342 std::vector<Real> discrete_values(n_discrete_values);
343 for (auto & val : discrete_values)
344 discrete_parameter_values_in >> val;
345
346 discrete_parameter_values[param_name] = discrete_values;
347 }
348 }
349}
350
351bool RBParametrized::is_discrete_parameter(const std::string & mu_name) const
352{
353 libmesh_error_msg_if(!parameters_initialized,
354 "Error: parameters not initialized in RBParametrized::is_discrete_parameter");
355
356 return _discrete_parameter_values.count(mu_name);
357}
358
359const std::map<std::string, std::vector<Real>> & RBParametrized::get_discrete_parameter_values() const
360{
361 libmesh_error_msg_if(!parameters_initialized, "Error: parameters not initialized in RBParametrized::get_discrete_parameter_values");
362
364}
365
367{
368 for (const auto & [name, values] : get_discrete_parameter_values())
369 {
370 libMesh::out << "Discrete parameter " << name << ", values: ";
371
372 for (const auto & value : values)
373 libMesh::out << value << " ";
374 libMesh::out << std::endl;
375 }
376}
377
379{
380 // Check if number of parameters are correct.
381 libmesh_error_msg_if(params.n_parameters() != get_n_params(),
382 "Error: Number of parameters don't match; found "
383 << params.n_parameters() << ", expected "
384 << get_n_params());
385
386 bool is_valid = true;
387 std::string prev_param_name = "";
388 for (const auto & [param_name, sample_vec] : params)
389 {
390 std::size_t sample_idx = 0;
391 const Real & min_value = get_parameter_min(param_name);
392 const Real & max_value = get_parameter_max(param_name);
393 for (const auto & value_vec : sample_vec)
394 {
395 for (const auto & value : value_vec)
396 {
397 // Check every parameter value (including across samples and vector-values)
398 // to ensure it's within the min/max range.
399 const bool outside_range = ((value < min_value) || (value > max_value));
400 is_valid = is_valid && !outside_range;
401 if (outside_range && verbose_mode)
402 {
403 libMesh::out << "Warning: parameter " << param_name << " value="
404 << value << " outside acceptable range: ("
405 << min_value << ", " << max_value << ")";
406 }
407
408 // For discrete params, make sure params.get_value(param_name) is sufficiently
409 // close to one of the discrete parameter values.
410 // Note that vector-values not yet supported in discrete parameters,
411 // and the .get_sample_value() call will throw an error if the user
412 // tries to do it.
413 if (const auto it = get_discrete_parameter_values().find(param_name);
414 it != get_discrete_parameter_values().end())
415 {
416 const bool is_value_discrete =
417 is_value_in_list(params.get_sample_value(param_name, sample_idx),
418 it->second,
419 TOLERANCE);
420 is_valid = is_valid && is_value_discrete;
421 if (!is_value_discrete && verbose_mode)
422 libMesh::out << "Warning: parameter " << param_name << " value="
423 << value << " is not in discrete value list.";
424 }
425 }
426 ++sample_idx;
427 }
428 }
429 return is_valid;
430}
431
432Real RBParametrized::get_closest_value(Real value, const std::vector<Real> & list_of_values)
433{
434 libmesh_error_msg_if(list_of_values.empty(), "Error: list_of_values is empty.");
435
436 Real min_distance = std::numeric_limits<Real>::max();
437 Real closest_val = 0.;
438 for (const auto & current_value : list_of_values)
439 {
440 Real distance = std::abs(value - current_value);
441 if (distance < min_distance)
442 {
443 min_distance = distance;
444 closest_val = current_value;
445 }
446 }
447
448 return closest_val;
449}
450
451bool RBParametrized::is_value_in_list(Real value, const std::vector<Real> & list_of_values, Real tol)
452{
453 Real closest_value = get_closest_value(value, list_of_values);
454
455 // Check if relative tolerance is satisfied
456 Real rel_error = std::abs(value - closest_value) / std::abs(value);
457 if (rel_error <= tol)
458 {
459 return true;
460 }
461
462 // If relative tolerance isn't satisfied, we should still check an absolute
463 // error, since relative tolerance can be misleading if value is close to zero
464 Real abs_error = std::abs(value - closest_value);
465 return (abs_error <= tol);
466}
467
468} // namespace libMesh
This class is part of the rbOOmit framework.
unsigned int n_parameters() const
Get the number of parameters that have been added.
Real get_value(const std::string &param_name) const
Get the value of the specified parameter, throw an error if it does not exist.
void clear()
Clear this object.
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...
unsigned int n_samples() const
Returns the number of samples stored for all parameters.
const_iterator end_serialized() const
void print(unsigned precision=6, int max_values=5) const
Print the parameters.
const_iterator begin_serialized() const
Get const_iterator access to the parameters stored in this RBParameters object.
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.
void write_parameter_data_to_files(const std::string &continuous_param_file_name, const std::string &discrete_param_file_name, const bool write_binary_data)
Write out the parameter ranges to files.
const RBParameters & get_parameters_max() const
Get an RBParameters object that specifies the maximum allowable value for each parameter.
const RBParameters & get_parameters() const
Get the current parameters.
unsigned int get_n_params() const
Get the number of parameters.
bool set_parameters(const RBParameters &params)
Set the current parameters to params The parameters are checked for validity; an error is thrown if t...
RBParameters parameters
Vector storing the current parameters.
static Real get_closest_value(Real value, const std::vector< Real > &list_of_values)
void write_parameter_ranges_to_file(const std::string &file_name, const bool write_binary)
Write out the parameter ranges to file.
virtual void clear()
Clear all the data structures associated with the system.
void read_parameter_data_from_files(const std::string &continuous_param_file_name, const std::string &discrete_param_file_name, const bool read_binary_data)
Read in the parameter ranges from files.
const std::map< std::string, std::vector< Real > > & get_discrete_parameter_values() const
Get a const reference to the discrete parameter values.
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.
RBParameters parameters_min
Vectors that define the ranges (min and max) for the parameters.
static bool is_value_in_list(Real value, const std::vector< Real > &list_of_values, Real tol)
Helper function to check if the specified value is in the list of values (within a tolerance given by...
void write_discrete_parameter_values_to_file(const std::string &file_name, const bool write_binary_data)
Write out the discrete parameter values to file.
std::map< std::string, std::vector< Real > > _discrete_parameter_values
Map that defines the allowable values of any discrete parameters.
Real get_parameter_max(const std::string &param_name) const
Get maximum allowable value of parameter param_name.
void print_discrete_parameter_values() const
Print out all the discrete parameter values.
const RBParameters & get_parameters_min() const
Get an RBParameters object that specifies the minimum allowable value for each parameter.
Real get_parameter_min(const std::string &param_name) const
Get minimum allowable value of parameter param_name.
void print_parameters() const
Print the current parameters.
void read_discrete_parameter_values_from_file(const std::string &file_name, const bool read_binary_data, std::map< std::string, std::vector< Real > > &discrete_parameter_values_in)
Read in the discrete parameter values from file, if we have any.
bool check_if_valid_params(const RBParameters &params) const
Helper function to check that params is valid:
bool verbose_mode
Public boolean to toggle verbose mode.
void read_parameter_ranges_from_file(const std::string &file_name, const bool read_binary, RBParameters &param_min, RBParameters &param_max)
Read in the parameter ranges from file.
unsigned int get_n_continuous_params() const
Get the number of continuous parameters.
bool parameters_initialized
Flag indicating whether the parameters have been initialized.
bool is_discrete_parameter(const std::string &mu_name) const
Is parameter mu_name discrete?
unsigned int get_n_discrete_params() const
Get the number of discrete parameters.
This class implements a C++ interface to the XDR (eXternal Data Representation) format.
Definition xdr_cxx.h:68
void close()
Closes the file if it is open.
Definition xdr_cxx.C:278
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(ctx)
OStreamProxy out
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
XdrMODE
Defines an enum for read/write mode in Xdr format.
Real distance(const Point &p)
static const bool value
Definition xdr_io.C:55