GRINS-0.6.0
grins_unsteady_solver.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
28 
29 // GRINS
30 #include "grins/grins_enums.h"
31 #include "grins/solver_context.h"
32 #include "grins/multiphysics_sys.h"
33 
34 // libMesh
35 #include "libmesh/dirichlet_boundaries.h"
36 #include "libmesh/dof_map.h"
37 #include "libmesh/getpot.h"
38 #include "libmesh/euler_solver.h"
39 #include "libmesh/twostep_time_solver.h"
40 
41 // C++
42 #include <ctime>
43 
44 namespace GRINS
45 {
46 
47  UnsteadySolver::UnsteadySolver( const GetPot& input )
48  : Solver(input),
49  _n_timesteps( input("unsteady-solver/n_timesteps", 1 ) ),
50  _backtrack_deltat( input("unsteady-solver/backtrack_deltat", 0 ) ),
51  _theta( input("unsteady-solver/theta", 0.5 ) ),
53  _deltat( input("unsteady-solver/deltat", 0.0 ) ),
54  _target_tolerance( input("unsteady-solver/target_tolerance", 0.0 ) ),
55  _upper_tolerance( input("unsteady-solver/upper_tolerance", 0.0 ) ),
56  _max_growth( input("unsteady-solver/max_growth", 0.0 ) )
57  {
58  const unsigned int n_component_norm =
59  input.vector_variable_size("unsteady-solver/component_norm");
60  for (unsigned int i=0; i != n_component_norm; ++i)
61  {
62  const std::string current_norm = input("component_norm", std::string("L2"), i);
63  // TODO: replace this with string_to_enum with newer libMesh
64  if (current_norm == "GRINSEnums::L2")
65  _component_norm.set_type(i, libMesh::L2);
66  else if (current_norm == "GRINSEnums::H1")
67  _component_norm.set_type(i, libMesh::H1);
68  else
69  libmesh_not_implemented();
70  }
71 
72 
73  }
74 
76  {
77  return;
78  }
79 
81  {
82  libMesh::EulerSolver* time_solver = new libMesh::EulerSolver( *(system) );
83 
85  {
86  libMesh::TwostepTimeSolver *outer_solver =
87  new libMesh::TwostepTimeSolver(*system);
88 
89  outer_solver->target_tolerance = _target_tolerance;
90  outer_solver->upper_tolerance = _upper_tolerance;
91  outer_solver->max_growth = _max_growth;
92  outer_solver->quiet = false;
93 
94  outer_solver->core_time_solver =
95  libMesh::AutoPtr<libMesh::UnsteadySolver>(time_solver);
96  system->time_solver = libMesh::AutoPtr<libMesh::TimeSolver>(outer_solver);
97  }
98  else
99  {
100  system->time_solver = libMesh::AutoPtr<libMesh::TimeSolver>(time_solver);
101  }
102 
103  // Set theta parameter for time-stepping scheme
104  time_solver->theta = this->_theta;
105  time_solver->reduce_deltat_on_diffsolver_failure = this->_backtrack_deltat;
106 
107  return;
108  }
109 
111  {
112  libmesh_assert( context.system );
113 
114  context.system->deltat = this->_deltat;
115 
116  libMesh::Real sim_time;
117 
118  if( context.output_vis )
119  {
120  context.postprocessing->update_quantities( *(context.equation_system) );
121  context.vis->output( context.equation_system );
122  }
123 
124  std::time_t first_wall_time = std::time(NULL);
125 
126  // Now we begin the timestep loop to compute the time-accurate
127  // solution of the equations.
128  for (unsigned int t_step=0; t_step < this->_n_timesteps; t_step++)
129  {
130  std::time_t latest_wall_time = std::time(NULL);
131 
132  std::cout << "==========================================================" << std::endl
133  << " Beginning time step " << t_step <<
134  ", t = " << context.system->time <<
135  ", dt = " << context.system->deltat <<
136  ", runtime = " << (latest_wall_time - first_wall_time) <<
137  std::endl
138  << "==========================================================" << std::endl;
139 
140  // If we have any solution-dependent Dirichlet boundaries, we
141  // need to update them with the current solution.
142  //
143  // FIXME: This needs to be much more efficient and intuitive.
144  bool have_nonlinear_dirichlet_bc = false;
145  {
146  const libMesh::DirichletBoundaries &db =
147  *context.system->get_dof_map().get_dirichlet_boundaries();
148  for (libMesh::DirichletBoundaries::const_iterator
149  it = db.begin(); it != db.end(); ++it)
150  {
151  const libMesh::DirichletBoundary* bdy = *it;
152  if (bdy->f_fem.get())
153  {
154  have_nonlinear_dirichlet_bc = true;
155  break;
156  }
157  }
158  }
159  if (have_nonlinear_dirichlet_bc)
160  context.system->get_equation_systems().reinit();
161 
162  // GRVY timers contained in here (if enabled)
163  context.system->solve();
164 
165  sim_time = context.system->time;
166 
167  if( context.output_vis && !((t_step+1)%context.timesteps_per_vis) )
168  {
169  context.postprocessing->update_quantities( *(context.equation_system) );
170  context.vis->output( context.equation_system, t_step, sim_time );
171  }
172 
173  if( context.output_residual && !((t_step+1)%context.timesteps_per_vis) )
174  context.vis->output_residual( context.equation_system, context.system,
175  t_step, sim_time );
176 
177  if ( context.print_perflog && context.timesteps_per_perflog
178  && !((t_step+1)%context.timesteps_per_perflog) )
179  libMesh::perflog.print_log();
180 
181  if ( context.print_scalars )
182  for (unsigned int v=0; v != context.system->n_vars(); ++v)
183  if (context.system->variable(v).type().family ==
184  libMesh::SCALAR)
185  {
186  std::cout << context.system->variable_name(v) <<
187  " = {";
188  std::vector<libMesh::dof_id_type> scalar_indices;
189  context.system->get_dof_map().SCALAR_dof_indices
190  (scalar_indices, v);
191  if (scalar_indices.size())
192  std::cout <<
193  context.system->current_solution(scalar_indices[0]);
194  for (unsigned int i=1; i < scalar_indices.size();
195  ++i)
196  std::cout << ", " <<
197  context.system->current_solution(scalar_indices[i]);
198  std::cout << '}' << std::endl;
199  }
200 
201  // Advance to the next timestep
202  context.system->time_solver->advance_timestep();
203  }
204 
205  std::time_t final_wall_time = std::time(NULL);
206  std::cout << "==========================================================" << std::endl
207  << " Ending time stepping, t = " << context.system->time <<
208  ", runtime = " << (final_wall_time - first_wall_time) <<
209  std::endl
210  << "==========================================================" << std::endl;
211 
212 
213  return;
214  }
215 
216 } // namespace GRINS
UnsteadySolver(const GetPot &input)
std::tr1::shared_ptr< libMesh::EquationSystems > equation_system
GRINS namespace.
unsigned int timesteps_per_perflog
virtual void init_time_solver(GRINS::MultiphysicsSystem *system)
unsigned int timesteps_per_vis
GRINS::MultiphysicsSystem * system
Interface with libMesh for solving Multiphysics problems.
std::tr1::shared_ptr< PostProcessedQuantities< libMesh::Real > > postprocessing
virtual void solve(SolverContext &context)
libMesh::SystemNorm _component_norm
std::tr1::shared_ptr< GRINS::Visualization > vis
Simple class to hold objects passed to Solver::solve.

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