36 _velocity_param(nullptr),
    57     _V_range          = std::pair<Real, Real>(0.,0.);
    71            unsigned int                                 n_V_divs,
    72            std::vector<libMesh::NumericVector<Real> *>& basis) {
    88     std::map<Real, MAST::FlutterSolutionBase*>::iterator it =
    94     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator cross_it =
    98         delete cross_it->second;
   110     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
   115     for ( ; it!=end; it++)
   116         if (it->second->root) 
   131     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
   135     unsigned int root_num = 0;
   136     for ( ; it!=end; it++) {
   137         if (it->second->root) { 
   139                 return *(it->second->root);
   145     libmesh_assert(
false); 
   152 std::pair<bool, MAST::FlutterRootBase*>
   154                                               const unsigned int n_bisection_iters)
   158     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator
   166             const unsigned int root_num = cross->
root_num;
   167             std::pair<bool, MAST::FlutterSolutionBase*> sol;
   176                                       root_num, g_tol, n_bisection_iters);
   178             cross->
root = &(sol.second->get_root(root_num));
   183             std::pair<Real, MAST::FlutterRootCrossoverBase*>
   184             val(cross->
root->
V, cross);
   186             return std::pair<bool, MAST::FlutterRootBase*> (
true, cross->
root);
   193     return std::pair<bool, MAST::FlutterRootBase*> (
false, 
nullptr);
   198 std::pair<bool,  MAST::FlutterRootBase*>
   200                                                   const unsigned int n_bisection_iters)
   204     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator
   209         return std::pair<bool, MAST::FlutterRootBase*> (
false, 
nullptr);
   214     while (!it->second->root)
   220             const unsigned int root_num = cross->
root_num;
   221             std::pair<bool, MAST::FlutterSolutionBase*> sol;
   230                                      root_num, g_tol, n_bisection_iters);
   232             cross->
root = &(sol.second->get_root(root_num));
   237             std::pair<Real, MAST::FlutterRootCrossoverBase*>
   238             val(cross->
root->
V, cross);
   247     return std::pair<bool, MAST::FlutterRootBase*> (
true, it->second->root);
   254 std::pair<bool,  MAST::FlutterRootBase*>
   257                                                 const unsigned int n_bisection_iters) {
   279     *lower_root = 
nullptr,
   280     *upper_root = 
nullptr;
   282     std::pair<unsigned int, unsigned int>
   283     bracket_n_unstable_roots(0, 0);
   296         libmesh_assert(!bracket_n_unstable_roots.first);
   301                               (lower_V, sol)).second;
   303     libmesh_assert(if_success);
   313         upper_V                         = lower_V + dV;
   315         sol                             = 
_analyze(upper_V, sol).release();
   324                                   (upper_V, sol)).second;
   326         libmesh_assert(if_success);
   329         if (bracket_n_unstable_roots.second ||
   340             bracket_n_unstable_roots.first  = bracket_n_unstable_roots.second;
   341             bracket_n_unstable_roots.second = 0;
   342             lower_root                      = upper_root;
   346     std::pair<bool, MAST::FlutterRootBase*> rval(
false, 
nullptr);
   349     if (!bracket_n_unstable_roots.second)
   353     unsigned int n_iters = 0;
   355     while (n_iters < n_bisection_iters) {
   358         lower_g    =   lower_root->
root.real();
   359         upper_g    =   upper_root->root.real();
   371         0.5*(upper_V-lower_V)/(upper_g-lower_g)*(1.e-4-upper_g);  
   373         sol        = 
_analyze(new_V, sol).release();
   383                                   (new_V, sol)).second;
   385         libmesh_assert(if_success);
   389         if ((root->
root.real() > 0.) &&  
   390             (root->
root.real() <= g_tol)) {
   398         if (root->
root.real() < 0.) {
   401             lower_g    = root->
root.real();
   407             upper_g    = root->
root.real();
   434         for (
unsigned int i=0; i<
_n_V_divs+1; i++) {
   435             V_vals[i] = current_V;
   436             current_V += delta_V;
   441         for (
unsigned int i=0; i<_n_V_divs+1; i++) {
   442             current_V = V_vals[i];
   443             std::unique_ptr<MAST::TimeDomainFlutterSolution>
   444             sol = 
_analyze(current_V, prev_sol);
   446             prev_sol = sol.get();
   454                                       (current_V, sol.release())).second;
   456             libmesh_assert(if_success);
   474     std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
   477     libmesh_assert(sol_it != sol_end); 
   479     unsigned int nvals = sol_it->second->n_roots();
   480     libmesh_assert(nvals); 
   483     for (
unsigned int i=0; i<nvals; i++)
   488         << std::setw(5) << i << 
" **" << std::endl
   489         << std::setw(15) << 
"V_ref"   490         << std::setw(15) << 
"Re"   491         << std::setw(15) << 
"Im" << std::endl;
   497         for ( ; sol_it != sol_end; sol_it++)
   500             sol_it->second->get_root(i);
   503             << std::setw(15) << root.
V   504             << std::setw(15) << std::real(root.
root)
   505             << std::setw(15) << std::imag(root.
root) << std::endl;
   507         *
_output << std::endl << std::endl;
   512     std::streamsize prec = 
_output->precision();
   516     << 
"n critical roots identified: " << nroots << std::endl;
   517     for (
unsigned int i=0; i<nroots; i++)
   521         << 
"** Root : " << std::setw(5) << i << 
" **" << std::endl
   522         << 
"V      = " << std::setw(15) << std::setprecision(15) << root.
V << std::endl
   523         << 
"g      = " << std::setw(15) << std::real(root.
root) << std::endl
   524         << 
"omega  = " << std::setw(15) << std::imag(root.
root) << std::endl
   525         << std::setprecision((
int) prec) 
   526         << 
"Modal Participation : " << std::endl ;
   527         for (
unsigned int j=0; j<nvals; j++)
   529             << 
"(" << std::setw(5) << j << 
"): "   531             << std::setw(3)  << 
" ";
   532         *
_output << std::endl << std::endl;
   546     *
_output << 
"n crossover points found: "   549     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
   554     for ( ; it != end; it++) {
   555         *
_output << 
"** Point : " << std::setw(5) << i << 
" **" << std::endl;
   566 std::pair<bool, MAST::FlutterSolutionBase*>
   570                   const unsigned int root_num,
   572                   const unsigned int max_iters) {
   577     lower_V  = ref_sol_range.first->ref_val(),
   578     lower_g  = ref_sol_range.first->get_root(root_num).root.real(),
   579     upper_V  = ref_sol_range.second->ref_val(),
   580     upper_g  = ref_sol_range.second->get_root(root_num).root.real(),
   582     unsigned int n_iters = 0;
   585     std::pair<bool, MAST::FlutterSolutionBase*> rval(
false, 
nullptr);
   587     while (n_iters < max_iters) {
   590         (upper_V-lower_V)/(upper_g-lower_g)*(0.-lower_g); 
   592         new_sol  = 
_analyze(new_V, ref_sol_range.first).release();
   600                                   (new_V, new_sol)).second;
   602         libmesh_assert(if_success);
   607         if (fabs(root.
root.real()) <= g_tol) {
   610             rval.second = new_sol;
   615         if (root.
root.real() < 0.) {
   618             lower_g = root.
root.real();
   623             upper_g = root.
root.real();
   631     rval.second = new_sol;
   639 std::unique_ptr<MAST::TimeDomainFlutterSolution>
   644     << 
" ====================================================" << std::endl
   645     << 
"Eigensolution" << std::endl
   646     << 
"   V_ref = " << std::setw(10) << v_ref << std::endl;
   660     root->
init(*
this, v_ref, ges);
   662         root->
sort(*prev_sol);
   665     << 
"Finished Eigensolution" << std::endl
   666     << 
" ====================================================" << std::endl;
   669     return std::unique_ptr<MAST::TimeDomainFlutterSolution> (root);
   700     (*_velocity_param) = U_inf;
   707         << 
"***  Performing Steady State Solve ***" << std::endl;
   716     m      =  RealMatrixX::Zero(n, n),
   717     c      =  RealMatrixX::Zero(n, n),
   718     k      =  RealMatrixX::Zero(n, n);
   723     std::map<MAST::StructuralQuantityType, RealMatrixX*> qty_map;
   738     B.topLeftCorner(n, n)      = RealMatrixX::Identity(n,n );
   739     B.bottomRightCorner(n, n)  = m;
   742     A.topRightCorner(n, n)     = RealMatrixX::Identity(n, n);
   743     A.bottomLeftCorner(n, n)   = -k;
   744     A.bottomRightCorner(n, n)  = -c;
   755                                          const libMesh::NumericVector<Real>& dXdp,
   781     m      =  RealMatrixX::Zero(n, n),
   782     c      =  RealMatrixX::Zero(n, n),
   783     k      =  RealMatrixX::Zero(n, n);
   788     std::map<MAST::StructuralQuantityType, RealMatrixX*> qty_map;
   795     (*_velocity_param) = U_inf;
   808     B.topLeftCorner(n, n)      = RealMatrixX::Identity(n,n );
   809     B.bottomRightCorner(n, n)  = m;
   812     A.topRightCorner(n, n)     = RealMatrixX::Identity(n, n);
   813     A.bottomLeftCorner(n, n)   = -k;
   814     A.bottomRightCorner(n, n)  = -c;
   830     const Real tol = 1.0e-5;
   834     libmesh_assert(nvals);
   843     std::vector<bool> modes_to_neglect(nvals);
   844     std::fill(modes_to_neglect.begin(),
   845               modes_to_neglect.end(), 
false);
   849     for (
unsigned int i=0; i<nvals; i++) {
   851         std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
   862         for ( ; sol_it!=sol_end; sol_it++) {
   864             g_val = fabs(sol_it->second->get_root(i).root.real());
   865             w_val = sol_it->second->get_root(i).root.imag();
   868             if (g_val > max_g_val)
   871             if (w_val > max_w_val)
   876         if (max_g_val < tol || max_w_val < 0.)
   877             modes_to_neglect[i] = 
true;
   882     for (
unsigned int i=0; i<nvals; i++) {
   884         std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
   889         if (sol_it == sol_end)
   893         bool if_process = 
false;
   895         while (sol_itp1 != sol_end) {
   899              (fabs(sol_it->second->ref_val()) > tol ||
   900               fabs(sol_itp1->second->ref_val()) > tol) &&
   906              !modes_to_neglect[i]);
   913                 *lower = sol_it->second,
   914                 *upper = sol_itp1->second;
   917                     (upper->get_root(i).root.real() > 0.)) {
   924                     std::pair<Real, MAST::FlutterRootCrossoverBase*>
   929                          (upper->get_root(i).root.real() <= 0.)) {
   936                     std::pair<Real, MAST::FlutterRootCrossoverBase*>
   937                     val( upper->get_root(i).V, cross);
   955          (fabs(sol_it->second->ref_val()) > tol ||
   956           fabs(sol_itp1->second->ref_val()) > tol) &&
   962          !modes_to_neglect[i]);
   964         Real g_val = sol_it->second->get_root(i).root.real();
   979             std::pair<Real, MAST::FlutterRootCrossoverBase*>
   980             val( sol_it->second->get_root(i).V, cross);
   994                       libMesh::NumericVector<Real>* dXdp,
   995                       libMesh::NumericVector<Real>* dXdV) {
  1000     << 
" ====================================================" << std::endl
  1001     << 
"Flutter Sensitivity Solution" << std::endl
  1002     << 
"   V_ref = " << std::setw(10) << root.
V << std::endl;
  1024     libMesh::NumericVector<Real>* sol_sens = dXdp;
  1025     std::unique_ptr<libMesh::NumericVector<Real> > zero_sol_sens;
  1027         zero_sol_sens.reset(
_assembly->
system().solution->zero_clone().release());
  1028         sol_sens = zero_sol_sens.get();
  1059         sol_sens = zero_sol_sens.get();
  1082     root.
V_sens     = - deig_dp.real() / deig_dV.real();
  1090     << 
"Finished Flutter Sensitivity Solution" << std::endl
  1091     << 
" ====================================================" << std::endl;
 
TimeDomainFlutterSolver()
defalut constructor 
virtual std::pair< bool, MAST::FlutterRootBase * > analyze_and_find_critical_root_without_tracking(const Real g_tol, const unsigned int n_iters)
This root starts with the lower velocity and increments the speed till a single unstable root is iden...
const MAST::NonlinearSystem & system() const
virtual void _identify_crossover_points()
identifies all cross-over and divergence points from analyzed roots 
ComplexVectorX eig_vec_left
std::vector< libMesh::NumericVector< Real > * > * _basis_vectors
basis vector used to define the reduced order model 
MAST::Parameter * _velocity_param
Parameter that define the velocity. 
virtual void print(std::ostream &output)
prints the data and modes from this solution 
void clear_base_solution(bool if_sens=false)
Clears the pointer to base solution. 
virtual std::pair< bool, MAST::FlutterSolutionBase * > _bisection_search(const std::pair< MAST::FlutterSolutionBase *, MAST::FlutterSolutionBase *> &ref_sol_range, const unsigned int root_num, const Real g_tol, const unsigned int max_iters)
bisection method search 
virtual void print(std::ostream &output)=0
prints the data and modes from this solution 
void scale_eigenvectors_to_identity_innerproduct()
Scales the right eigenvector so that the inner product with respect to the B matrix is equal to an Id...
virtual void clear()
clears the solution and other data from this solver 
const MAST::FlutterRootBase & get_root(const unsigned int n) const
returns the n th root in terms of ascending velocity that is found by the solver 
virtual void calculate_sensitivity(MAST::FlutterRootBase &root, const MAST::FunctionBase &f, libMesh::NumericVector< Real > *dXdp=nullptr, libMesh::NumericVector< Real > *dXdV=nullptr)
Calculate the sensitivity of the flutter root with respect to the f parameter. 
virtual void print_crossover_points()
Prints the crossover points output. 
Matrix< Complex, Dynamic, 1 > ComplexVectorX
This is a scalar function whose value can be changed and one that can be used as a design variable in...
virtual unsigned int n_roots_found() const
finds the number of critical points already identified in the procedure. 
unsigned int n_unstable_roots_in_upper_complex_half(Real tol) const
number of unstable roots in this solution. 
virtual std::unique_ptr< MAST::TimeDomainFlutterSolution > _analyze(const Real v_ref, const MAST::FlutterSolutionBase *prev_sol=nullptr)
performs an eigensolution at the specified reference value, and sort the roots based on the provided ...
MAST::FlutterSolverBase::SteadySolver * _steady_solver
object provides the steady state solution. 
void init(const MAST::TimeDomainFlutterSolver &solver, const Real v_ref, const MAST::LAPACK_DGGEV &eig_sol)
initializes the root 
std::multimap< Real, MAST::FlutterRootCrossoverBase * > _flutter_crossovers
the map of flutter crossover points versus average velocity of the two bounding roots ...
void _initialize_matrices(Real U_inf, RealMatrixX &A, RealMatrixX &B)
Assembles the reduced order system structural and aerodynmaic matrices for specified flight velocity ...
std::ofstream * _output
file to which the result will be written 
virtual void assemble_reduced_order_quantity(std::vector< libMesh::NumericVector< Real > *> &basis, std::map< MAST::StructuralQuantityType, RealMatrixX *> &mat_qty_map)
calculates the reduced order matrix given the basis provided in basis. 
virtual void print_sorted_roots()
Prints the sorted roots to the output. 
Matrix< Real, Dynamic, Dynamic > RealMatrixX
const MAST::FlutterRootBase & get_root(const unsigned int i) const
virtual ~TimeDomainFlutterSolver()
MAST::FlutterRootBase * get_critical_root(Real tol)
void set_base_solution(const libMesh::NumericVector< Real > &sol, bool if_sens=false)
if the eigenproblem is defined about a non-zero base solution, then this method provides the object w...
virtual void sort(const MAST::FlutterSolutionBase &sol)
sort this root with respect to the given solution from a previous eigen solution. ...
void initialize(MAST::Parameter &velocity_param, Real V_lower, Real V_upper, unsigned int n_V_divs, std::vector< libMesh::NumericVector< Real > *> &basis)
initializes the data structres for a flutter solution. 
std::pair< Real, Real > _V_range
range of reference values within which to find flutter roots 
std::pair< MAST::FlutterSolutionBase *, MAST::FlutterSolutionBase * > crossover_solutions
virtual const libMesh::NumericVector< Real > & solve()=0
solves for the steady state solution, and 
virtual void scan_for_roots()
Scans for flutter roots in the analyzed points, and identified the divergence (if k_red = 0...
virtual void assemble_reduced_order_quantity_sensitivity(const MAST::FunctionBase &f, std::vector< libMesh::NumericVector< Real > *> &basis, std::map< MAST::StructuralQuantityType, RealMatrixX *> &mat_qty_map)
calculates the sensitivity of reduced order matrix given the basis provided in basis. 
virtual std::pair< bool, MAST::FlutterRootBase * > find_critical_root(const Real g_tol, const unsigned int n_bisection_iters)
This method checks if the flutter root corresponding to the lowest velocity crossover has been calcul...
MAST::StructuralFluidInteractionAssembly * _assembly
structural assembly that provides the assembly of the system matrices. 
unsigned int _n_V_divs
number of division in the reference value range for initial scanning 
RealVectorX modal_participation
virtual void clear_solutions()
clears the solutions stored from a previous analysis. 
void compute(const RealMatrixX &A, const RealMatrixX &B, bool computeEigenvectors=true)
computes the eigensolution for . 
std::map< Real, MAST::FlutterSolutionBase * > _flutter_solutions
map of velocity sorted flutter solutions 
ComplexVectorX eig_vec_right
right and left eigenvevtors 
virtual void clear()
clears the solution and other data from this solver 
bool has_sensitivity_data
void initialize(std::vector< libMesh::NumericVector< Real > *> &basis)
initializes the data structres for a flutter solution. 
void _initialize_matrix_sensitivity_for_param(const MAST::FunctionBase &f, const libMesh::NumericVector< Real > &dXdp, Real U_inf, RealMatrixX &A, RealMatrixX &B)
Assembles the reduced order system structural and aerodynmaic matrices for specified flight velocity ...
virtual std::pair< bool, MAST::FlutterRootBase * > find_next_root(const Real g_tol, const unsigned int n_bisection_iters)
Looks through the list of flutter cross-over points and iteratively zooms in to find the cross-over p...
MAST::FlutterRootBase * root