GRINS-0.6.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-2015 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"
34 
35 // libMesh
36 #include "libmesh/dof_map.h"
37 #include "libmesh/parameter_vector.h"
38 #include "libmesh/qoi_set.h"
39 #include "libmesh/sensitivity_data.h"
40 
41 namespace GRINS
42 {
43 
44  Simulation::Simulation( const GetPot& input,
45  SimulationBuilder& sim_builder,
46  const libMesh::Parallel::Communicator &comm )
47  : _mesh( sim_builder.build_mesh(input, comm) ),
48  _equation_system( new libMesh::EquationSystems( *_mesh ) ),
49  _solver( sim_builder.build_solver(input) ),
50  _system_name( input("screen-options/system_name", "GRINS" ) ),
51  _multiphysics_system( &(_equation_system->add_system<MultiphysicsSystem>( _system_name )) ),
52  _vis( sim_builder.build_vis(input, comm) ),
53  _postprocessing( sim_builder.build_postprocessing(input) ),
54  _print_mesh_info( input("screen-options/print_mesh_info", false ) ),
55  _print_log_info( input("screen-options/print_log_info", false ) ),
56  _print_equation_system_info( input("screen-options/print_equation_system_info", false ) ),
57  _print_qoi( input("screen-options/print_qoi", false ) ),
58  _print_scalars( input("screen-options/print_scalars", false ) ),
59  _output_vis( input("vis-options/output_vis", false ) ),
60  _output_adjoint( input("vis-options/output_adjoint", false ) ),
61  _output_residual( input( "vis-options/output_residual", false ) ),
62  _output_residual_sensitivities( input( "vis-options/output_residual_sensitivities", false ) ),
63  _output_solution_sensitivities( input( "vis-options/output_solution_sensitivities", false ) ),
64  _timesteps_per_vis( input("vis-options/timesteps_per_vis", 1 ) ),
65  _timesteps_per_perflog( input("screen-options/timesteps_per_perflog", 0 ) ),
66  _error_estimator(), // effectively NULL
67  _do_adjoint_solve(false) // Helper function will set final value
68  {
69  libmesh_deprecated();
70 
71  this->init_multiphysics_system(input,sim_builder);
72 
73  this->init_qois(input,sim_builder);
74 
75  this->init_params(input,sim_builder);
76 
77  this->init_adjoint_solve(input,_output_adjoint);
78 
79  // Must be called after setting QoI on the MultiphysicsSystem
80  _error_estimator = sim_builder.build_error_estimator( input, libMesh::QoISet(*_multiphysics_system) );
81 
82  if( input.have_variable("restart-options/restart_file") )
83  {
84  this->init_restart(input,sim_builder,comm);
85  }
86 
87  this->check_for_unused_vars(input, false /*warning only*/);
88 
89  return;
90  }
91 
92  Simulation::Simulation( const GetPot& input,
93  GetPot& command_line,
94  SimulationBuilder& sim_builder,
95  const libMesh::Parallel::Communicator &comm )
96  : _mesh( sim_builder.build_mesh(input, comm) ),
97  _equation_system( new libMesh::EquationSystems( *_mesh ) ),
98  _solver( sim_builder.build_solver(input) ),
99  _system_name( input("screen-options/system_name", "GRINS" ) ),
100  _multiphysics_system( &(_equation_system->add_system<MultiphysicsSystem>( _system_name )) ),
101  _vis( sim_builder.build_vis(input, comm) ),
102  _postprocessing( sim_builder.build_postprocessing(input) ),
103  _print_mesh_info( input("screen-options/print_mesh_info", false ) ),
104  _print_log_info( input("screen-options/print_log_info", false ) ),
105  _print_equation_system_info( input("screen-options/print_equation_system_info", false ) ),
106  _print_qoi( input("screen-options/print_qoi", false ) ),
107  _print_scalars( input("screen-options/print_scalars", false ) ),
108  _output_vis( input("vis-options/output_vis", false ) ),
109  _output_adjoint( input("vis-options/output_adjoint", false ) ),
110  _output_residual( input( "vis-options/output_residual", false ) ),
111  _output_residual_sensitivities( input( "vis-options/output_residual_sensitivities", false ) ),
112  _output_solution_sensitivities( input( "vis-options/output_solution_sensitivities", false ) ),
113  _timesteps_per_vis( input("vis-options/timesteps_per_vis", 1 ) ),
114  _timesteps_per_perflog( input("screen-options/timesteps_per_perflog", 0 ) ),
115  _error_estimator(), // effectively NULL
116  _do_adjoint_solve(false) // Helper function will set final value
117  {
118  this->init_multiphysics_system(input,sim_builder);
119 
120  this->init_qois(input,sim_builder);
121 
122  this->init_params(input,sim_builder);
123 
124  this->init_adjoint_solve(input,_output_adjoint);
125 
126  // Must be called after setting QoI on the MultiphysicsSystem
127  _error_estimator = sim_builder.build_error_estimator( input, libMesh::QoISet(*_multiphysics_system) );
128 
129  if( input.have_variable("restart-options/restart_file") )
130  {
131  this->init_restart(input,sim_builder,comm);
132  }
133 
134  bool warning_only = command_line.search("--warn-only-unused-var");
135  this->check_for_unused_vars(input, warning_only );
136 
137  return;
138  }
139 
141  {
142  return;
143  }
144 
145  void Simulation::init_multiphysics_system( const GetPot& input,
146  SimulationBuilder& sim_builder )
147  {
148  // Only print libMesh logging info if the user requests it
149  libMesh::perflog.disable_logging();
150  if( this->_print_log_info ) libMesh::perflog.enable_logging();
151 
152  PhysicsList physics_list = sim_builder.build_physics(input);
153 
154  _multiphysics_system->attach_physics_list( physics_list );
155 
157 
159 
160  // This *must* be done before equation_system->init
162 
163  /* Postprocessing needs to be initialized before the solver since that's
164  where equation_system gets init'ed */
166 
167  _solver->initialize( input, _equation_system, _multiphysics_system );
168 
169  // Useful for debugging
170  if( input("screen-options/print_dof_constraints", false ) )
171  {
172  _multiphysics_system->get_dof_map().print_dof_constraints();
173  }
174 
175  // This *must* be done after equation_system->init in order to get variable indices
177 
178  return;
179  }
180 
181  void Simulation::init_qois( const GetPot& input, SimulationBuilder& sim_builder )
182  {
183  // If the user actually asks for a QoI, then we add it.
184  std::tr1::shared_ptr<CompositeQoI> qois = sim_builder.build_qoi( input );
185  if( qois->n_qois() > 0 )
186  {
187  // This *must* be done after equation_system->init in order to get variable indices
188  qois->init(input, *_multiphysics_system );
189 
190  /* Note that we are effectively transfering ownership of the qoi pointer because
191  it will be cloned in _multiphysics_system and all the calculations are done there. */
192  _multiphysics_system->attach_qoi( qois.get() );
193  }
194  else if (_print_qoi)
195  {
196  std::cout << "Error: print_qoi is specified but\n" <<
197  "no QoIs have been specified.\n" << std::endl;
198  libmesh_error();
199  }
200 
201  return;
202  }
203 
204  void Simulation::init_params( const GetPot& input,
205  SimulationBuilder& /*sim_builder*/ )
206  {
207  unsigned int n_adjoint_parameters =
208  input.vector_variable_size("QoI/adjoint_sensitivity_parameters");
209 
210  unsigned int n_forward_parameters =
211  input.vector_variable_size("QoI/forward_sensitivity_parameters");
212 
213  // If the user actually asks for parameter sensitivities, then we
214  // set up the parameter vectors to use.
215  if ( n_adjoint_parameters )
216  {
217  // If we're doing adjoint sensitivities, dq/dp only makes
218  // sense if we have q
219  CompositeQoI* qoi =
220  libMesh::cast_ptr<CompositeQoI*>
221  (this->_multiphysics_system->get_qoi());
222 
223  if (!qoi)
224  {
225  std::cout <<
226  "Error: adjoint_sensitivity_parameters are specified but\n"
227  << "no QoIs have been specified.\n" << std::endl;
228  libmesh_error();
229  }
230 
232  (input, "QoI/adjoint_sensitivity_parameters",
233  *this->_multiphysics_system, qoi);
234  }
235 
236  if ( n_forward_parameters )
237  {
238  // If we're doing forward sensitivities, du/dp can make
239  // sense even with no q defined
240  CompositeQoI* qoi =
241  dynamic_cast<CompositeQoI*>
242  (this->_multiphysics_system->get_qoi());
243 
244  // dynamic_cast returns NULL if our QoI isn't a CompositeQoI;
245  // i.e. if there were no QoIs that made us bother setting up
246  // the CompositeQoI object. Passing NULL tells
247  // ParameterManager not to bother asking for qoi registration
248  // of parameters.
249 
251  (input, "QoI/forward_sensitivity_parameters",
252  *this->_multiphysics_system, qoi);
253  }
254  }
255 
256 
257  void Simulation::init_restart( const GetPot& input, SimulationBuilder& sim_builder,
258  const libMesh::Parallel::Communicator &comm )
259  {
260  this->read_restart( input );
261 
262  /* We do this here only if there's a restart file. Otherwise, this was done
263  at mesh construction time */
264  sim_builder.mesh_builder().do_mesh_refinement_from_input( input, comm, *_mesh );
265 
266  /* \todo Any way to tell if the mesh got refined so we don't unnecessarily
267  call reinit()? */
268  _equation_system->reinit();
269 
270  return;
271  }
272 
273  void Simulation::check_for_unused_vars( const GetPot& input, bool warning_only )
274  {
275  /* Everything should be set up now, so check if there's any unused variables
276  in the input file. If so, then tell the user what they were and error out. */
277  std::vector<std::string> unused_vars = input.unidentified_variables();
278 
279  if( !unused_vars.empty() )
280  {
281  libMesh::err << "==========================================================" << std::endl;
282  if( warning_only )
283  libMesh::err << "Warning: ";
284  else
285  libMesh::err << "Error: ";
286 
287  libMesh::err << "Found unused variables!" << std::endl;
288 
289  for( std::vector<std::string>::const_iterator it = unused_vars.begin();
290  it != unused_vars.end(); ++it )
291  {
292  libMesh::err << *it << std::endl;
293  }
294  libMesh::err << "==========================================================" << std::endl;
295 
296  if( !warning_only )
297  libmesh_error();
298  }
299 
300  return;
301  }
302 
304  {
305  this->print_sim_info();
306 
307  SolverContext context;
308  context.system = _multiphysics_system;
310  context.vis = _vis;
314  context.output_vis = _output_vis;
318  context.print_scalars = _print_scalars;
319  context.print_perflog = _print_log_info;
322  context.print_qoi = _print_qoi;
324 
327  {
328  std::cout <<
329  "Error: output_residual_sensitivities is specified but\n" <<
330  "no forward sensitivity parameters have been specified.\n" <<
331  std::endl;
332  libmesh_error();
333  }
334 
337  {
338  std::cout <<
339  "Error: output_solution_sensitivities is specified but\n" <<
340  "no forward sensitivity parameters have been specified.\n" <<
341  std::endl;
342  libmesh_error();
343  }
344 
345  _solver->solve( context );
346 
347  if ( this->_print_qoi )
348  {
349  _multiphysics_system->assemble_qoi();
350  const CompositeQoI* my_qoi = libMesh::libmesh_cast_ptr<const CompositeQoI*>(this->_multiphysics_system->get_qoi());
351  my_qoi->output_qoi( std::cout );
352  }
353 
355  {
356  // Default: "calculate sensitivities for all QoIs"
357  libMesh::QoISet qois;
358 
359  const libMesh::ParameterVector & params =
361 
362  libMesh::SensitivityData sensitivities
363  (qois, *this->_multiphysics_system, params);
364 
365  _solver->adjoint_qoi_parameter_sensitivity
366  (context, qois, params, sensitivities);
367 
368  std::cout << "Adjoint sensitivities:" << std::endl;
369 
370  for (unsigned int q=0;
371  q != this->_multiphysics_system->qoi.size(); ++q)
372  {
373  for (unsigned int p=0; p != params.size(); ++p)
374  {
375  std::cout << "dq" << q << "/dp" << p << " = " <<
376  sensitivities[q][p] << std::endl;
377  }
378  }
379  }
380 
382  {
383  // Default: "calculate sensitivities for all QoIs"
384  libMesh::QoISet qois;
385 
386  const libMesh::ParameterVector & params =
388 
389  libMesh::SensitivityData sensitivities
390  (qois, *this->_multiphysics_system, params);
391 
392  _solver->forward_qoi_parameter_sensitivity
393  (context, qois, params, sensitivities);
394 
395  std::cout << "Forward sensitivities:" << std::endl;
396 
397  for (unsigned int q=0;
398  q != this->_multiphysics_system->qoi.size(); ++q)
399  {
400  for (unsigned int p=0; p != params.size(); ++p)
401  {
402  std::cout << "dq" << q << "/dp" << p << " = " <<
403  sensitivities[q][p] << std::endl;
404  }
405  }
406  }
407 
408  return;
409  }
410 
412  {
413  // Print mesh info if the user wants it
414  if( this->_print_mesh_info ) this->_mesh->print_info();
415 
416  // Print info if requested
417  if( this->_print_equation_system_info ) this->_equation_system->print_info();
418 
419  return;
420  }
421 
422  std::tr1::shared_ptr<libMesh::EquationSystems> Simulation::get_equation_system()
423  {
424  return _equation_system;
425  }
426 
427  libMesh::Number Simulation::get_qoi_value( unsigned int qoi_index ) const
428  {
429  const CompositeQoI* qoi = libMesh::libmesh_cast_ptr<const CompositeQoI*>(this->_multiphysics_system->get_qoi());
430  return qoi->get_qoi_value(qoi_index);
431  }
432 
433  void Simulation::read_restart( const GetPot& input )
434  {
435  const std::string restart_file = input( "restart-options/restart_file", "none" );
436 
437  // Most of this was pulled from FIN-S
438  if (restart_file != "none")
439  {
440  std::cout << " ====== Restarting from " << restart_file << std::endl;
441 
442  // Must have correct file type to restart
443  if (restart_file.rfind(".xdr") < restart_file.size())
444  _equation_system->read(restart_file,GRINSEnums::DECODE,
445  //libMesh::EquationSystems::READ_HEADER | // Allow for thermochemistry upgrades
446  libMesh::EquationSystems::READ_DATA |
447  libMesh::EquationSystems::READ_ADDITIONAL_DATA);
448 
449  else if (restart_file.rfind(".xda") < restart_file.size())
450  _equation_system->read(restart_file,GRINSEnums::READ,
451  //libMesh::EquationSystems::READ_HEADER | // Allow for thermochemistry upgrades
452  libMesh::EquationSystems::READ_DATA |
453  libMesh::EquationSystems::READ_ADDITIONAL_DATA);
454 
455  else
456  {
457  std::cerr << "Error: Restart filename must have .xdr or .xda extension!" << std::endl;
458  libmesh_error();
459  }
460 
461  const std::string system_name = input("screen-options/system_name", "GRINS" );
462 
463  MultiphysicsSystem& system =
464  _equation_system->get_system<MultiphysicsSystem>(system_name);
465 
466  // Update the old data
467  system.update();
468  }
469 
470  return;
471  }
472 
473  void Simulation::attach_neumann_bc_funcs( std::map< std::string, NBCContainer > neumann_bcs,
474  MultiphysicsSystem* system )
475  {
476  //_neumann_bc_funcs = neumann_bcs;
477 
478  if( neumann_bcs.size() > 0 )
479  {
480  for( std::map< std::string, NBCContainer >::iterator bc = neumann_bcs.begin();
481  bc != neumann_bcs.end();
482  bc++ )
483  {
484  std::tr1::shared_ptr<Physics> physics = system->get_physics( bc->first );
485  physics->attach_neumann_bound_func( bc->second );
486  }
487  }
488 
489  return;
490  }
491 
492  void Simulation::attach_dirichlet_bc_funcs( std::multimap< PhysicsName, DBCContainer > dbc_map,
493  MultiphysicsSystem* system )
494  {
495  for( std::multimap< PhysicsName, DBCContainer >::const_iterator it = dbc_map.begin();
496  it != dbc_map.end();
497  it++ )
498  {
499  std::tr1::shared_ptr<Physics> physics = system->get_physics( it->first );
500 
501  physics->attach_dirichlet_bound_func( it->second );
502  }
503  return;
504  }
505 
506  void Simulation::init_adjoint_solve( const GetPot& input, bool output_adjoint )
507  {
508  // Check if we're doing an adjoint solve
510 
511  const libMesh::DifferentiableQoI* raw_qoi = _multiphysics_system->get_qoi();
512  const CompositeQoI* qoi = dynamic_cast<const CompositeQoI*>( raw_qoi );
513 
514  // If we are trying to do an adjoint solve without a QoI, that's an error
515  // If there are no QoIs, the CompositeQoI never gets built and qoi will be NULL
516  if( _do_adjoint_solve && !qoi )
517  {
518  libmesh_error_msg("Error: Adjoint solve requested, but no QoIs detected.");
519  }
520 
521  /* If we are not doing an adjoint solve, but adjoint output was requested:
522  that's an error. */
523  if( !_do_adjoint_solve && output_adjoint )
524  {
525  libmesh_error_msg("Error: Adjoint output requested, but no adjoint solve requested.");
526  }
527  }
528 
529  bool Simulation::check_for_adjoint_solve( const GetPot& input ) const
530  {
532  std::string error_estimator = input("MeshAdaptivity/estimator_type", "none");
533 
534  bool do_adjoint_solve = false;
535 
536  // First check if the error estimator requires an adjoint solve
537  if( error_estimator.find("adjoint") != std::string::npos )
538  {
539  do_adjoint_solve = true;
540  }
541 
542  // Now check if the user requested to do an adjoint solve regardless
544  if( input( "linear-nonlinear-solver/do_adjoint_solve", false ) )
545  {
546  do_adjoint_solve = true;
547  }
548 
549  return do_adjoint_solve;
550  }
551 
552 #ifdef GRINS_USE_GRVY_TIMERS
553  void Simulation::attach_grvy_timer( GRVY::GRVY_Timer_Class* grvy_timer )
554  {
555  this->_multiphysics_system->attach_grvy_timer( grvy_timer );
556  return;
557  }
558 #endif
559 
560 } // namespace GRINS
void init_multiphysics_system(const GetPot &input, SimulationBuilder &sim_builder)
Helper function.
Definition: simulation.C:145
void attach_neumann_bc_funcs(std::map< GRINS::PhysicsName, GRINS::NBCContainer > neumann_bcs, GRINS::MultiphysicsSystem *system)
Definition: simulation.C:473
void attach_physics_list(PhysicsList physics_list)
PhysicsList gets built by GRINS::PhysicsFactory and attached here.
std::tr1::shared_ptr< CompositeQoI > build_qoi(const GetPot &input)
std::map< std::string, std::tr1::shared_ptr< GRINS::Physics > > PhysicsList
Container for GRINS::Physics object pointers.
Definition: var_typedefs.h:57
void read_restart(const GetPot &input)
Definition: simulation.C:433
std::tr1::shared_ptr< GRINS::Physics > get_physics(const std::string physics_name)
void register_postprocessing_vars(const GetPot &input, PostProcessedQuantities< libMesh::Real > &postprocessing)
Each Physics will register their postprocessed quantities with this call.
ParameterManager _forward_parameters
Definition: simulation.h:164
std::tr1::shared_ptr< PostProcessedQuantities< libMesh::Real > > _postprocessing
Definition: simulation.h:140
std::map< GRINS::PhysicsName, GRINS::NBCContainer > build_neumann_bcs(libMesh::EquationSystems &equation_system)
void init_params(const GetPot &input, SimulationBuilder &sim_builder)
Helper function.
Definition: simulation.C:204
unsigned int _timesteps_per_vis
Definition: simulation.h:157
std::tr1::shared_ptr< libMesh::EquationSystems > equation_system
GRINS namespace.
void attach_dirichlet_bc_funcs(std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > dbc_map, GRINS::MultiphysicsSystem *system)
Definition: simulation.C:492
std::tr1::shared_ptr< libMesh::EquationSystems > _equation_system
Definition: simulation.h:128
unsigned int timesteps_per_perflog
std::tr1::shared_ptr< libMesh::ErrorEstimator > error_estimator
GRINS::PhysicsList build_physics(const GetPot &input)
virtual ~Simulation()
Definition: simulation.C:140
bool _print_equation_system_info
Definition: simulation.h:145
libMesh::Number get_qoi_value(unsigned int qoi_index) const
Definition: simulation.C:427
const MeshBuilder & mesh_builder() const
unsigned int timesteps_per_vis
std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > build_dirichlet_bcs()
std::tr1::shared_ptr< libMesh::EquationSystems > get_equation_system()
Definition: simulation.C:422
libMesh::ParameterVector parameter_vector
void init_adjoint_solve(const GetPot &input, bool output_adjoint)
Helper function.
Definition: simulation.C:506
std::tr1::shared_ptr< GRINS::Visualization > _vis
Definition: simulation.h:138
GRINS::MultiphysicsSystem * system
void init_qois(const GetPot &input, SimulationBuilder &sim_builder)
Helper function.
Definition: simulation.C:181
Interface with libMesh for solving Multiphysics problems.
ParameterManager _adjoint_parameters
Definition: simulation.h:162
bool _output_residual_sensitivities
Definition: simulation.h:154
bool _output_solution_sensitivities
Definition: simulation.h:155
std::tr1::shared_ptr< PostProcessedQuantities< libMesh::Real > > postprocessing
void output_qoi(std::ostream &out) const
Basic output for computed QoI's.
std::tr1::shared_ptr< libMesh::UnstructuredMesh > _mesh
Definition: simulation.h:126
void check_for_unused_vars(const GetPot &input, bool warning_only)
Helper function.
Definition: simulation.C:273
std::tr1::shared_ptr< GRINS::Visualization > vis
std::tr1::shared_ptr< GRINS::Solver > _solver
Definition: simulation.h:130
void init_restart(const GetPot &input, SimulationBuilder &sim_builder, const libMesh::Parallel::Communicator &comm)
Helper function.
Definition: simulation.C:257
std::tr1::shared_ptr< libMesh::ErrorEstimator > _error_estimator
Definition: simulation.h:160
Simple class to hold objects passed to Solver::solve.
GRINS::MultiphysicsSystem * _multiphysics_system
Definition: simulation.h:136
unsigned int _timesteps_per_perflog
Definition: simulation.h:158
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:360
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:411
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:529

Generated on Mon Jun 22 2015 21:32:20 for GRINS-0.6.0 by  doxygen 1.8.9.1