libMesh
Loading...
Searching...
No Matches
reduced_basis_ex7.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18// rbOOmit: An implementation of the Certified Reduced Basis method.
19// Copyright (C) 2009, 2010 David J. Knezevic
20// This file is part of rbOOmit.
21
22
23
24// <h1>Reduced Basis Example 7 - Acoustic Horn</h1>
25// \author David Knezevic
26// \date 2012
27//
28// In this example problem we use the Certified Reduced Basis method
29// to solve a complex-valued Helmholtz problem for acoustics. There is only
30// one parameter in this problem: the forcing frequency at the horn inlet.
31// We impose a radiation boundary condition on the outer boundary.
32//
33// In the Online stage we write out the reflection coefficient as a function
34// of frequency. The reflection coefficient gives the ratio of the reflected
35// wave to the applied wave at the inlet.
36
37// C++ include files that we need
38#include <iostream>
39#include <algorithm>
40#include <cmath>
41#include <set>
42
43// Basic include file needed for the mesh functionality.
44#include "libmesh/libmesh.h"
45#include "libmesh/mesh.h"
46#include "libmesh/mesh_generation.h"
47#include "libmesh/exodusII_io.h"
48#include "libmesh/equation_systems.h"
49#include "libmesh/dof_map.h"
50#include "libmesh/getpot.h"
51#include "libmesh/elem.h"
52#include "libmesh/rb_data_serialization.h"
53#include "libmesh/rb_data_deserialization.h"
54#include "libmesh/enum_solver_package.h"
55
56// local includes
57#include "rb_classes.h"
58#include "assembly.h"
59
60// Bring in everything from the libMesh namespace
61using namespace libMesh;
62
63// The main program.
64int main (int argc, char** argv)
65{
66 // Initialize libMesh.
67 LibMeshInit init (argc, argv);
68
69#ifndef LIBMESH_USE_COMPLEX_NUMBERS
70 libmesh_example_requires(false, "--enable-complex");
71#else
72
73#if !defined(LIBMESH_HAVE_XDR)
74 // We need XDR support to write out reduced bases
75 libmesh_example_requires(false, "--enable-xdr");
76#elif defined(LIBMESH_DEFAULT_SINGLE_PRECISION)
77 // XDR binary support requires double precision
78 libmesh_example_requires(false, "--disable-singleprecision");
79#elif defined(LIBMESH_DEFAULT_TRIPLE_PRECISION)
80 // long double doesn't work on the previous examples, don't try it
81 // here
82 libmesh_example_requires(false, "double precision");
83#endif
84 // FIXME: This example currently segfaults with Trilinos?
85 libmesh_example_requires(libMesh::default_solver_package() == PETSC_SOLVERS, "--enable-petsc");
86
87#ifdef LIBMESH_HAVE_PETSC
88 // lets parse the input to check which set of arguments was provided.
89 // Skip the runs with wrong arguments:
90 GetPot input(argc, argv);
91
92 // skip if the specification of the solver-package is given in wrong syntax:
93#if PETSC_VERSION_LESS_THAN(3,9,0)
94 if (input.search("-pc_factor_mat_solver_type"))
95 {
96 libMesh::out << "LibMesh was configured with PETSc < 3.9, but command-line options "
97 << "use syntax understood by later versions only. Skipping this example."
98 << std::endl;
99 return 77;
100 }
101 input.search("-pc_factor_mat_solver_package");
102#else
103 if (input.search("-pc_factor_mat_solver_package"))
104 {
105 libMesh::out << "LibMesh was configured with PETSc >= 3.9, but command-line options "
106 << "use deprecated syntax. Skipping now."
107 << std::endl;
108 return 77;
109 }
110 input.search("-pc_factor_mat_solver_type");
111#endif
112
113 // check that we have the required solver:
114 std::string solver;
115 solver = input.next("invalid_solver");
116 if (solver == "mumps")
117 {
118#ifndef LIBMESH_PETSC_HAVE_MUMPS
119 libmesh_example_requires(false, "PETSc compiled with MUMPS support");
120#endif
121 }
122 else if (solver == "superlu")
123 {
124#ifndef LIBMESH_PETSC_HAVE_SUPERLU_DIST
125 libmesh_example_requires(false, "PETSc compiled with SuperLU support");
126#endif
127 }
128 else
129 {
130 libMesh::err << "Error: Solver " << solver << " is unknown."
131 << std::endl;
132 return 1;
133 }
134
135#endif //LIBMESH_HAVE_PETSC
136
137 // Skip this 2D example if libMesh was compiled as 1D-only.
138 libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
139
140 // Parse the input file (reduced_basis_ex7.in) using GetPot
141 std::string parameters_filename = "reduced_basis_ex7.in";
142 GetPot infile(parameters_filename);
143
144 const unsigned int dim = 2; // The number of spatial dimensions
145
146 bool store_basis_functions = infile("store_basis_functions", true); // Do we write the RB basis functions to disk?
147
148 // Read the "online_mode" flag from the command line
149 const int online_mode =
150 libMesh::command_line_next("-online_mode", 0);
151
152 // Create a mesh on the default MPI communicator.
153 Mesh mesh(init.comm(), dim);
154 mesh.read("horn.msh");
155
156 // Create an equation systems object.
157 EquationSystems equation_systems (mesh);
158
159 // We override RBConstruction with SimpleRBConstruction in order to
160 // specialize a few functions for this particular problem.
161 SimpleRBConstruction & rb_con =
162 equation_systems.add_system<SimpleRBConstruction> ("Acoustics");
163
164 // Initialize the data structures for the equation system.
165 equation_systems.init ();
166
167 // Print out some information about the "truth" discretization
168 equation_systems.print_info();
170
171 // Build a new RBEvaluation object which will be used to perform
172 // Reduced Basis calculations. This is required in both the
173 // "Offline" and "Online" stages.
174 SimpleRBEvaluation rb_eval(mesh.comm());
175
176 // We need to give the RBConstruction object a pointer to
177 // our RBEvaluation object
178 rb_con.set_rb_evaluation(rb_eval);
179
180 if (!online_mode) // Perform the Offline stage of the RB method
181 {
182 // Read in the data that defines this problem from the specified text file
183 rb_con.process_parameters_file(parameters_filename);
184
185 // Print out info that describes the current setup of rb_con
186 rb_con.print_info();
187
188 // Prepare rb_con for the Construction stage of the RB method.
189 // This sets up the necessary data structures and performs
190 // initial assembly of the "truth" affine expansion of the PDE.
192
193 // Compute the reduced basis space by computing "snapshots", i.e.
194 // "truth" solves, at well-chosen parameter values and employing
195 // these snapshots as basis functions.
196 libmesh_try
197 {
198 rb_con.train_reduced_basis();
199 }
200 libmesh_catch (LogicError & e)
201 {
202 libMesh::err << "\n\n"
203 << "********************************************************************************\n"
204 << "Training reduced basis failed, this example requires a direct solver.\n"
205 << "Try running with -ksp_type preonly -pc_type lu instead.\n"
206 << "********************************************************************************"
207 << std::endl;
208 return 77;
209 }
210
211 // Write out the data that will subsequently be required for the Evaluation stage
212#if defined(LIBMESH_HAVE_CAPNPROTO)
214 rb_eval_writer.write_to_file("rb_eval.bin");
215#else
217#endif
218
219 // If requested, write out the RB basis functions for visualization purposes
220 if (store_basis_functions)
221 {
222 // Write out the basis functions
224 }
225
226 // Basis functions should be orthonormal, so
227 // print out the inner products to check this
229 }
230 else // Perform the Online stage of the RB method
231 {
232 // Read in the reduced basis data
233#if defined(LIBMESH_HAVE_CAPNPROTO)
235 rb_eval_reader.read_from_file("rb_eval.bin", /*read_error_bound_data*/ true);
236#else
238#endif
239
240 // Read in online_N and initialize online parameters
241 Real online_frequency = infile("online_frequency", 0.);
242 RBParameters online_mu;
243 online_mu.set_value("frequency", online_frequency);
244 rb_eval.set_parameters(online_mu);
245 rb_eval.print_parameters();
246
247 // Now do the Online solve using the precomputed reduced basis
248 rb_eval.rb_solve(rb_eval.get_n_basis_functions());
249
250 if (store_basis_functions)
251 {
252 // Read in the basis functions
253 rb_eval.read_in_basis_functions(rb_con);
254
255 // Plot the solution
256 rb_con.load_rb_solution();
257
258 //Output the variable in ExodusII format (single precision)
259 ExodusII_IO(mesh, /*single_precision=*/true).write_equation_systems ("RB_sol_float.exo", equation_systems);
260 }
261
262 // Now do a sweep over frequencies and write out the reflection coefficient for each frequency
263 std::ofstream reflection_coeffs_out("reflection_coefficients.dat");
264
265 Real n_frequencies = infile("n_frequencies", 0.);
266 Real delta_f = (rb_eval.get_parameter_max("frequency") - rb_eval.get_parameter_min("frequency")) / (n_frequencies-1);
267 for (unsigned int freq_i=0; freq_i<n_frequencies; freq_i++)
268 {
269 Real frequency = rb_eval.get_parameter_min("frequency") + freq_i * delta_f;
270 online_mu.set_value("frequency", frequency);
271 rb_eval.set_parameters(online_mu);
272 rb_eval.rb_solve(rb_eval.get_n_basis_functions());
273
274 Number complex_one(1., 0.);
275 reflection_coeffs_out << frequency << " " << std::abs(rb_eval.RB_outputs[0] - complex_one) << std::endl;
276 }
277 reflection_coeffs_out.close();
278
279 }
280
281#endif
282
283 return 0;
284}
unsigned int dim
This is the EquationSystems class.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
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
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false)=0
Interfaces for reading/writing a mesh to/from a file.
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
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
const Parallel::Communicator & comm() const
void print_basis_function_orthogonality() const
Print out a matrix that shows the orthogonality of the RB basis functions.
void set_rb_evaluation(RBEvaluation &rb_eval_in)
Set the RBEvaluation object.
virtual void print_info() const
Print out info that describes the current setup of this RBConstruction.
RBEvaluation & get_rb_evaluation()
Get a reference to the RBEvaluation object.
virtual void initialize_rb_construction(bool skip_matrix_assembly=false, bool skip_vector_assembly=false)
Allocate all the data structures necessary for the construction stage of the RB method.
virtual Real train_reduced_basis(const bool resize_rb_eval_data=true)
Train the reduced basis.
virtual void load_rb_solution()
Load the RB solution from the most recent solve with rb_eval into this system's solution vector.
virtual void process_parameters_file(const std::string &parameters_filename)
Read in from the file specified by parameters_filename and set the this system's member variables acc...
This class de-serializes an RBEvaluation object using the Cap'n Proto library.
void read_from_file(const std::string &path, bool read_error_bound_data, bool use_packing=false)
Read the Cap'n'Proto buffer from disk.
This class serializes an RBEvaluation object using the Cap'n Proto library.
void write_to_file(const std::string &path, bool use_packing=false)
Write the Cap'n'Proto buffer to disk.
virtual void legacy_write_offline_data_to_files(const std::string &directory_name="offline_data", const bool write_binary_data=true)
Write out all the data to text files in order to segregate the Offline stage from the Online stage.
virtual Real rb_solve(unsigned int N)
Perform online solve with the N RB basis functions, for the set of parameters in current_params,...
virtual unsigned int get_n_basis_functions() const
Get the current number of basis functions.
std::vector< Number > RB_outputs
The vectors storing the RB output values and corresponding error bounds.
virtual void write_out_basis_functions(System &sys, const std::string &directory_name="offline_data", const bool write_binary_basis_functions=true)
Write out all the basis functions to file.
virtual void read_in_basis_functions(System &sys, const std::string &directory_name="offline_data", const bool read_binary_basis_functions=true)
Read in all the basis functions from file.
virtual void legacy_read_offline_data_from_files(const std::string &directory_name="offline_data", bool read_error_bound_data=true, const bool read_binary_data=true)
Read in the saved Offline reduced basis data to initialize the system for Online solves.
This class is part of the rbOOmit framework.
void set_value(const std::string &param_name, Real value)
Set the value of the specified parameter.
bool set_parameters(const RBParameters &params)
Set the current parameters to params The parameters are checked for validity; an error is thrown if t...
Real get_parameter_max(const std::string &param_name) const
Get maximum allowable value of parameter param_name.
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.
MeshBase & mesh
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err
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
int main()