33 _velocity_param(nullptr),
    36 _V_range(std::pair<
Real, 
Real>(0., 0.)),
    38 _kr_range(std::pair<
Real, 
Real>(0., 0.)),
    59     _V_range          = std::pair<Real, Real>(0.,0.);
    77            unsigned int                                 n_V_divs,
    80            unsigned int                                 n_kr_divs,
    81            std::vector<libMesh::NumericVector<Real>*>& basis) {
   105     std::map<Real, MAST::FlutterSolutionBase*>::iterator it =
   111     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator cross_it =
   115         delete cross_it->second;
   127     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
   132     for ( ; it!=end; it++)
   133         if (it->second->root) 
   154             k_red_vals[i] = current_k_red;
   155             current_k_red -= delta_k_red;
   162         for (
unsigned int j=0; j<_n_k_red_divs+1; j++) {
   164             current_k_red = k_red_vals[j];
   170             std::vector<Real> v_ref_vals(
_n_V_divs+1);
   171             for (
unsigned int i=0; i<
_n_V_divs+1; i++) {
   172                 v_ref_vals[i] = current_v_ref;
   173                 current_v_ref += delta_v_ref;
   182             for (
unsigned int i=0; i<_n_V_divs+1; i++) {
   183                 current_v_ref = v_ref_vals[i];
   184                 std::unique_ptr<MAST::FlutterSolutionBase> sol =
   198                 std::map<Real, MAST::FlutterSolutionBase*>::iterator it =
   202                 prev_sol = it->second;
   220     std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
   223     libmesh_assert(sol_it != sol_end); 
   225     unsigned int nvals = sol_it->second->n_roots();
   226     libmesh_assert(nvals); 
   229     for (
unsigned int i=0; i<nvals; i++)
   234         << std::setw(5) << i << 
" **" << std::endl
   235         << std::setw(15) << 
"kr"   236         << std::setw(15) << 
"g"   237         << std::setw(15) << 
"V" << std::endl;
   243         for ( ; sol_it != sol_end; sol_it++)
   246             sol_it->second->get_root(i);
   249             << std::setw(15) << root.
kr   250             << std::setw(15) << root.
g   251             << std::setw(15) << root.
V << std::endl;
   253         *
_output << std::endl << std::endl;
   258     std::streamsize prec = 
_output->precision();
   262     << 
"n critical roots identified: " << nroots << std::endl;
   263     for (
unsigned int i=0; i<nroots; i++)
   267         << 
"** Root : " << std::setw(5) << i << 
" **" << std::endl
   268         << 
"kr     = " << std::setw(15) << std::setprecision(15) << root.
kr << std::endl
   269         << 
"V      = " << std::setw(15) << std::setprecision(15) << root.
V << std::endl
   270         << 
"g      = " << std::setw(15) << root.
g << std::endl
   271         << 
"omega  = " << std::setw(15) << root.
omega << std::endl
   272         << std::setprecision((
int) prec) 
   273         << 
"Modal Participation : " << std::endl ;
   274         for (
unsigned int j=0; j<nvals; j++)
   276             << 
"(" << std::setw(5) << j << 
"): "   278             << std::setw(3)  << 
" ";
   279         *
_output << std::endl << std::endl;
   291     *
_output << 
"n crossover points found: "   294     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
   299     for ( ; it != end; it++) {
   300         *
_output << 
"** Point : " << std::setw(5) << i << 
" **" << std::endl;
   310 std::pair<bool, MAST::FlutterSolutionBase*>
   313                                         const unsigned int root_num,
   315                                         const unsigned int max_iters) {
   320     lower_k = ref_sol_range.first->get_root(root_num).kr,
   321     lower_v = ref_sol_range.first->get_root(root_num).V,
   322     lower_g = ref_sol_range.first->get_root(root_num).g,
   323     upper_k = ref_sol_range.second->get_root(root_num).kr,
   324     upper_v = ref_sol_range.second->get_root(root_num).V,
   325     upper_g = ref_sol_range.second->get_root(root_num).g,
   326     new_k   = lower_k + (upper_k-lower_k)/(upper_g-lower_g)*(0.-lower_g),
   328     unsigned int n_iters = 0;
   330     std::unique_ptr<MAST::FlutterSolutionBase> new_sol;
   331     std::pair<bool, MAST::FlutterSolutionBase*> rval(
false, 
nullptr);
   333     while (n_iters < max_iters) {
   335         new_v = lower_v + (upper_v-lower_v)/(upper_g-lower_g)*(0.-lower_g); 
   339                                ref_sol_range.first).release());
   348         std::map<Real, MAST::FlutterSolutionBase*>::iterator it =
   352         rval.second = it->second;
   360         if (fabs(root.
g) <= g_tol) {
   392     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
   396     unsigned int root_num = 0;
   397     for ( ; it!=end; it++) {
   398         if (it->second->root) { 
   400                 return *(it->second->root);
   406     libmesh_assert(
false); 
   411 std::pair<bool, MAST::FlutterRootBase*>
   413                                       const unsigned int n_bisection_iters)
   417     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator
   424             const unsigned int root_num = cross->
root_num;
   425             std::pair<bool, MAST::FlutterSolutionBase*> sol;
   434                                       root_num, g_tol, n_bisection_iters);
   436             cross->
root = &(sol.second->get_root(root_num));
   441             std::pair<Real, MAST::FlutterRootCrossoverBase*>
   442             val(cross->
root->
V, cross);
   444             return std::pair<bool, MAST::FlutterRootBase*> (
true, cross->
root);
   451     return std::pair<bool, MAST::FlutterRootBase*> (
false, 
nullptr);
   456 std::pair<bool,  MAST::FlutterRootBase*>
   458                                           const unsigned int n_bisection_iters)
   462     std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator
   466         return std::pair<bool, MAST::FlutterRootBase*> (
false, 
nullptr);
   471     while (!it->second->root)
   477             const unsigned int root_num = cross->
root_num;
   478             std::pair<bool, MAST::FlutterSolutionBase*> sol;
   487                                       root_num, g_tol, n_bisection_iters);
   489             cross->
root = &(sol.second->get_root(root_num));
   494             std::pair<Real, MAST::FlutterRootCrossoverBase*>
   495             val(cross->
root->
V, cross);
   504     return std::pair<bool, MAST::FlutterRootBase*> (
true, it->second->root);
   668     std::map<Real, MAST::FlutterSolutionBase*>::iterator it =
   674                                   (v_ref, sol)).second;
   676         libmesh_assert(if_success);
   685         libmesh_assert_equal_to(it->second->n_roots(), sol->
n_roots());
   687         Real dk_old = 0., k_ref_old = 0., dk_new = 0.;
   690         for (
unsigned int i=0; i<sol->
n_roots(); i++) {
   691             old_root  = &(it->second->get_root(i));
   693             k_ref_old = old_root->
kr;
   694             dk_old    = fabs(fabs(old_root->
kr) - k_ref_old);
   695             dk_new    = fabs(fabs(new_root->
kr) - k_red);
   714     const Real tol = 1.0e-5, max_allowable_g = 0.75;
   718     libmesh_assert(nvals);
   727     std::vector<bool> modes_to_neglect(nvals);
   728     std::fill(modes_to_neglect.begin(),
   729               modes_to_neglect.end(), 
false);
   733     for (
unsigned int i=0; i<nvals; i++) {
   734         std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
   737         Real max_g_val = 0., val = 0.;
   738         for ( ; sol_it!=sol_end; sol_it++) {
   739             val = fabs(sol_it->second->get_root(i).g);
   745             modes_to_neglect[i] = 
true;
   751         std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
   754         if (sol_it == sol_end)
   758         if (fabs(sol_it->second->ref_val()) < tol) { 
   763             for (
unsigned int i=0; i<nvals; i++) {
   764                 if (!sol_it->second->get_root(i).if_nonphysical_root &&
   765                     fabs(sol_it->second->get_root(i).g) < tol) {
   770                     cross->
root = &sol_it->second->get_root(i);
   772                     std::pair<Real, MAST::FlutterRootCrossoverBase*>
   773                     val( cross->
root->
V, cross);
   782     for (
unsigned int i=0; i<nvals; i++) {
   783         std::map<Real, MAST::FlutterSolutionBase*>::const_reverse_iterator
   787         if (sol_rit == sol_rend)
   791         while (sol_ritp1 != sol_rend) {
   793             if (sol_rit->second->get_root(i).if_nonphysical_root ||
   794                 sol_ritp1->second->get_root(i).if_nonphysical_root ||
   795                 fabs(sol_rit->second->ref_val()) < tol ||
   796                 fabs(sol_ritp1->second->ref_val()) < tol ||
   797                 fabs(sol_rit->second->get_root(i).g) > max_allowable_g ||
   798                 fabs(sol_ritp1->second->get_root(i).g) > max_allowable_g) {
   801             else if (!modes_to_neglect[i]) { 
   803                 *upper = sol_ritp1->second;
   806                     (upper->get_root(i).g > 0.)) {
   812                     std::pair<Real, MAST::FlutterRootCrossoverBase*>
   817                          (upper->get_root(i).g <= 0.)) {
   823                     std::pair<Real, MAST::FlutterRootCrossoverBase*>
   824                     val( upper->get_root(i).V, cross);
   838 std::unique_ptr<MAST::FlutterSolutionBase>
   847     << 
" ====================================================" << std::endl
   848     << 
"PK Solution" << std::endl
   849     << 
"   k_red = " << std::setw(10) << k_red << std::endl
   850     << 
"   V_ref = " << std::setw(10) << v_ref << std::endl;
   863         root->
sort(*prev_sol);
   866     << 
"Finished PK Solution" << std::endl
   867     << 
" ====================================================" << std::endl;
   870     return std::unique_ptr<MAST::FlutterSolutionBase> (root);
   987     m      =  RealMatrixX::Zero(n, n),
   988     k      =  RealMatrixX::Zero(n, n);
   991     a      =  ComplexMatrixX::Zero(n, n);
   996     std::map<MAST::StructuralQuantityType, RealMatrixX*> qty_map;
  1002     (*_kred_param)      = k_red;
  1003     (*_velocity_param)  = v_ref;
  1008     assemble_generalized_aerodynamic_force_matrix(*
_basis_vectors, a);
  1018     A.topRightCorner    (n, n)    =  ComplexMatrixX::Identity(n, n);
  1019     A.bottomLeftCorner  (n, n)    = -k.cast<
Complex>() + 
_rho/2.*v_ref*v_ref*a;
  1020     B.topLeftCorner     (n, n)    = ComplexMatrixX::Identity(n, n);
  1021     B.bottomRightCorner (n, n)    = m.cast<
Complex>();
 
void _insert_new_solution(const Real k_red_ref, MAST::FlutterSolutionBase *sol)
virtual void copy_root(const MAST::FlutterRootBase &f)
virtual std::unique_ptr< MAST::FlutterSolutionBase > _analyze(const Real k_red, const Real v_ref, const MAST::FlutterSolutionBase *prev_sol=nullptr)
Newton method to look for cross-over point method search. 
std::vector< libMesh::NumericVector< Real > * > * _basis_vectors
basis vector used to define the reduced order model 
void _initialize_matrices(const Real k_red, const Real v_ref, ComplexMatrixX &L, ComplexMatrixX &R, RealMatrixX &stiff)
initializes the matrices for the specified k_red. 
virtual void sort(const MAST::FlutterSolutionBase &sol)
sort this root with respect to the given solution from a previous eigen solution. ...
virtual ~PKFlutterSolver()
unsigned int n_roots() const
number of roots in this solution 
virtual void compute(const ComplexMatrixX &A, const ComplexMatrixX &B, bool computeEigenvectors=true)
computes the eigensolution for . 
void initialize(MAST::Parameter &V_param, MAST::Parameter &kr_param, MAST::Parameter &bref_param, Real rho, Real V_lower, Real V_upper, unsigned int n_V_divs, Real kr_lower, Real kr_upper, unsigned int n_kr_divs, std::vector< libMesh::NumericVector< Real > *> &basis)
initializes the data structres for a flutter solution. 
unsigned int _n_k_red_divs
number of division in the reference value range for initial scanning 
This is a scalar function whose value can be changed and one that can be used as a design variable in...
std::pair< Real, Real > _kr_range
range of reference values within which to find flutter roots 
std::multimap< Real, MAST::FlutterRootCrossoverBase * > _flutter_crossovers
the map of flutter crossover points versus average velocity of the two bounding roots ...
void _initialize_matrix_sensitivity_for_param(const MAST::FunctionBase &f, const Real k_red, const Real U_inf, ComplexMatrixX &L, ComplexMatrixX &R)
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...
Real ref_val() const
the reduced frequency for this solution 
unsigned int _n_V_divs
number of division in the reference value range for initial scanning 
virtual void calculate_sensitivity(MAST::FlutterRootBase &root, const MAST::FunctionBase &f)
Calculate the sensitivity of the flutter root with respect to the parameter f. 
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)
virtual void clear_solutions()
clears the solutions stored from a previous analysis. 
virtual void scan_for_roots()
Scans for flutter roots in the analyzed points, and identified the divergence (if k_red = 0...
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 clear()
clears the solution and other data from this solver 
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...
Matrix< Real, Dynamic, Dynamic > RealMatrixX
Matrix< Complex, Dynamic, Dynamic > ComplexMatrixX
const MAST::FlutterRootBase & get_root(const unsigned int i) const
virtual void print_crossover_points()
Prints the crossover points output. 
virtual void print_sorted_roots()
Prints the sorted roots to the output. 
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 unsigned int n_roots_found() const
finds the number of critical points already identified in the procedure. 
virtual void _identify_crossover_points()
identifies all cross-over and divergence points from analyzed roots 
std::pair< MAST::FlutterSolutionBase *, MAST::FlutterSolutionBase * > crossover_solutions
virtual void init(const MAST::PKFlutterSolver &solver, const Real k_red, const Real v_ref, const Real bref, const RealMatrixX &kmat, const MAST::LAPACK_ZGGEV &eig_sol)
initializes the flutter solution from an eigensolution 
MAST::Parameter * _kred_param
Parameter that define the reduced frequency. 
MAST::StructuralFluidInteractionAssembly * _assembly
structural assembly that provides the assembly of the system matrices. 
MAST::Parameter * _velocity_param
Parameter that define the velocity. 
std::pair< Real, Real > _V_range
range of reference values within which to find flutter roots 
RealVectorX modal_participation
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...
virtual void clear()
clears the solution and other data from this solver 
MAST::Parameter * _bref_param
reference chord 
void initialize(std::vector< libMesh::NumericVector< Real > *> &basis)
initializes the data structres for a flutter solution. 
MAST::FlutterRootBase * root
std::map< Real, MAST::FlutterSolutionBase * > _flutter_solutions
map of velocity sorted flutter solutions