$extrastylesheet
adaptive_time_solver.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 #include "libmesh/adaptive_time_solver.h"
00019 #include "libmesh/diff_system.h"
00020 #include "libmesh/numeric_vector.h"
00021 
00022 namespace libMesh
00023 {
00024 
00025 
00026 
00027 AdaptiveTimeSolver::AdaptiveTimeSolver (sys_type& s)
00028   : UnsteadySolver(s),
00029     core_time_solver(),
00030     target_tolerance(1.e-3),
00031     upper_tolerance(0.0),
00032     max_deltat(0.),
00033     min_deltat(0.),
00034     max_growth(0.),
00035     global_tolerance(true)
00036 {
00037   // the child class must populate core_time_solver
00038   // with whatever actual time solver is to be used
00039 
00040   // As an UnsteadySolver, we have an old_local_nonlinear_solution, but we're
00041   // going to drop it and use our core time solver's instead.
00042   old_local_nonlinear_solution.reset();
00043 }
00044 
00045 
00046 
00047 AdaptiveTimeSolver::~AdaptiveTimeSolver ()
00048 {
00049   // As an UnsteadySolver, we have an old_local_nonlinear_solution, but it
00050   // is being managed by our core_time_solver.  Make sure we don't delete
00051   // it out from under them, in case the user wants to keep using the core
00052   // solver after they're done with us.
00053   old_local_nonlinear_solution.release();
00054 }
00055 
00056 
00057 
00058 void AdaptiveTimeSolver::init()
00059 {
00060   libmesh_assert(core_time_solver.get());
00061 
00062   // We override this because our core_time_solver is the one that
00063   // needs to handle new vectors, diff_solver->init(), etc
00064   core_time_solver->init();
00065 
00066   // As an UnsteadySolver, we have an old_local_nonlinear_solution, but it
00067   // isn't pointing to the right place - fix it
00068   //
00069   // This leaves us with two UniquePtrs holding the same pointer - dangerous
00070   // for future use.  Replace with shared_ptr?
00071   old_local_nonlinear_solution =
00072     UniquePtr<NumericVector<Number> >(core_time_solver->old_local_nonlinear_solution.get());
00073 }
00074 
00075 
00076 
00077 void AdaptiveTimeSolver::reinit()
00078 {
00079   libmesh_assert(core_time_solver.get());
00080 
00081   // We override this because our core_time_solver is the one that
00082   // needs to handle new vectors, diff_solver->reinit(), etc
00083   core_time_solver->reinit();
00084 }
00085 
00086 
00087 void AdaptiveTimeSolver::advance_timestep ()
00088 {
00089   NumericVector<Number> &old_nonlinear_soln =
00090     _system.get_vector("_old_nonlinear_solution");
00091   NumericVector<Number> &nonlinear_solution =
00092     *(_system.solution);
00093   //    _system.get_vector("_nonlinear_solution");
00094 
00095   old_nonlinear_soln = nonlinear_solution;
00096 
00097   if (!first_solve)
00098     _system.time += last_deltat;
00099 }
00100 
00101 
00102 
00103 Real AdaptiveTimeSolver::error_order () const
00104 {
00105   libmesh_assert(core_time_solver.get());
00106 
00107   return core_time_solver->error_order();
00108 }
00109 
00110 
00111 
00112 bool AdaptiveTimeSolver::element_residual (bool request_jacobian,
00113                                            DiffContext &context)
00114 {
00115   libmesh_assert(core_time_solver.get());
00116 
00117   return core_time_solver->element_residual(request_jacobian, context);
00118 }
00119 
00120 
00121 
00122 bool AdaptiveTimeSolver::side_residual (bool request_jacobian,
00123                                         DiffContext &context)
00124 {
00125   libmesh_assert(core_time_solver.get());
00126 
00127   return core_time_solver->side_residual(request_jacobian, context);
00128 }
00129 
00130 
00131 
00132 bool AdaptiveTimeSolver::nonlocal_residual (bool request_jacobian,
00133                                             DiffContext &context)
00134 {
00135   libmesh_assert(core_time_solver.get());
00136 
00137   return core_time_solver->nonlocal_residual(request_jacobian, context);
00138 }
00139 
00140 
00141 
00142 UniquePtr<DiffSolver> & AdaptiveTimeSolver::diff_solver()
00143 {
00144   return core_time_solver->diff_solver();
00145 }
00146 
00147 
00148 
00149 UniquePtr<LinearSolver<Number> > & AdaptiveTimeSolver::linear_solver()
00150 {
00151   return core_time_solver->linear_solver();
00152 }
00153 
00154 
00155 
00156 Real AdaptiveTimeSolver::calculate_norm(System &s,
00157                                         NumericVector<Number> &v)
00158 {
00159   return s.calculate_norm(v, component_norm);
00160 }
00161 
00162 } // namespace libMesh