#include <eigen_time_solver.h>
typedef DifferentiableSystem sys_type
typedef TimeSolver Parent
EigenTimeSolver (sys_type &s)
virtual ~EigenTimeSolver ()
virtual void init ()
virtual void reinit ()
virtual void solve ()
virtual void advance_timestep ()
virtual Real error_order () const
virtual bool element_residual (bool get_jacobian, DiffContext &)
virtual bool side_residual (bool get_jacobian, DiffContext &)
virtual Real du (const SystemNorm &) const
virtual void adjoint_solve ()
virtual void adjoint_recede_timestep ()
virtual void before_timestep ()
const sys_type & system () const
virtual AutoPtr< DiffSolver > & diff_solver ()
virtual AutoPtr< DiffSolver > & adjoint_solver ()
static std::string get_info ()
static void print_info ()
static unsigned int n_objects ()
AutoPtr< EigenSolver< Number > > eigen_solver
Real tol
unsigned int maxits
unsigned int n_eigenpairs_to_compute
unsigned int n_basis_vectors_to_use
unsigned int n_converged_eigenpairs
unsigned int n_iterations_reqd
bool quiet
unsigned int reduce_deltat_on_diffsolver_failure
typedef std::map< std::string, std::pair< unsigned int, unsigned int > > Counts
sys_type & system ()
void increment_constructor_count (const std::string &name)
void increment_destructor_count (const std::string &name)
AutoPtr< DiffSolver > _diff_solver
AutoPtr< DiffSolver > _adjoint_solver
sys_type & _system
bool first_solve
AutoPtr< NumericVector< Number > > old_local_nonlinear_solution
static Counts _counts
static Threads::atomic< unsigned int > _n_objects
static Threads::spin_mutex _mutex
enum NowAssembling { Matrix_A, Matrix_B, Invalid_Matrix }
The name of this class is confusing...it's meant to refer to the base class (TimeSolver) while still telling one that it's for solving (generalized) EigenValue problems that arise from finite element discretizations. For a time-dependent problem du/dt=F(u), with a steady solution 0=F(u_0), we look at the time evolution of a small perturbation, p=u-u_0, for which the (linearized) governing equation is
dp/dt = F'(u_0)p
where F'(u_0) is the Jacobian. The generalized eigenvalue problem arises by considering perturbations of the general form p = exp(lambda*t)x, which leads to
Ax = lambda*Bx
where A is the (discretized by FEM) Jacobian matrix and B is the (discretized by FEM) mass matrix.
The EigenSystem class (by Steffen Petersen) is related but does not fall under the FEMSystem paradigm invented by Roy Stogner. The EigenSolver class (also by Steffen) is meant to provide a generic 'linear solver' interface for EigenValue software. The only current concrete implementation is a SLEPc-based eigensolver class, which we make use of here as well.
Author:
Definition at line 66 of file eigen_time_solver.h.
Definition at line 105 of file reference_counter.h.
Definition at line 77 of file eigen_time_solver.h.
Reimplemented from TimeSolver.
Definition at line 72 of file eigen_time_solver.h.
Enumerator:
Definition at line 186 of file eigen_time_solver.h.
{
Matrix_A,
Matrix_B,
Invalid_Matrix
};
Definition at line 32 of file eigen_time_solver.C.
References eigen_solver, libMeshEnums::GHEP, and libMeshEnums::LARGEST_MAGNITUDE.
: Parent(s),
eigen_solver (EigenSolver<Number>::build()),
tol(pow(TOLERANCE, 5./3.)),
maxits(1000),
n_eigenpairs_to_compute(5),
n_basis_vectors_to_use(3*n_eigenpairs_to_compute),
n_converged_eigenpairs(0),
n_iterations_reqd(0)
{
libmesh_experimental();
eigen_solver->set_eigenproblem_type(GHEP);//or GNHEP
eigen_solver->set_position_of_spectrum(LARGEST_MAGNITUDE);
}
Definition at line 47 of file eigen_time_solver.C.
{
}
Definition at line 90 of file time_solver.C.
{
}
Definition at line 77 of file time_solver.C.
References TimeSolver::_adjoint_solver.
{
_adjoint_solver->adjoint_solve();
}
Definition at line 157 of file time_solver.h.
References TimeSolver::_adjoint_solver.
{ return _adjoint_solver; }
Reimplemented from TimeSolver.
Definition at line 111 of file eigen_time_solver.h.
{ }
Definition at line 142 of file time_solver.h.
{}
Reimplemented in AdaptiveTimeSolver.
Definition at line 152 of file time_solver.h.
References TimeSolver::_diff_solver.
{ return _diff_solver; }
Implements TimeSolver.
Definition at line 137 of file eigen_time_solver.h.
{ return 0.; }
Implements TimeSolver.
Definition at line 127 of file eigen_time_solver.C.
References TimeSolver::_system, DifferentiableSystem::element_constraint(), DifferentiableSystem::element_time_derivative(), DifferentiableSystem::mass_residual(), Matrix_A, Matrix_B, and now_assembling.
{
// The EigenTimeSolver always computes jacobians!
libmesh_assert (request_jacobian);
// Assemble the operator for the spatial part.
if (now_assembling == Matrix_A)
{
bool jacobian_computed =
_system.element_time_derivative(request_jacobian, context);
// The user shouldn't compute a jacobian unless requested
libmesh_assert(request_jacobian || !jacobian_computed);
bool jacobian_computed2 =
_system.element_constraint(jacobian_computed, context);
// The user shouldn't compute a jacobian unless requested
libmesh_assert (jacobian_computed || !jacobian_computed2);
return jacobian_computed && jacobian_computed2;
}
// Assemble the mass matrix operator
else if (now_assembling == Matrix_B)
{
bool mass_jacobian_computed =
_system.mass_residual(request_jacobian, context);
// Scale Jacobian by -1?
//context.elem_jacobian *= -1.0;
return mass_jacobian_computed;
}
else
{
libmesh_error();
return false;
}
}
Definition at line 117 of file eigen_time_solver.h.
{ return 0.; }
Definition at line 45 of file reference_counter.C.
References ReferenceCounter::_counts, and Quality::name().
Referenced by ReferenceCounter::print_info().
{
#if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
std::ostringstream out;
out << '
<< ' ----------------------------------------------------------------------------
<< '| Reference count information |
<< ' ---------------------------------------------------------------------------- ;
for (Counts::iterator it = _counts.begin();
it != _counts.end(); ++it)
{
const std::string name(it->first);
const unsigned int creations = it->second.first;
const unsigned int destructions = it->second.second;
out << '| ' << name << ' reference count information:
<< '| Creations: ' << creations << '
<< '| Destructions: ' << destructions << ';
}
out << ' ---------------------------------------------------------------------------- ;
return out.str();
#else
return '';
#endif
}
Definition at line 149 of file reference_counter.h.
References ReferenceCounter::_counts, Quality::name(), and Threads::spin_mtx.
Referenced by ReferenceCountedObject< Value >::ReferenceCountedObject().
{
Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
std::pair<unsigned int, unsigned int>& p = _counts[name];
p.first++;
}
Definition at line 167 of file reference_counter.h.
References ReferenceCounter::_counts, Quality::name(), and Threads::spin_mtx.
Referenced by ReferenceCountedObject< Value >::~ReferenceCountedObject().
{
Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
std::pair<unsigned int, unsigned int>& p = _counts[name];
p.second++;
}
Reimplemented from TimeSolver.
Definition at line 56 of file eigen_time_solver.C.
References TimeSolver::_system, ImplicitSystem::add_matrix(), and ImplicitSystem::have_matrix().
{
// Add matrix 'B' to _system if not already there.
// The user may have already added a matrix 'B' before
// calling the System initialization. This would be
// necessary if e.g. the System originally started life
// with a different type of TimeSolver and only later
// had its TimeSolver changed to an EigenTimeSolver.
if (!_system.have_matrix('B'))
_system.add_matrix('B');
}
Definition at line 76 of file reference_counter.h.
References ReferenceCounter::_n_objects.
Referenced by System::read_serialized_blocked_dof_objects(), and System::write_serialized_blocked_dof_objects().
{ return _n_objects; }
Definition at line 83 of file reference_counter.C.
References ReferenceCounter::get_info().
{
#if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
std::cout << ReferenceCounter::get_info();
#endif
}
Reimplemented from TimeSolver.
Definition at line 51 of file eigen_time_solver.C.
{
// empty...
}
Implements TimeSolver.
Definition at line 173 of file eigen_time_solver.C.
References TimeSolver::_system, Matrix_A, Matrix_B, now_assembling, DifferentiableSystem::side_constraint(), DifferentiableSystem::side_mass_residual(), and DifferentiableSystem::side_time_derivative().
{
// The EigenTimeSolver always requests jacobians?
//libmesh_assert (request_jacobian);
// Assemble the operator for the spatial part.
if (now_assembling == Matrix_A)
{
bool jacobian_computed =
_system.side_time_derivative(request_jacobian, context);
// The user shouldn't compute a jacobian unless requested
libmesh_assert (request_jacobian || !jacobian_computed);
bool jacobian_computed2 =
_system.side_constraint(jacobian_computed, context);
// The user shouldn't compute a jacobian unless requested
libmesh_assert (jacobian_computed || !jacobian_computed2);
return jacobian_computed && jacobian_computed2;
}
// There is now a 'side' equivalent for the mass matrix
else if (now_assembling == Matrix_B)
{
bool mass_jacobian_computed =
_system.side_mass_residual(request_jacobian, context);
return mass_jacobian_computed;
}
else
{
libmesh_error();
return false;
}
}
Reimplemented from TimeSolver.
Definition at line 68 of file eigen_time_solver.C.
References TimeSolver::_system, DifferentiableSystem::assembly(), eigen_solver, ImplicitSystem::get_matrix(), ImplicitSystem::matrix, Matrix_A, Matrix_B, maxits, n_basis_vectors_to_use, n_converged_eigenpairs, n_eigenpairs_to_compute, n_iterations_reqd, now_assembling, TimeSolver::quiet, and tol.
{
// The standard implementation is basically to call:
// _diff_solver->solve();
// which internally assembles (when necessary) matrices and vectors
// and calls linear solver software while also doing Newton steps (see newton_solver.C)
//
// The element_residual and side_residual functions below control
// what happens in the interior of the element assembly loops.
// We have a system reference, so it's possible to call _system.assembly()
// ourselves if we want to...
//
// Interestingly, for the EigenSolver we don't need residuals...just Jacobians.
// The Jacobian should therefore always be requested, and always return
// jacobian_computed as being true.
// The basic plan of attack is:
// .) Construct the Jacobian using _system.assembly(true,true) as we
// would for a steady system. Use a flag in this class to
// control behavior in element_residual and side_residual
// .) Swap _system.matrix to matrix 'B' (be sure to add this extra matrix during init)
// .) Call _system.assembly(true,true) again, using the flag in element_residual
// and side_residual to only get the mass matrix terms.
// .) Send A and B to Steffen's EigenSolver interface.
// Assemble the spatial part (matrix A) of the operator
if (!this->quiet)
std::cout << 'Assembling matrix A.' << std::endl;
_system.matrix = &( _system.get_matrix ('System Matrix') );
this->now_assembling = Matrix_A;
_system.assembly(true, true);
//_system.matrix->print_matlab('matrix_A.m');
// Point the system's matrix at B, call assembly again.
if (!this->quiet)
std::cout << 'Assembling matrix B.' << std::endl;
_system.matrix = &( _system.get_matrix ('B') );
this->now_assembling = Matrix_B;
_system.assembly(true, true);
//_system.matrix->print_matlab('matrix_B.m');
// Send matrices A, B to Steffen's SlepcEigenSolver interface
//libmesh_here();
if (!this->quiet)
std::cout << 'Calling the EigenSolver.' << std::endl;
std::pair<unsigned int, unsigned int> solve_data =
eigen_solver->solve_generalized (_system.get_matrix ('System Matrix'),
_system.get_matrix ('B'),
n_eigenpairs_to_compute,
n_basis_vectors_to_use,
tol,
maxits);
this->n_converged_eigenpairs = solve_data.first;
this->n_iterations_reqd = solve_data.second;
}
Definition at line 202 of file time_solver.h.
References TimeSolver::_system.
{ return _system; }
Definition at line 147 of file time_solver.h.
References TimeSolver::_system.
{ return _system; }
Definition at line 197 of file time_solver.h.
Referenced by TimeSolver::adjoint_solve(), TimeSolver::adjoint_solver(), TimeSolver::init(), and TimeSolver::reinit().
Definition at line 110 of file reference_counter.h.
Referenced by ReferenceCounter::get_info(), ReferenceCounter::increment_constructor_count(), and ReferenceCounter::increment_destructor_count().
Definition at line 192 of file time_solver.h.
Referenced by TimeSolver::diff_solver(), TimeSolver::init(), TimeSolver::reinit(), UnsteadySolver::solve(), and TimeSolver::solve().
Definition at line 123 of file reference_counter.h.
Definition at line 118 of file reference_counter.h.
Referenced by ReferenceCounter::n_objects(), ReferenceCounter::ReferenceCounter(), and ReferenceCounter::~ReferenceCounter().
Definition at line 207 of file time_solver.h.
Referenced by UnsteadySolver::advance_timestep(), AdaptiveTimeSolver::advance_timestep(), UnsteadySolver::du(), SteadySolver::element_residual(), EulerSolver::element_residual(), Euler2Solver::element_residual(), element_residual(), UnsteadySolver::init(), TimeSolver::init(), init(), UnsteadySolver::old_nonlinear_solution(), SteadySolver::side_residual(), EulerSolver::side_residual(), Euler2Solver::side_residual(), side_residual(), UnsteadySolver::solve(), TwostepTimeSolver::solve(), solve(), and TimeSolver::system().
Definition at line 143 of file eigen_time_solver.h.
Referenced by EigenTimeSolver(), and solve().
Reimplemented in UnsteadySolver.
Definition at line 213 of file time_solver.h.
Definition at line 154 of file eigen_time_solver.h.
Definition at line 170 of file eigen_time_solver.h.
Definition at line 176 of file eigen_time_solver.h.
Definition at line 159 of file eigen_time_solver.h.
Definition at line 182 of file eigen_time_solver.h.
Definition at line 206 of file eigen_time_solver.h.
Referenced by element_residual(), side_residual(), and solve().
Reimplemented in UnsteadySolver.
Definition at line 218 of file time_solver.h.
Definition at line 162 of file time_solver.h.
Referenced by UnsteadySolver::solve(), TwostepTimeSolver::solve(), and solve().
Definition at line 185 of file time_solver.h.
Referenced by UnsteadySolver::solve(), and TwostepTimeSolver::solve().
Definition at line 149 of file eigen_time_solver.h.
Referenced by solve().
Generated automatically by Doxygen for libMesh from the source code.