libMesh
Loading...
Searching...
No Matches
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.

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
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
155 {
156 libMesh::out << std::endl << "Perform RB training" << std::endl << std::endl;
157
158 // Initialize the EquationSystems object for this mesh and attach
159 // the EIM and RB Construction objects
160 EquationSystems equation_systems (mesh);
161
162 SimpleEIMConstruction & eim_construction =
163 equation_systems.add_system<SimpleEIMConstruction> ("EIM");
164 SimpleRBConstruction & rb_construction =
165 equation_systems.add_system<SimpleRBConstruction> ("RB");
166
167 // Initialize the data structures for the equation system.
168 equation_systems.init ();
169
170 // Print out some information about the "truth" discretization
172 equation_systems.print_info();
173
174 // Initialize the standard RBEvaluation object
175 SimpleRBEvaluation rb_eval(mesh.comm());
176
177 // Initialize the EIM RBEvaluation object
178 SimpleEIMEvaluation eim_rb_eval(mesh.comm());
179
180 // Set the rb_eval objects for the RBConstructions
181 eim_construction.set_rb_eim_evaluation(eim_rb_eval);
182 rb_construction.set_rb_evaluation(rb_eval);
183
184 RBDataDeserialization::RBEIMEvaluationDeserialization rb_eim_eval_reader(eim_rb_eval);
185 rb_eim_eval_reader.read_from_file("rb_eim_eval.bin");
186 eim_rb_eval.read_in_basis_functions(rb_construction, "eim_data", eim_binary_io);
187
188 // Read data from input file and print state
189 rb_construction.process_parameters_file(rb_parameters);
190
191 // attach the EIM theta objects to the RBConstruction and RBEvaluation objects
192 eim_rb_eval.initialize_eim_theta_objects();
193 rb_eval.get_rb_theta_expansion().attach_multiple_F_theta(eim_rb_eval.get_eim_theta_objects());
194
195 // attach the EIM assembly objects to the RBConstruction object
196 eim_construction.initialize_eim_assembly_objects();
197 rb_construction.get_rb_assembly_expansion().attach_multiple_F_assembly(eim_construction.get_eim_assembly_objects());
198
199 // Print out the state of rb_construction now that the EIM objects have been attached
200 rb_construction.print_info();
201
202 // Need to initialize _after_ EIM greedy so that
203 // the system knows how many affine terms there are
204 rb_construction.initialize_rb_construction();
205 rb_construction.train_reduced_basis();
206
207 RBDataSerialization::RBEvaluationSerialization rb_eval_writer(rb_construction.get_rb_evaluation());
208 rb_eval_writer.write_to_file("rb_eval.bin");
209
210 rb_construction.get_rb_evaluation().write_out_basis_functions(rb_construction,
211 "rb_data");
212 }
213 }
214 else // online mode
215 {
216 SimpleEIMEvaluation eim_rb_eval(mesh.comm());
217 SimpleRBEvaluation rb_eval(mesh.comm());
218
219 RBDataDeserialization::RBEIMEvaluationDeserialization rb_eim_eval_reader(eim_rb_eval);
220 rb_eim_eval_reader.read_from_file("rb_eim_eval.bin");
221
222 // attach the EIM theta objects to rb_eval objects
223 eim_rb_eval.initialize_eim_theta_objects();
224 rb_eval.get_rb_theta_expansion().attach_multiple_F_theta(eim_rb_eval.get_eim_theta_objects());
225
226 // Read in the offline data for rb_eval
228 rb_eval_reader.read_from_file("rb_eval.bin", /*read_error_bound_data*/ true);
229
230 // Get the parameters at which we will do a reduced basis solve
231 Real online_center_x = infile("online_center_x", 0.);
232 Real online_center_y = infile("online_center_y", 0.);
233 RBParameters online_mu;
234 online_mu.push_back_value("center_x", online_center_x);
235 online_mu.push_back_value("center_y", online_center_y);
236
237 // Testing: Add secondary center_x and center_y values,
238 // corresponding to e.g. a different time step or load step.
239 online_mu.push_back_value("center_x", 0.5);
240 online_mu.push_back_value("center_y", 0.5);
241
242 // Add 3rd (center_x, center_y) values. For debugging purposes,
243 // we want the number of "samples" (3) to be different from the
244 // number of parameters (2).
245 online_mu.push_back_value("center_x", -0.25);
246 online_mu.push_back_value("center_y", -0.25);
247
248 // Here we are going to pre-evaluate the thetas and pass them in
249 // to rb_solve() in a loop. Note that the rb_solve doesn't
250 // explicitly need the parameters ("mus"), it just needs the
251 // evaluated functions of parameters ("thetas"), but we can
252 // perform an rb_solve() with either.
253 rb_eval.set_parameters(online_mu);
254 rb_eval.print_parameters();
255
256 // When performing an rb_solve() with "mu" values, we only
257 // support single-valued RBParameters objects. In this case,
258 // since the RBParameters object stores multiple "samples", we
259 // take the approach of pre-evaluating the thetas for each
260 // parameter while calling the rb_solve() in a loop.
261 const RBThetaExpansion & rb_theta_expansion = rb_eval.get_rb_theta_expansion();
262
263 // Single-entry vector which makes calling the vector-overrides
264 // of eval_A_theta(), eval_F_theta(), etc. easier.
265 std::vector<RBParameters> mu_vec = {online_mu};
266
267 // 1.) Evaluate and store "A" thetas at all samples:
268 std::vector<std::vector<Number>> all_A(rb_theta_expansion.get_n_A_terms());
269 for (unsigned int q_a=0; q_a<rb_theta_expansion.get_n_A_terms(); q_a++)
270 {
271 // Here we call the version of eval_A_theta() taking a
272 // vector, so we evaluate theta(mu) at all samples
273 // simultaneously.
274 all_A[q_a] = rb_theta_expansion.eval_A_theta(q_a, mu_vec);
275
276 // This size of each A_q vector here is:
277 // sum_i mu_vec[i].n_samples()
278 //
279 // Each A_q vector contains the logically 2D ragged array of
280 // values (theta[i], sample[j(i)]), arranged in "row-major"
281 // format, where the number of samples defined by each mu
282 // object can vary, and they are all concatenated together
283 // to produce one long list of samples.
284 //
285 // Example: suppose that there are 2 mu values containing
286 // the same sets of parameters, with 5 samples defined in the
287 // first and 10 samples defined in the second. Then, the A_q
288 // vector will look like:
289 //
290 // {Theta(mu_vec[0], sample_0), Theta(mu_vec[0], sample_1), ... Theta(mu_vec[0], sample_4),
291 // Theta(mu_vec[1], sample_0), Theta(mu_vec[1], sample_1), ... Theta(mu_vec[1], sample_4), ..., Theta(mu_vec[1], sample_9)}
292 //
293 // Note: this example is unusual in that it would be
294 // conceptually much simpler to have either:
295 // (i) A vector of 15 single-sample RBParameters objects, or
296 // (ii) A single RBParameters object with 15 samples defined in it.
297 // but we can also support a combination of approaches (i)
298 // and (ii) by concatenation, if necessary.
299 }
300
301 // 2.) Evaluate "F" thetas at all samples:
302 std::vector<std::vector<Number>> all_F(rb_theta_expansion.get_n_F_terms());
303 for (unsigned int q_f=0; q_f<rb_theta_expansion.get_n_F_terms(); q_f++)
304 all_F[q_f] = rb_theta_expansion.eval_F_theta(q_f, mu_vec);
305
306 // The eval_F_theta() calls above use "EIM solves" from eim_rb_eval, hence we
307 // can now print out the EIM error indicator values.
308 const auto & eim_error_indicators =
309 eim_rb_eval.get_rb_eim_error_indicators();
310
311 libMesh::out << std::scientific;
312 for (auto idx : index_range(eim_error_indicators))
313 libMesh::out << "EIM (error indicator, normalization factor) for step "
314 << idx << ": "
315 << "(" << eim_error_indicators[idx].first
316 << ", " << eim_error_indicators[idx].second
317 << ")" << std::endl;
318 libMesh::out << std::endl;
319
320 // 3.) Evaluate "output" thetas at all samples: in this case, the
321 // output is particularly simple (does not depend on mu) so this
322 // should just be a vector of all 1s.
323 std::vector<std::vector<Number>> all_outputs(rb_theta_expansion.get_total_n_output_terms());
324 {
325 unsigned int output_counter = 0;
326 for (unsigned int n=0; n<rb_theta_expansion.get_n_outputs(); n++)
327 for (unsigned int q_l=0; q_l<rb_theta_expansion.get_n_output_terms(n); q_l++)
328 all_outputs[output_counter++] =
329 rb_theta_expansion.eval_output_theta(n, q_l, mu_vec);
330 }
331
332 // The total number of thetas is the sum of the "A", "F", and
333 // "output" thetas.
334 unsigned int n_thetas =
335 rb_theta_expansion.get_n_A_terms() +
336 rb_theta_expansion.get_n_F_terms() +
337 rb_theta_expansion.get_total_n_output_terms();
338
339 // Allocate enough space to store all the evaluated theta values for this RBThetaExpansion
340 std::vector<Number> evaluated_thetas(n_thetas);
341
342 // The RBConstruction object is used for plotting reduced-basis solutions (visualization)
343 EquationSystems equation_systems (mesh);
344
345 SimpleRBConstruction & rb_construction =
346 equation_systems.add_system<SimpleRBConstruction> ("RB");
347
348 equation_systems.init ();
349
350 // Tell the RBConstruction object about the RBEvaluation object
351 // and read in the RB basis functions.
352 rb_construction.set_rb_evaluation(rb_eval);
353 rb_eval.read_in_basis_functions(rb_construction, "rb_data");
354
355 // Loop over each sample, fill the evaluated_thetas array, call rb_solve()
356 for (unsigned sample_idx=0; sample_idx<online_mu.n_samples(); ++sample_idx)
357 {
358 unsigned int counter = 0;
359
360 // Set A Theta values for current sample
361 for (unsigned int q_a=0; q_a<rb_theta_expansion.get_n_A_terms(); q_a++)
362 evaluated_thetas[counter++] = all_A[q_a][sample_idx];
363
364 // Set F Theta values for current sample
365 for (unsigned int q_f=0; q_f<rb_theta_expansion.get_n_F_terms(); q_f++)
366 evaluated_thetas[counter++] = all_F[q_f][sample_idx];
367
368 // Set output Theta values for current sample
369 {
370 unsigned int output_counter = 0;
371 for (unsigned int n=0; n<rb_theta_expansion.get_n_outputs(); n++)
372 for (unsigned int q_l=0; q_l<rb_theta_expansion.get_n_output_terms(n); q_l++)
373 evaluated_thetas[counter++] = all_outputs[output_counter++][sample_idx];
374 }
375
376 // Call rb_solve() for the current thetas
377 libMesh::out << "Performing solve for step " << sample_idx << std::endl;
378 rb_eval.rb_solve(rb_eval.get_n_basis_functions(), &evaluated_thetas);
379
380 // Print the output as well as the corresponding output error bound
381 for (auto i : index_range(rb_eval.RB_outputs))
382 libMesh::out << "Output value " << i << " = " << rb_eval.RB_outputs[i]
383 << ", error bound " << i << " = " << rb_eval.RB_output_error_bounds[i]
384 << std::endl;
385
386 // Write an exo file to visualize this solution
387 rb_construction.load_rb_solution();
388#ifdef LIBMESH_HAVE_EXODUS_API
389 ExodusII_IO(mesh).write_equation_systems("RB_sol_" + std::to_string(sample_idx) + ".e", equation_systems);
390#endif
391 } // end for (sample)
392 }
393
394#endif // LIBMESH_ENABLE_DIRICHLET
395}
unsigned int dim
This is the EquationSystems class.
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition exodusII_io.h:53
virtual void write_equation_systems(const std::string &fname, const EquationSystems &es, const std::set< std::string > *system_names=nullptr) override
Writes out the solution for no specific time or timestep.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition libmesh.h:92
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:1755
const Parallel::Communicator & comm() const
void set_rb_evaluation(RBEvaluation &rb_eval_in)
Set the RBEvaluation object.
virtual void load_rb_solution()
Load the RB solution from the most recent solve with rb_eval into this system's solution vector.
This class de-serializes a RBEIMEvaluation object using the Cap'n Proto library.
This class de-serializes an RBEvaluation object using the Cap'n Proto library.
This class serializes an RBEIMEvaluation object using the Cap'n Proto library.
This class serializes an RBEvaluation object using the Cap'n Proto library.
void initialize_eim_construction()
Perform initialization of this object to prepare for running train_eim_approximation().
std::vector< std::unique_ptr< ElemAssembly > > & get_eim_assembly_objects()
virtual void initialize_eim_assembly_objects()
Build a vector of ElemAssembly objects that accesses the basis functions stored in this RBEIMConstruc...
void set_rb_eim_evaluation(RBEIMEvaluation &rb_eim_eval_in)
Set the RBEIMEvaluation object.
virtual Real train_eim_approximation()
Generate the EIM approximation for the specified parametrized function using either POD or the Greedy...
virtual void print_info()
Print out info that describes the current setup of this RBConstruction.
virtual void process_parameters_file(const std::string &parameters_filename)
Read parameters in from file and set up this system accordingly.
This class is part of the rbOOmit framework.
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,...
unsigned int n_samples() const
Returns the number of samples stored for all parameters.
This class stores the set of RBTheta functor objects that define the "parameter-dependent expansion" ...
virtual Number eval_F_theta(unsigned int q, const RBParameters &mu) const
Evaluate theta_q_f at the current parameter.
unsigned int get_total_n_output_terms() const
Returns the total number of affine terms associated with all outputs.
unsigned int get_n_F_terms() const
Get Q_f, the number of terms in the affine expansion for the right-hand side.
unsigned int get_n_A_terms() const
Get Q_a, the number of terms in the affine expansion for the bilinear form.
virtual Number eval_A_theta(unsigned int q, const RBParameters &mu) const
Evaluate theta_q_a at the current parameter.
unsigned int get_n_output_terms(unsigned int output_index) const
Get the number of affine terms associated with the specified output.
unsigned int get_n_outputs() const
Get n_outputs, the number output functionals.
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...
void init()
Initializes degrees of freedom on the current mesh.
Definition system.C:196
MeshBase & mesh
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.
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.
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).
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
The libMesh namespace provides an interface to certain functionality in the library.
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:153
SolverPackage default_solver_package()
Definition libmesh.C:1064
OStreamProxy out
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line.
Definition libmesh.C:1025
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References libMesh::EquationSystems::add_system(), libMesh::RBThetaExpansion::attach_multiple_F_theta(), 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::RBEvaluation::get_n_basis_functions(), libMesh::RBThetaExpansion::get_n_F_terms(), libMesh::RBThetaExpansion::get_n_output_terms(), libMesh::RBThetaExpansion::get_n_outputs(), libMesh::RBEvaluation::get_rb_theta_expansion(), libMesh::RBThetaExpansion::get_total_n_output_terms(), libMesh::index_range(), libMesh::EquationSystems::init(), libMesh::RBEIMConstruction::initialize_eim_assembly_objects(), libMesh::RBEIMConstruction::initialize_eim_construction(), libMesh::INVALID_SOLVER_PACKAGE, libMesh::RBConstruction::load_rb_solution(), main(), mesh, libMesh::RBParameters::n_samples(), libMesh::out, libMesh::RBEIMConstruction::print_info(), libMesh::EquationSystems::print_info(), libMesh::MeshBase::print_info(), libMesh::RBParametrized::print_parameters(), libMesh::RBEIMConstruction::process_parameters_file(), libMesh::RBParameters::push_back_value(), libMesh::QUAD4, libMesh::RBEvaluation::RB_output_error_bounds, libMesh::RBEvaluation::RB_outputs, libMesh::RBEvaluation::rb_solve(), libMesh::RBDataDeserialization::RBEvaluationDeserialization::read_from_file(), libMesh::RBDataDeserialization::RBEIMEvaluationDeserialization::read_from_file(), libMesh::RBEvaluation::read_in_basis_functions(), libMesh::Real, libMesh::RBParametrized::set_parameters(), libMesh::RBEIMConstruction::set_rb_eim_evaluation(), libMesh::RBConstruction::set_rb_evaluation(), libMesh::RBEIMConstruction::train_eim_approximation(), libMesh::ExodusII_IO::write_equation_systems(), libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file(), and libMesh::RBDataSerialization::RBEIMEvaluationSerialization::write_to_file().