libMesh
Functions
reduced_basis_ex4.C File Reference

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 58 of file reduced_basis_ex4.C.

References libMesh::EquationSystems::add_system(), libMesh::MeshTools::Generation::build_square(), libMesh::ParallelObject::comm(), libMesh::command_line_next(), libMesh::default_solver_package(), dim, libMesh::RBThetaExpansion::eval_A_theta(), libMesh::RBThetaExpansion::eval_F_theta(), libMesh::RBThetaExpansion::eval_output_theta(), libMesh::RBEIMConstruction::get_eim_assembly_objects(), libMesh::RBThetaExpansion::get_n_A_terms(), libMesh::RBThetaExpansion::get_n_F_terms(), libMesh::RBThetaExpansion::get_n_output_terms(), libMesh::RBThetaExpansion::get_n_outputs(), libMesh::RBEIMConstruction::get_parametrized_function_from_training_set(), libMesh::RBThetaExpansion::get_total_n_output_terms(), libMesh::MeshTools::Generation::Private::idx(), libMesh::index_range(), libMesh::TriangleWrapper::init(), libMesh::EquationSystems::init(), libMesh::RBEIMConstruction::initialize_eim_assembly_objects(), libMesh::RBEIMConstruction::initialize_eim_construction(), libMesh::INVALID_SOLVER_PACKAGE, libMesh::RBConstruction::load_rb_solution(), mesh, libMesh::MeshTools::n_elem(), libMesh::RBParameters::n_samples(), libMesh::System::name(), libMesh::out, libMesh::RBEIMConstruction::print_info(), libMesh::EquationSystems::print_info(), libMesh::MeshBase::print_info(), libMesh::RBEIMConstruction::process_parameters_file(), libMesh::RBParameters::push_back_value(), libMesh::QUAD4, libMesh::RBDataDeserialization::RBEvaluationDeserialization::read_from_file(), libMesh::RBDataDeserialization::RBEIMEvaluationDeserialization::read_from_file(), libMesh::Real, libMesh::RBEIMConstruction::set_rb_eim_evaluation(), libMesh::RBConstruction::set_rb_evaluation(), libMesh::RBEIMConstruction::train_eim_approximation(), libMesh::MeshOutput< MT >::write_equation_systems(), libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file(), and libMesh::RBDataSerialization::RBEIMEvaluationSerialization::write_to_file().

59 {
60  // Initialize libMesh.
61  LibMeshInit init (argc, argv);
62 
63  // This example requires a linear solver package.
64  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
65  "--enable-petsc, --enable-trilinos, or --enable-eigen");
66 
67 #if !defined(LIBMESH_HAVE_XDR)
68  // We need XDR support to write out reduced bases
69  libmesh_example_requires(false, "--enable-xdr");
70 #elif defined(LIBMESH_DEFAULT_SINGLE_PRECISION)
71  // XDR binary support requires double precision
72  libmesh_example_requires(false, "double precision");
73 #elif defined(LIBMESH_DEFAULT_TRIPLE_PRECISION)
74  // I have no idea why long double isn't working here... [RHS]
75  libmesh_example_requires(false, "double precision");
76 #endif
77 
78  // Skip this 2D example if libMesh was compiled as 1D-only.
79  libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
80 
81  // This example requires libmesh to be configured with both
82  // DirichletBoundary and Cap'n Proto support.
83 #if !defined(LIBMESH_ENABLE_DIRICHLET) || !defined(LIBMESH_HAVE_CAPNPROTO)
84  libmesh_example_requires(false, "--enable-dirichlet --enable-capnp");
85 #else
86 
87  // Define the names of the input files we will read the problem properties from
88  std::string eim_parameters = "eim.in";
89  std::string rb_parameters = "rb.in";
90  std::string main_parameters = "reduced_basis_ex4.in";
91  GetPot infile(main_parameters);
92 
93  unsigned int n_elem = infile("n_elem", 1); // Determines the number of elements in the "truth" mesh
94  const unsigned int dim = 2; // The number of spatial dimensions
95 
96  // Read the "online_mode" flag from the command line
97  const int online_mode =
98  libMesh::command_line_next("-online_mode", 0),
99  eim_training_function_to_plot =
100  libMesh::command_line_next("-eim_training_function_to_plot", 0),
101  eim_basis_function_to_plot =
102  libMesh::command_line_next("-eim_basis_function_to_plot", 0);
103 
104  ReplicatedMesh mesh (init.comm(), dim);
106  n_elem, n_elem,
107  -1., 1.,
108  -1., 1.,
109  QUAD4);
110 
111  // Set to true the write binary (XDR) files with EIM data, false to write ASCII files.
112  bool eim_binary_io = true;
113 
114  if (!online_mode)
115  {
116  // First run the Offline stage for the EIM approximation.
117  {
118  libMesh::out << "Perform EIM training" << std::endl << std::endl;
119 
120  // Initialize the EquationSystems object for this mesh and attach
121  // the EIM and RB Construction objects
122  EquationSystems equation_systems (mesh);
123 
124  SimpleEIMConstruction & eim_construction =
125  equation_systems.add_system<SimpleEIMConstruction> ("EIM");
126 
127  // Initialize the data structures for the equation system.
128  equation_systems.init ();
129 
130  // Print out some information about the "truth" discretization
131  mesh.print_info();
132  equation_systems.print_info();
133 
134  // Initialize the EIM RBEvaluation object
135  SimpleEIMEvaluation eim_rb_eval(mesh.comm());
136 
137  // Set the rb_eval objects for the RBConstructions
138  eim_construction.set_rb_eim_evaluation(eim_rb_eval);
139 
140  // Read data from input file and print state
141  eim_construction.process_parameters_file(eim_parameters);
142  eim_construction.print_info();
143 
144  // Perform the EIM Greedy and write out the data
145  eim_construction.initialize_eim_construction();
146  eim_construction.train_eim_approximation();
147 
148  RBDataSerialization::RBEIMEvaluationSerialization rb_eim_eval_writer(eim_rb_eval);
149  rb_eim_eval_writer.write_to_file("rb_eim_eval.bin");
150 
151  // Write out the EIM basis functions
152  eim_rb_eval.write_out_basis_functions("eim_data", eim_binary_io);
153 
154 #ifdef LIBMESH_HAVE_EXODUS_API
155  // Plot one of the parametrized functions from the training set
156  eim_rb_eval.project_qp_data_map_onto_system(eim_construction,
157  eim_construction.get_parametrized_function_from_training_set(eim_training_function_to_plot),
158  /*eim_var*/ 0);
159  std::set<std::string> system_names = {eim_construction.name()};
160  ExodusII_IO(mesh).write_equation_systems("eim_parametrized_function.e", equation_systems, &system_names);
161 
162  // Plot one of the basis functions
163  eim_rb_eval.project_qp_data_map_onto_system(eim_construction,
164  eim_rb_eval.get_basis_function(eim_basis_function_to_plot),
165  /*eim_var*/ 0);
166  ExodusII_IO(mesh).write_equation_systems("eim_basis_function.e", equation_systems, &system_names);
167 #endif
168  }
169 
170  {
171  libMesh::out << std::endl << "Perform RB training" << std::endl << std::endl;
172 
173  // Initialize the EquationSystems object for this mesh and attach
174  // the EIM and RB Construction objects
175  EquationSystems equation_systems (mesh);
176 
177  SimpleEIMConstruction & eim_construction =
178  equation_systems.add_system<SimpleEIMConstruction> ("EIM");
179  SimpleRBConstruction & rb_construction =
180  equation_systems.add_system<SimpleRBConstruction> ("RB");
181 
182  // Initialize the data structures for the equation system.
183  equation_systems.init ();
184 
185  // Print out some information about the "truth" discretization
186  mesh.print_info();
187  equation_systems.print_info();
188 
189  // Initialize the standard RBEvaluation object
190  SimpleRBEvaluation rb_eval(mesh.comm());
191 
192  // Initialize the EIM RBEvaluation object
193  SimpleEIMEvaluation eim_rb_eval(mesh.comm());
194 
195  // Set the rb_eval objects for the RBConstructions
196  eim_construction.set_rb_eim_evaluation(eim_rb_eval);
197  rb_construction.set_rb_evaluation(rb_eval);
198 
199  RBDataDeserialization::RBEIMEvaluationDeserialization rb_eim_eval_reader(eim_rb_eval);
200  rb_eim_eval_reader.read_from_file("rb_eim_eval.bin");
201  eim_rb_eval.read_in_basis_functions(rb_construction, "eim_data", eim_binary_io);
202 
203  // Read data from input file and print state
204  rb_construction.process_parameters_file(rb_parameters);
205 
206  // attach the EIM theta objects to the RBConstruction and RBEvaluation objects
207  eim_rb_eval.initialize_eim_theta_objects();
208  rb_eval.get_rb_theta_expansion().attach_multiple_F_theta(eim_rb_eval.get_eim_theta_objects());
209 
210  // attach the EIM assembly objects to the RBConstruction object
211  eim_construction.initialize_eim_assembly_objects();
212  rb_construction.get_rb_assembly_expansion().attach_multiple_F_assembly(eim_construction.get_eim_assembly_objects());
213 
214  // Print out the state of rb_construction now that the EIM objects have been attached
215  rb_construction.print_info();
216 
217  // Need to initialize _after_ EIM greedy so that
218  // the system knows how many affine terms there are
219  rb_construction.initialize_rb_construction();
220  rb_construction.train_reduced_basis();
221 
222  RBDataSerialization::RBEvaluationSerialization rb_eval_writer(rb_construction.get_rb_evaluation());
223  rb_eval_writer.write_to_file("rb_eval.bin");
224 
225  rb_construction.get_rb_evaluation().write_out_basis_functions(rb_construction,
226  "rb_data");
227  }
228  }
229  else // online mode
230  {
231  SimpleEIMEvaluation eim_rb_eval(mesh.comm());
232  SimpleRBEvaluation rb_eval(mesh.comm());
233 
234  RBDataDeserialization::RBEIMEvaluationDeserialization rb_eim_eval_reader(eim_rb_eval);
235  rb_eim_eval_reader.read_from_file("rb_eim_eval.bin");
236 
237  // attach the EIM theta objects to rb_eval objects
238  eim_rb_eval.initialize_eim_theta_objects();
239  rb_eval.get_rb_theta_expansion().attach_multiple_F_theta(eim_rb_eval.get_eim_theta_objects());
240 
241  // Read in the offline data for rb_eval
243  rb_eval_reader.read_from_file("rb_eval.bin", /*read_error_bound_data*/ true);
244 
245  // Get the parameters at which we will do a reduced basis solve
246  Real online_center_x = infile("online_center_x", 0.);
247  Real online_center_y = infile("online_center_y", 0.);
248  RBParameters online_mu;
249  online_mu.push_back_value("center_x", online_center_x);
250  online_mu.push_back_value("center_y", online_center_y);
251 
252  // Testing: Add secondary center_x and center_y values,
253  // corresponding to e.g. a different time step or load step.
254  online_mu.push_back_value("center_x", 0.5);
255  online_mu.push_back_value("center_y", 0.5);
256 
257  // Add 3rd (center_x, center_y) values. For debugging purposes,
258  // we want the number of "samples" (3) to be different from the
259  // number of parameters (2).
260  online_mu.push_back_value("center_x", -0.25);
261  online_mu.push_back_value("center_y", -0.25);
262 
263  // Here we are going to pre-evaluate the thetas and pass them in
264  // to rb_solve() in a loop. Note that the rb_solve doesn't
265  // explicitly need the parameters ("mus"), it just needs the
266  // evaluated functions of parameters ("thetas"), but we can
267  // perform an rb_solve() with either.
268  rb_eval.set_parameters(online_mu);
269  rb_eval.print_parameters();
270 
271  // When performing an rb_solve() with "mu" values, we only
272  // support single-valued RBParameters objects. In this case,
273  // since the RBParameters object stores multiple "samples", we
274  // take the approach of pre-evaluating the thetas for each
275  // parameter while calling the rb_solve() in a loop.
276  const RBThetaExpansion & rb_theta_expansion = rb_eval.get_rb_theta_expansion();
277 
278  // Single-entry vector which makes calling the vector-overrides
279  // of eval_A_theta(), eval_F_theta(), etc. easier.
280  std::vector<RBParameters> mu_vec = {online_mu};
281 
282  // 1.) Evaluate and store "A" thetas at all samples:
283  std::vector<std::vector<Number>> all_A(rb_theta_expansion.get_n_A_terms());
284  for (unsigned int q_a=0; q_a<rb_theta_expansion.get_n_A_terms(); q_a++)
285  {
286  // Here we call the version of eval_A_theta() taking a
287  // vector, so we evaluate theta(mu) at all samples
288  // simultaneously.
289  all_A[q_a] = rb_theta_expansion.eval_A_theta(q_a, mu_vec);
290 
291  // This size of each A_q vector here is:
292  // sum_i mu_vec[i].n_samples()
293  //
294  // Each A_q vector contains the logically 2D ragged array of
295  // values (theta[i], sample[j(i)]), arranged in "row-major"
296  // format, where the number of samples defined by each mu
297  // object can vary, and they are all concatenated together
298  // to produce one long list of samples.
299  //
300  // Example: suppose that there are 2 mu values containing
301  // the same sets of parameters, with 5 samples defined in the
302  // first and 10 samples defined in the second. Then, the A_q
303  // vector will look like:
304  //
305  // {Theta(mu_vec[0], sample_0), Theta(mu_vec[0], sample_1), ... Theta(mu_vec[0], sample_4),
306  // Theta(mu_vec[1], sample_0), Theta(mu_vec[1], sample_1), ... Theta(mu_vec[1], sample_4), ..., Theta(mu_vec[1], sample_9)}
307  //
308  // Note: this example is unusual in that it would be
309  // conceptually much simpler to have either:
310  // (i) A vector of 15 single-sample RBParameters objects, or
311  // (ii) A single RBParameters object with 15 samples defined in it.
312  // but we can also support a combination of approaches (i)
313  // and (ii) by concatenation, if necessary.
314  }
315 
316  // 2.) Evaluate "F" thetas at all samples:
317  std::vector<std::vector<Number>> all_F(rb_theta_expansion.get_n_F_terms());
318  for (unsigned int q_f=0; q_f<rb_theta_expansion.get_n_F_terms(); q_f++)
319  all_F[q_f] = rb_theta_expansion.eval_F_theta(q_f, mu_vec);
320 
321  // The eval_F_theta() calls above use "EIM solves" from eim_rb_eval, hence we
322  // can now print out the EIM error indicator values.
323  const auto & eim_error_indicators =
324  eim_rb_eval.get_rb_eim_error_indicators();
325  for (auto idx : index_range(eim_error_indicators))
326  libMesh::out << "EIM error indicator for step: " << idx << ": "
327  << std::scientific << eim_error_indicators[idx] << std::endl;
328  libMesh::out << std::endl;
329 
330  // 3.) Evaluate "output" thetas at all samples: in this case, the
331  // output is particularly simple (does not depend on mu) so this
332  // should just be a vector of all 1s.
333  std::vector<std::vector<Number>> all_outputs(rb_theta_expansion.get_total_n_output_terms());
334  {
335  unsigned int output_counter = 0;
336  for (unsigned int n=0; n<rb_theta_expansion.get_n_outputs(); n++)
337  for (unsigned int q_l=0; q_l<rb_theta_expansion.get_n_output_terms(n); q_l++)
338  all_outputs[output_counter++] =
339  rb_theta_expansion.eval_output_theta(n, q_l, mu_vec);
340  }
341 
342  // The total number of thetas is the sum of the "A", "F", and
343  // "output" thetas.
344  unsigned int n_thetas =
345  rb_theta_expansion.get_n_A_terms() +
346  rb_theta_expansion.get_n_F_terms() +
347  rb_theta_expansion.get_total_n_output_terms();
348 
349  // Allocate enough space to store all the evaluated theta values for this RBThetaExpansion
350  std::vector<Number> evaluated_thetas(n_thetas);
351 
352  // The RBConstruction object is used for plotting reduced-basis solutions (visualization)
353  EquationSystems equation_systems (mesh);
354 
355  SimpleRBConstruction & rb_construction =
356  equation_systems.add_system<SimpleRBConstruction> ("RB");
357 
358  equation_systems.init ();
359 
360  // Tell the RBConstruction object about the RBEvaluation object
361  // and read in the RB basis functions.
362  rb_construction.set_rb_evaluation(rb_eval);
363  rb_eval.read_in_basis_functions(rb_construction, "rb_data");
364 
365  // Loop over each sample, fill the evaluated_thetas array, call rb_solve()
366  for (unsigned sample_idx=0; sample_idx<online_mu.n_samples(); ++sample_idx)
367  {
368  unsigned int counter = 0;
369 
370  // Set A Theta values for current sample
371  for (unsigned int q_a=0; q_a<rb_theta_expansion.get_n_A_terms(); q_a++)
372  evaluated_thetas[counter++] = all_A[q_a][sample_idx];
373 
374  // Set F Theta values for current sample
375  for (unsigned int q_f=0; q_f<rb_theta_expansion.get_n_F_terms(); q_f++)
376  evaluated_thetas[counter++] = all_F[q_f][sample_idx];
377 
378  // Set output Theta values for current sample
379  {
380  unsigned int output_counter = 0;
381  for (unsigned int n=0; n<rb_theta_expansion.get_n_outputs(); n++)
382  for (unsigned int q_l=0; q_l<rb_theta_expansion.get_n_output_terms(n); q_l++)
383  evaluated_thetas[counter++] = all_outputs[output_counter++][sample_idx];
384  }
385 
386  // Call rb_solve() for the current thetas
387  libMesh::out << "Performing solve for step " << sample_idx << std::endl;
388  rb_eval.rb_solve(rb_eval.get_n_basis_functions(), &evaluated_thetas);
389 
390  // Print the output as well as the corresponding output error bound
391  for (auto i : index_range(rb_eval.RB_outputs))
392  libMesh::out << "Output value " << i << " = " << rb_eval.RB_outputs[i]
393  << ", error bound " << i << " = " << rb_eval.RB_output_error_bounds[i]
394  << std::endl;
395 
396  // Write an exo file to visualize this solution
397  rb_construction.load_rb_solution();
398 #ifdef LIBMESH_HAVE_EXODUS_API
399  ExodusII_IO(mesh).write_equation_systems("RB_sol_" + std::to_string(sample_idx) + ".e", equation_systems);
400 #endif
401  } // end for (sample)
402  }
403 
404 #endif // LIBMESH_ENABLE_DIRICHLET
405 }
T command_line_next(std::string name, T default_value)
Use GetPot&#39;s search()/next() functions to get following arguments from the command line...
Definition: libmesh.C:1011
This is the EquationSystems class.
virtual Number eval_output_theta(unsigned int output_index, unsigned int q_l, const RBParameters &mu) const
Evaluate theta_q_l at the current parameter.
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
virtual Number eval_A_theta(unsigned int q, const RBParameters &mu) const
Evaluate theta_q_a at the current parameter.
unsigned int get_n_F_terms() const
Get Q_f, the number of terms in the affine expansion for the right-hand side.
void initialize_eim_construction()
Perform initialization of this object to prepare for running train_eim_approximation().
This class serializes an RBEvaluation object using the Cap&#39;n Proto library.
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
Definition: mesh_output.C:31
dof_id_type n_elem(const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
Count up the number of elements of a specific type (as defined by an iterator range).
Definition: mesh_tools.C:850
unsigned int dim
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:52
virtual Real train_eim_approximation()
Generate the EIM approximation for the specified parametrized function using either POD or the Greedy...
MeshBase & mesh
virtual void process_parameters_file(const std::string &parameters_filename)
Read parameters in from file and set up this system accordingly.
unsigned int get_n_A_terms() const
Get Q_a, the number of terms in the affine expansion for the bilinear form.
const Parallel::Communicator & comm() const
const QpDataMap & get_parametrized_function_from_training_set(unsigned int training_index) const
Get a const reference to the specified parametrized function from the training set.
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:90
This class serializes an RBEIMEvaluation object using the Cap&#39;n Proto library.
unsigned int get_n_outputs() const
Get n_outputs, the number output functionals.
void init()
Initializes degrees of freedom on the current mesh.
Definition: system.C:189
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
virtual void print_info()
Print out info that describes the current setup of this RBConstruction.
SolverPackage default_solver_package()
Definition: libmesh.C:1050
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Definition: mesh_base.C:1489
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
virtual Number eval_F_theta(unsigned int q, const RBParameters &mu) const
Evaluate theta_q_f at the current parameter.
This class is part of the rbOOmit framework.
Definition: rb_parameters.h:52
void write_to_file(const std::string &path)
Write the Cap&#39;n&#39;Proto buffer to disk.
unsigned int n_samples() const
Returns the number of samples stored for all parameters.
void set_rb_eim_evaluation(RBEIMEvaluation &rb_eim_eval_in)
Set the RBEIMEvaluation object.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int get_n_output_terms(unsigned int output_index) const
Get the number of affine terms associated with the specified output.
virtual void initialize_eim_assembly_objects()
Build a vector of ElemAssembly objects that accesses the basis functions stored in this RBEIMConstruc...
std::vector< std::unique_ptr< ElemAssembly > > & get_eim_assembly_objects()
unsigned int get_total_n_output_terms() const
Returns the total number of affine terms associated with all outputs.
OStreamProxy out
This class de-serializes an RBEvaluation object using the Cap&#39;n Proto library.
const std::string & name() const
Definition: system.h:2261
virtual void load_rb_solution()
Load the RB solution from the most recent solve with rb_eval into this system&#39;s solution vector...
void set_rb_evaluation(RBEvaluation &rb_eval_in)
Set the RBEvaluation object.
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.
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:111
This class de-serializes a RBEIMEvaluation object using the Cap&#39;n Proto library.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
A useful inline function which replaces the macros used previously.