libMesh
reduced_basis_ex7.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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
61 using namespace libMesh;
62 
63 // The main program.
64 int 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 #if 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 #else
102  if (input.search("-pc_factor_mat_solver_package"))
103  {
104  libMesh::out << "LibMesh was configured with PETSc >= 3.9, but command-line options "
105  << "use deprecated syntax. Skipping now."
106  << std::endl;
107  return 77;
108  }
109 #endif
110 
111  // check that we have the required solver:
112  std::string solver;
113  solver = input.next(solver);
114  if (solver == "mumps")
115  {
116 #ifndef LIBMESH_PETSC_HAVE_MUMPS
117  libmesh_example_requires(false, "PETSc compiled with MUMPS support");
118 #endif
119  }
120  else if (solver == "superlu")
121  {
122 #ifndef LIBMESH_PETSC_HAVE_SUPERLU_DIST
123  libmesh_example_requires(false, "PETSc compiled with SuperLU support");
124 #endif
125  }
126  else
127  {
128  libMesh::err << "Error: Solver " << solver << " is unknown."
129  << std::endl;
130  return 1;
131  }
132 
133 #endif //LIBMESH_HAVE_PETSC
134 
135  // Skip this 2D example if libMesh was compiled as 1D-only.
136  libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
137 
138  // Parse the input file (reduced_basis_ex7.in) using GetPot
139  std::string parameters_filename = "reduced_basis_ex7.in";
140  GetPot infile(parameters_filename);
141 
142  const unsigned int dim = 2; // The number of spatial dimensions
143 
144  bool store_basis_functions = infile("store_basis_functions", true); // Do we write the RB basis functions to disk?
145 
146  // Read the "online_mode" flag from the command line
147  GetPot command_line (argc, argv);
148  int online_mode = 0;
149  if (command_line.search(1, "-online_mode"))
150  online_mode = command_line.next(online_mode);
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();
169  mesh.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
237  rb_eval.legacy_read_offline_data_from_files();
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 }
SimpleRBConstruction
Definition: rb_classes.h:73
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::Mesh
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
libMesh::EquationSystems::add_system
virtual System & add_system(const std::string &system_type, const std::string &name)
Add the system of type system_type named name to the systems array.
Definition: equation_systems.C:345
libMesh::MeshBase::read
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false)=0
Interfaces for reading/writing a mesh to/from a file.
libMesh::PETSC_SOLVERS
Definition: enum_solver_package.h:36
libMesh::RBConstruction::process_parameters_file
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...
Definition: rb_construction.C:193
libMesh::RBEvaluation::write_out_basis_functions
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.
Definition: rb_evaluation.C:880
libMesh::RBConstruction::initialize_rb_construction
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.
Definition: rb_construction.C:419
libMesh::RBConstruction::set_rb_evaluation
void set_rb_evaluation(RBEvaluation &rb_eval_in)
Set the RBEvaluation object.
Definition: rb_construction.C:170
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::LogicError
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
Definition: libmesh_exceptions.h:38
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
main
int main(int argc, char **argv)
Definition: reduced_basis_ex7.C:64
libMesh::RBParameters
This class is part of the rbOOmit framework.
Definition: rb_parameters.h:42
libMesh::RBDataSerialization::RBEvaluationSerialization
This class serializes an RBEvaluation object using the Cap'n Proto library.
Definition: rb_data_serialization.h:58
libMesh::default_solver_package
SolverPackage default_solver_package()
Definition: libmesh.C:993
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::ExodusII_IO
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:51
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::TriangleWrapper::init
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
libMesh::RBConstruction::print_basis_function_orthogonality
void print_basis_function_orthogonality()
Print out a matrix that shows the orthogonality of the RB basis functions.
Definition: rb_construction.C:348
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file
void write_to_file(const std::string &path)
Write the Cap'n'Proto buffer to disk.
Definition: rb_data_serialization.C:82
libMesh::EquationSystems::init
virtual void init()
Initialize all the systems.
Definition: equation_systems.C:96
libMesh::RBConstruction::get_rb_evaluation
RBEvaluation & get_rb_evaluation()
Get a reference to the RBEvaluation object.
Definition: rb_construction.C:175
libMesh::RBParameters::set_value
void set_value(const std::string &param_name, Real value)
Set the value of the specified parameter.
Definition: rb_parameters.C:47
libMesh::LibMeshInit
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:83
libMesh::EquationSystems::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
Definition: equation_systems.C:1314
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::MeshOutput::write_equation_systems
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
libMesh::RBConstruction::print_info
virtual void print_info()
Print out info that describes the current setup of this RBConstruction.
Definition: rb_construction.C:312
libMesh::RBEvaluation::legacy_write_offline_data_to_files
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.
Definition: rb_evaluation.C:416
SimpleRBEvaluation
Definition: rb_classes.h:45
libMesh::MeshBase::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
Definition: mesh_base.C:585
libMesh::RBConstruction::load_rb_solution
virtual void load_rb_solution()
Load the RB solution from the most recent solve with rb_eval into this system's solution vector.
Definition: rb_construction.C:1800
libMesh::RBDataDeserialization::RBEvaluationDeserialization
This class de-serializes an RBEvaluation object using the Cap'n Proto library.
Definition: rb_data_deserialization.h:60
libMesh::RBDataDeserialization::RBEvaluationDeserialization::read_from_file
void read_from_file(const std::string &path, bool read_error_bound_data)
Write the Cap'n'Proto buffer to disk.
Definition: rb_data_deserialization.C:78
libMesh::err
OStreamProxy err
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::out
OStreamProxy out
libMesh::RBConstruction::train_reduced_basis
virtual Real train_reduced_basis(const bool resize_rb_eval_data=true)
Train the reduced basis.
Definition: rb_construction.C:1024