GRINS-0.8.0
simulation.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // GRINS - General Reacting Incompressible Navier-Stokes
5 //
6 // Copyright (C) 2014-2017 Paul T. Bauman, Roy H. Stogner
7 // Copyright (C) 2010-2013 The PECOS Development Team
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the Version 2.1 GNU Lesser General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301 USA
22 //
23 //-----------------------------------------------------------------------el-
24 
25 
26 // This class
27 #include "grins/simulation.h"
28 
29 // GRINS
30 #include "grins/grins_enums.h"
32 #include "grins/multiphysics_sys.h"
33 #include "grins/solver_context.h"
36 #include "grins/physics_builder.h"
38 #include "grins/variable_builder.h"
40 #include "grins/solver_parsing.h"
41 
42 // libMesh
43 #include "libmesh/dof_map.h"
44 #include "libmesh/parameter_vector.h"
45 #include "libmesh/qoi_set.h"
46 #include "libmesh/sensitivity_data.h"
47 
48 namespace GRINS
49 {
50 
51  Simulation::Simulation( const GetPot& input,
52  SimulationBuilder& sim_builder,
53  const libMesh::Parallel::Communicator &comm )
54  : _mesh( sim_builder.build_mesh(input, comm) ),
55  _equation_system( new libMesh::EquationSystems( *_mesh ) ),
56  _system_name( input("screen-options/system_name", "GRINS" ) ),
57  _multiphysics_system( &(_equation_system->add_system<MultiphysicsSystem>( _system_name )) ),
58  _vis( sim_builder.build_vis(input, comm) ),
59  _postprocessing( sim_builder.build_postprocessing(input) ),
60  _print_mesh_info( input("screen-options/print_mesh_info", false ) ),
61  _print_log_info( input("screen-options/print_log_info", false ) ),
62  _print_equation_system_info( input("screen-options/print_equation_system_info", false ) ),
63  _print_constraint_info( input("screen-options/print_constraint_info", false ) ),
64  _print_scalars( input("screen-options/print_scalars", false ) ),
65  _qoi_output( new QoIOutput(input) ),
66  _output_vis( input("vis-options/output_vis", false ) ),
67  _output_adjoint( input("vis-options/output_adjoint", false ) ),
68  _output_residual( input( "vis-options/output_residual", false ) ),
69  _output_residual_sensitivities( input( "vis-options/output_residual_sensitivities", false ) ),
70  _output_solution_sensitivities( input( "vis-options/output_solution_sensitivities", false ) ),
71  _timesteps_per_vis( input("vis-options/timesteps_per_vis", 1 ) ),
72  _timesteps_per_perflog( input("screen-options/timesteps_per_perflog", 0 ) ),
73  _error_estimator_options(input),
74  _error_estimator(), // effectively NULL
75  _do_adjoint_solve(false), // Helper function will set final value
76  _have_restart(false)
77  {
78  libmesh_deprecated();
79 
80  this->build_solver(input);
81 
82  this->init_multiphysics_system(input);
83 
84  this->init_qois(input,sim_builder);
85 
86  this->init_params(input,sim_builder);
87 
88  this->init_adjoint_solve(input,_output_adjoint);
89 
90  // Must be called after setting QoI on the MultiphysicsSystem
91  this->build_error_estimator(input);
92 
94  this->init_restart(input,sim_builder,comm);
95  }
96 
97  Simulation::Simulation( const GetPot& input,
98  GetPot& /*command_line*/,
99  SimulationBuilder& sim_builder,
100  const libMesh::Parallel::Communicator &comm )
101  : _mesh( sim_builder.build_mesh(input, comm) ),
102  _equation_system( new libMesh::EquationSystems( *_mesh ) ),
103  _system_name( input("screen-options/system_name", "GRINS" ) ),
104  _multiphysics_system( &(_equation_system->add_system<MultiphysicsSystem>( _system_name )) ),
105  _vis( sim_builder.build_vis(input, comm) ),
106  _postprocessing( sim_builder.build_postprocessing(input) ),
107  _print_mesh_info( input("screen-options/print_mesh_info", false ) ),
108  _print_log_info( input("screen-options/print_log_info", false ) ),
109  _print_equation_system_info( input("screen-options/print_equation_system_info", false ) ),
110  _print_constraint_info( input("screen-options/print_constraint_info", false ) ),
111  _print_scalars( input("screen-options/print_scalars", false ) ),
112  _qoi_output( new QoIOutput(input) ),
113  _output_vis( input("vis-options/output_vis", false ) ),
114  _output_adjoint( input("vis-options/output_adjoint", false ) ),
115  _output_residual( input( "vis-options/output_residual", false ) ),
116  _output_residual_sensitivities( input( "vis-options/output_residual_sensitivities", false ) ),
117  _output_solution_sensitivities( input( "vis-options/output_solution_sensitivities", false ) ),
118  _timesteps_per_vis( input("vis-options/timesteps_per_vis", 1 ) ),
119  _timesteps_per_perflog( input("screen-options/timesteps_per_perflog", 0 ) ),
120  _error_estimator_options(input),
121  _error_estimator(), // effectively NULL
122  _do_adjoint_solve(false), // Helper function will set final value
123  _have_restart(false)
124  {
125  this->build_solver(input);
126 
127  this->init_multiphysics_system(input);
128 
129  this->init_qois(input,sim_builder);
130 
131  this->init_params(input,sim_builder);
132 
133  this->init_adjoint_solve(input,_output_adjoint);
134 
135  // Must be called after setting QoI on the MultiphysicsSystem
136  this->build_error_estimator(input);
137 
139  this->init_restart(input,sim_builder,comm);
140  }
141 
142  void Simulation::init_multiphysics_system( const GetPot& input )
143  {
144  // Only print libMesh logging info if the user requests it
145  libMesh::perflog.disable_logging();
146  if( this->_print_log_info ) libMesh::perflog.enable_logging();
147 
149 
150  PhysicsList physics_list = PhysicsBuilder::build_physics_map(input);
151 
152  _multiphysics_system->attach_physics_list( physics_list );
153 
155 
157 
158  /* Postprocessing needs to be initialized before the solver since that's
159  where equation_system gets init'ed */
161 
162  _solver->initialize( input, _equation_system, _multiphysics_system );
163 
164  // Useful for debugging
165  if( input("screen-options/print_dof_constraints", false ) )
166  {
167  _multiphysics_system->get_dof_map().print_dof_constraints();
168  }
169 
170  // This *must* be done after equation_system->init in order to get variable indices
171  // Set any extra quadrature order the user requested. By default, is 0.
172  _multiphysics_system->extra_quadrature_order = StrategiesParsing::extra_quadrature_order(input);
173 
174  if (input("Strategies/MeshAdaptivity/disable_two_step_refinement",false))
175  _equation_system->disable_refine_in_reinit();
176  }
177 
178  void Simulation::init_qois( const GetPot& input, SimulationBuilder& sim_builder )
179  {
180  // If the user actually asks for a QoI, then we add it.
181  SharedPtr<CompositeQoI> qois = sim_builder.build_qoi( input );
182  if( qois->n_qois() > 0 )
183  {
184  // This *must* be done after equation_system->init in order to get variable indices
185  qois->init(input, *_multiphysics_system );
186 
187  /* Note that we are effectively transfering ownership of the qoi pointer because
188  it will be cloned in _multiphysics_system and all the calculations are done there. */
189  _multiphysics_system->attach_qoi( qois.get() );
190  }
191  else if (_qoi_output->output_qoi_set())
192  {
193  std::cout << "Error: print_qoi is specified but\n" <<
194  "no QoIs have been specified.\n" << std::endl;
195  libmesh_error();
196  }
197  }
198 
199  void Simulation::init_params( const GetPot& input,
200  SimulationBuilder& /*sim_builder*/ )
201  {
202  unsigned int n_adjoint_parameters =
203  input.vector_variable_size("QoI/adjoint_sensitivity_parameters");
204 
205  unsigned int n_forward_parameters =
206  input.vector_variable_size("QoI/forward_sensitivity_parameters");
207 
208  // If the user actually asks for parameter sensitivities, then we
209  // set up the parameter vectors to use.
210  if ( n_adjoint_parameters )
211  {
212  // If we're doing adjoint sensitivities, dq/dp only makes
213  // sense if we have q
214  CompositeQoI* qoi =
215  libMesh::cast_ptr<CompositeQoI*>
216  (this->_multiphysics_system->get_qoi());
217 
218  if (!qoi)
219  {
220  std::cout <<
221  "Error: adjoint_sensitivity_parameters are specified but\n"
222  << "no QoIs have been specified.\n" << std::endl;
223  libmesh_error();
224  }
225 
227  (input, "QoI/adjoint_sensitivity_parameters",
228  *this->_multiphysics_system, qoi);
229  }
230 
231  if ( n_forward_parameters )
232  {
233  // If we're doing forward sensitivities, du/dp can make
234  // sense even with no q defined
235  CompositeQoI* qoi =
236  dynamic_cast<CompositeQoI*>
237  (this->_multiphysics_system->get_qoi());
238 
239  // dynamic_cast returns NULL if our QoI isn't a CompositeQoI;
240  // i.e. if there were no QoIs that made us bother setting up
241  // the CompositeQoI object. Passing NULL tells
242  // ParameterManager not to bother asking for qoi registration
243  // of parameters.
244 
246  (input, "QoI/forward_sensitivity_parameters",
247  *this->_multiphysics_system, qoi);
248  }
249  }
250 
251 
252  void Simulation::init_restart( const GetPot& input, SimulationBuilder& sim_builder,
253  const libMesh::Parallel::Communicator &comm )
254  {
255  this->read_restart( input );
256 
257  /* We do this here only if there's a restart file. Otherwise, this was done
258  at mesh construction time */
259  sim_builder.mesh_builder().do_mesh_refinement_from_input( input, comm, *_mesh );
260 
261  /* \todo Any way to tell if the mesh got refined so we don't unnecessarily
262  call reinit()? */
263  _equation_system->reinit();
264  }
265 
266 
268  {
269  this->print_sim_info();
270 
271  SolverContext context;
272  context.system = _multiphysics_system;
274  context.vis = _vis;
278  context.output_vis = _output_vis;
282  context.print_scalars = _print_scalars;
283  context.print_perflog = _print_log_info;
286  context.qoi_output = _qoi_output;
288  context.have_restart = _have_restart;
289 
292  {
293  std::cout <<
294  "Error: output_residual_sensitivities is specified but\n" <<
295  "no forward sensitivity parameters have been specified.\n" <<
296  std::endl;
297  libmesh_error();
298  }
299 
302  {
303  std::cout <<
304  "Error: output_solution_sensitivities is specified but\n" <<
305  "no forward sensitivity parameters have been specified.\n" <<
306  std::endl;
307  libmesh_error();
308  }
309 
310  _solver->solve( context );
311 
312  if (_qoi_output->output_qoi_set())
313  {
314  _multiphysics_system->assemble_qoi();
315  const CompositeQoI * my_qoi = libMesh::cast_ptr<const CompositeQoI*>(this->_multiphysics_system->get_qoi());
316  _qoi_output->output_qois(*my_qoi, this->_multiphysics_system->comm() );
317  }
318 
320  {
321  // Default: "calculate sensitivities for all QoIs"
322  libMesh::QoISet qois;
323 
324  const libMesh::ParameterVector & params =
326 
327  libMesh::SensitivityData sensitivities
328  (qois, *this->_multiphysics_system, params);
329 
330  _solver->adjoint_qoi_parameter_sensitivity
331  (context, qois, params, sensitivities);
332 
333  std::cout << "Adjoint sensitivities:" << std::endl;
334 
335  for (unsigned int q=0;
336  q != this->_multiphysics_system->qoi.size(); ++q)
337  {
338  for (unsigned int p=0; p != params.size(); ++p)
339  {
340  std::cout << "dq" << q << "/dp" << p << " = " <<
341  sensitivities[q][p] << std::endl;
342  }
343  }
344  }
345 
347  {
348  // Default: "calculate sensitivities for all QoIs"
349  libMesh::QoISet qois;
350 
351  const libMesh::ParameterVector & params =
353 
354  libMesh::SensitivityData sensitivities
355  (qois, *this->_multiphysics_system, params);
356 
357  _solver->forward_qoi_parameter_sensitivity
358  (context, qois, params, sensitivities);
359 
360  std::cout << "Forward sensitivities:" << std::endl;
361 
362  for (unsigned int q=0;
363  q != this->_multiphysics_system->qoi.size(); ++q)
364  {
365  for (unsigned int p=0; p != params.size(); ++p)
366  {
367  std::cout << "dq" << q << "/dp" << p << " = " <<
368  sensitivities[q][p] << std::endl;
369  }
370  }
371  }
372 
373  return;
374  }
375 
377  {
378  // Print mesh info if the user wants it
379  if( this->_print_mesh_info )
380  this->_mesh->print_info();
381 
382  // Print EquationSystems info if requested
383  if( this->_print_equation_system_info )
384  this->_equation_system->print_info();
385 
386  // Print DofMap constraint info if requested
387  if( this->_print_constraint_info )
388  this->_multiphysics_system->get_dof_map().print_dof_constraints();
389 
390  return;
391  }
392 
393  SharedPtr<libMesh::EquationSystems> Simulation::get_equation_system()
394  {
395  return _equation_system;
396  }
397 
398  libMesh::Number Simulation::get_qoi_value( unsigned int qoi_index ) const
399  {
400  const CompositeQoI* qoi = libMesh::cast_ptr<const CompositeQoI*>(this->_multiphysics_system->get_qoi());
401  return qoi->get_qoi_value(qoi_index);
402  }
403 
404  void Simulation::read_restart( const GetPot& input )
405  {
406  const std::string restart_file = SimulationParsing::restart_file(input);
407 
408  // Most of this was pulled from FIN-S
409  if (restart_file != "none")
410  {
411  std::cout << " ====== Restarting from " << restart_file << std::endl;
412 
413  // Must have correct file type to restart
414  if (restart_file.rfind(".xdr") < restart_file.size())
415  _equation_system->read(restart_file,GRINSEnums::DECODE,
416  //libMesh::EquationSystems::READ_HEADER | // Allow for thermochemistry upgrades
417  libMesh::EquationSystems::READ_DATA |
418  libMesh::EquationSystems::READ_ADDITIONAL_DATA);
419 
420  else if (restart_file.rfind(".xda") < restart_file.size())
421  _equation_system->read(restart_file,GRINSEnums::READ,
422  //libMesh::EquationSystems::READ_HEADER | // Allow for thermochemistry upgrades
423  libMesh::EquationSystems::READ_DATA |
424  libMesh::EquationSystems::READ_ADDITIONAL_DATA);
425 
426  else
427  {
428  std::cerr << "Error: Restart filename must have .xdr or .xda extension!" << std::endl;
429  libmesh_error();
430  }
431 
432  this->_have_restart = true;
433 
434  const std::string system_name = input("screen-options/system_name", "GRINS" );
435 
436  MultiphysicsSystem& system =
437  _equation_system->get_system<MultiphysicsSystem>(system_name);
438 
439  // Update the old data
440  system.update();
441  }
442 
443  return;
444  }
445 
446  void Simulation::init_adjoint_solve( const GetPot& input, bool output_adjoint )
447  {
448  // Check if we're doing an adjoint solve
450 
451  const libMesh::DifferentiableQoI* raw_qoi = _multiphysics_system->get_qoi();
452  const CompositeQoI* qoi = dynamic_cast<const CompositeQoI*>( raw_qoi );
453 
454  // If we are trying to do an adjoint solve without a QoI, that's an error
455  // If there are no QoIs, the CompositeQoI never gets built and qoi will be NULL
456  if( _do_adjoint_solve && !qoi )
457  {
458  libmesh_error_msg("Error: Adjoint solve requested, but no QoIs detected.");
459  }
460 
461  /* If we are not doing an adjoint solve, but adjoint output was requested:
462  that's an error. */
463  if( !_do_adjoint_solve && output_adjoint )
464  {
465  libmesh_error_msg("Error: Adjoint output requested, but no adjoint solve requested.");
466  }
467  }
468 
469  bool Simulation::check_for_adjoint_solve( const GetPot& input ) const
470  {
471  std::string error_estimator = _error_estimator_options.estimator_type();
472 
473  bool do_adjoint_solve = false;
474 
475  // First check if the error estimator requires an adjoint solve
477  do_adjoint_solve = true;
478 
479  // Next check if parameter sensitivies require an adjoint solve
481  do_adjoint_solve = true;
482 
483  // Now check if the user requested to do an adjoint solve regardless
486  do_adjoint_solve = true;
487 
488  return do_adjoint_solve;
489  }
490 
491  void Simulation::build_error_estimator(const GetPot& input)
492  {
493  std::string estimator_type = _error_estimator_options.estimator_type();
494  if( estimator_type != std::string("none") )
495  {
499  _error_estimator.reset( (ErrorEstimatorFactoryBase::build(estimator_type)).release() );
500  }
501  }
502 
503  void Simulation::build_solver(const GetPot& input)
504  {
506 
507  std::string solver_name = SolverParsing::solver_type(input);
508 
509  _solver = SolverFactoryAbstract::build(solver_name);
510  }
511 
512 } // namespace GRINS
static PhysicsList build_physics_map(const GetPot &input)
Returns container of constructed Physics objects.
static bool do_adjoint_solve(const GetPot &input)
Option to let user manually trigger adjoint solve.
void attach_physics_list(PhysicsList physics_list)
PhysicsList gets built by GRINS::PhysicsFactory and attached here.
void read_restart(const GetPot &input)
Definition: simulation.C:404
static void set_estimator_options(const ErrorEstimatorOptions &estimator_options)
SharedPtr< libMesh::EquationSystems > equation_system
SharedPtr< libMesh::EquationSystems > get_equation_system()
Definition: simulation.C:393
const std::string & estimator_type() const
void register_postprocessing_vars(const GetPot &input, PostProcessedQuantities< libMesh::Real > &postprocessing)
Each Physics will register their postprocessed quantities with this call.
void init_multiphysics_system(const GetPot &input)
Helper function.
Definition: simulation.C:142
ParameterManager _forward_parameters
Definition: simulation.h:157
static std::string solver_type(const GetPot &input)
SharedPtr< PostProcessedQuantities< libMesh::Real > > postprocessing
void init_params(const GetPot &input, SimulationBuilder &sim_builder)
Helper function.
Definition: simulation.C:199
unsigned int _timesteps_per_vis
Definition: simulation.h:149
static bool have_restart(const GetPot &input)
SharedPtr< PostProcessedQuantities< libMesh::Real > > _postprocessing
Definition: simulation.h:129
static libMesh::UniquePtr< libMesh::ErrorEstimator > build(const std::string &name)
Use this method to build objects of type Base.
SharedPtr< libMesh::ErrorEstimator > error_estimator
SharedPtr< CompositeQoI > build_qoi(const GetPot &input)
GRINS namespace.
bool _print_constraint_info
Definition: simulation.h:135
unsigned int timesteps_per_perflog
void build_error_estimator(const GetPot &input)
Definition: simulation.C:491
static int extra_quadrature_order(const GetPot &input)
SharedPtr< QoIOutput > _qoi_output
Definition: simulation.h:140
SharedPtr< libMesh::ErrorEstimator > _error_estimator
Definition: simulation.h:153
bool _print_equation_system_info
Definition: simulation.h:134
libMesh::Number get_qoi_value(unsigned int qoi_index) const
Definition: simulation.C:398
SharedPtr< QoIOutput > qoi_output
const MeshBuilder & mesh_builder() const
unsigned int timesteps_per_vis
static void build_variables(const GetPot &input, MultiphysicsSystem &system)
static void set_system(MultiphysicsSystem &system)
libMesh::ParameterVector parameter_vector
void init_adjoint_solve(const GetPot &input, bool output_adjoint)
Helper function.
Definition: simulation.C:446
libMesh::UniquePtr< GRINS::Solver > _solver
Definition: simulation.h:119
GRINS::MultiphysicsSystem * system
SharedPtr< GRINS::Visualization > vis
void init_qois(const GetPot &input, SimulationBuilder &sim_builder)
Helper function.
Definition: simulation.C:178
void build_solver(const GetPot &input)
Definition: simulation.C:503
Interface with libMesh for solving Multiphysics problems.
ParameterManager _adjoint_parameters
Definition: simulation.h:155
std::map< std::string, SharedPtr< GRINS::Physics > > PhysicsList
Container for GRINS::Physics object pointers.
Definition: var_typedefs.h:59
bool _output_residual_sensitivities
Definition: simulation.h:146
bool _output_solution_sensitivities
Definition: simulation.h:147
ErrorEstimatorOptions _error_estimator_options
Definition: simulation.h:152
static std::string restart_file(const GetPot &input)
void init_restart(const GetPot &input, SimulationBuilder &sim_builder, const libMesh::Parallel::Communicator &comm)
Helper function.
Definition: simulation.C:252
Simple class to hold objects passed to Solver::solve.
SharedPtr< libMesh::UnstructuredMesh > _mesh
Definition: simulation.h:115
GRINS::MultiphysicsSystem * _multiphysics_system
Definition: simulation.h:125
unsigned int _timesteps_per_perflog
Definition: simulation.h:150
void do_mesh_refinement_from_input(const GetPot &input, const libMesh::Parallel::Communicator &comm, libMesh::UnstructuredMesh &mesh) const
Refine the mesh based on user input parameters.
Definition: mesh_builder.C:355
SharedPtr< GRINS::Visualization > _vis
Definition: simulation.h:127
virtual void read_input_options(const GetPot &input)
Reads input options for this class and all physics that are enabled.
libMesh::Number get_qoi_value(unsigned int qoi_index) const
Accessor for value of QoI for given qoi_index.
void print_sim_info()
Definition: simulation.C:376
virtual void initialize(const GetPot &input, const std::string &parameters_varname, GRINS::MultiphysicsSystem &system, GRINS::CompositeQoI *qoi)
bool check_for_adjoint_solve(const GetPot &input) const
Helper function.
Definition: simulation.C:469
SharedPtr< libMesh::EquationSystems > _equation_system
Definition: simulation.h:117

Generated on Tue Dec 19 2017 12:47:28 for GRINS-0.8.0 by  doxygen 1.8.9.1