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)
const MAST::FlutterRootBase & get_root(const unsigned int i) const
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()
virtual void compute(const ComplexMatrixX &A, const ComplexMatrixX &B, bool computeEigenvectors=true)
computes the eigensolution for .
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)
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...
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 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
unsigned int n_roots() const
number of roots in this solution
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
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_crossover_points()
Prints the crossover points output.
virtual void print_sorted_roots()
Prints the sorted roots to the output.
void initialize(std::vector< libMesh::NumericVector< Real > * > &basis)
initializes the data structres for a flutter solution.
virtual unsigned int n_roots_found() const
finds the number of critical points already identified in the procedure.
Real ref_val() const
the reduced frequency for this solution
virtual void _identify_crossover_points()
identifies all cross-over and divergence points from analyzed roots
std::pair< MAST::FlutterSolutionBase *, MAST::FlutterSolutionBase * > crossover_solutions
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 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
MAST::FlutterRootBase * root
std::map< Real, MAST::FlutterSolutionBase * > _flutter_solutions
map of velocity sorted flutter solutions
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.