41 _include_highest_kr_unstable(false) {
78 unsigned int n_kr_divs,
79 std::vector<libMesh::NumericVector<Real> *>& basis) {
98 std::map<Real, MAST::FlutterSolutionBase*>::iterator it =
104 std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator cross_it =
108 delete cross_it->second;
120 std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
125 for ( ; it!=end; it++)
126 if (it->second->root)
141 std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
145 unsigned int root_num = 0;
146 for ( ; it!=end; it++) {
147 if (it->second->root) {
149 return *(it->second->root);
155 libmesh_assert(
false);
162 std::pair<bool, MAST::FlutterRootBase*>
164 const unsigned int n_bisection_iters)
168 std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator
175 const unsigned int root_num = cross->
root_num;
176 std::pair<bool, MAST::FlutterSolutionBase*> sol;
185 root_num, g_tol, n_bisection_iters);
187 cross->
root = &(sol.second->get_root(root_num));
192 std::pair<Real, MAST::FlutterRootCrossoverBase*>
193 val(cross->
root->
V, cross);
195 return std::pair<bool, MAST::FlutterRootBase*> (
true, cross->
root);
202 return std::pair<bool, MAST::FlutterRootBase*> (
false,
nullptr);
207 std::pair<bool, MAST::FlutterRootBase*>
209 const unsigned int n_bisection_iters)
213 std::multimap<Real, MAST::FlutterRootCrossoverBase*>::iterator
217 return std::pair<bool, MAST::FlutterRootBase*> (
false,
nullptr);
222 while (!it->second->root)
228 const unsigned int root_num = cross->
root_num;
229 std::pair<bool, MAST::FlutterSolutionBase*> sol;
238 root_num, g_tol, n_bisection_iters);
240 cross->
root = &(sol.second->get_root(root_num));
245 std::pair<Real, MAST::FlutterRootCrossoverBase*>
246 val(cross->
root->
V, cross);
255 return std::pair<bool, MAST::FlutterRootBase*> (
true, it->second->root);
273 k_vals[i] = current_kr;
274 current_kr -= delta_kr;
279 for (
unsigned int i=0; i< _n_kr_divs+1; i++) {
281 current_kr = k_vals[i];
282 std::unique_ptr<MAST::FlutterSolutionBase> sol =
285 prev_sol = sol.get();
293 (current_kr, sol.release())).second;
295 libmesh_assert(if_success);
314 std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
317 libmesh_assert(sol_it != sol_end);
319 unsigned int nvals = sol_it->second->n_roots();
320 libmesh_assert(nvals);
323 for (
unsigned int i=0; i<nvals; i++)
328 << std::setw(5) << i <<
" **" << std::endl
329 << std::setw(15) <<
"kr" 330 << std::setw(15) <<
"g" 331 << std::setw(15) <<
"V" << std::endl;
337 for ( ; sol_it != sol_end; sol_it++)
340 sol_it->second->get_root(i);
343 << std::setw(15) << root.
kr 344 << std::setw(15) << root.
g 345 << std::setw(15) << root.
V << std::endl;
347 *
_output << std::endl << std::endl;
352 std::streamsize prec =
_output->precision();
356 <<
"n critical roots identified: " << nroots << std::endl;
357 for (
unsigned int i=0; i<nroots; i++)
361 <<
"** Root : " << std::setw(5) << i <<
" **" << std::endl
362 <<
"kr = " << std::setw(15) << std::setprecision(15) << root.
kr << std::endl
363 <<
"V = " << std::setw(15) << std::setprecision(15) << root.
V << std::endl
364 <<
"g = " << std::setw(15) << root.
g << std::endl
365 <<
"omega = " << std::setw(15) << root.
omega << std::endl
366 << std::setprecision((
int) prec)
367 <<
"Modal Participation : " << std::endl ;
368 for (
unsigned int j=0; j<nvals; j++)
370 <<
"(" << std::setw(5) << j <<
"): " 372 << std::setw(3) <<
" ";
373 *
_output << std::endl << std::endl;
385 *
_output <<
"n crossover points found: " 388 std::multimap<Real, MAST::FlutterRootCrossoverBase*>::const_iterator
393 for ( ; it != end; it++) {
394 *
_output <<
"** Point : " << std::setw(5) << i <<
" **" << std::endl;
405 std::pair<bool, MAST::FlutterSolutionBase*>
409 const unsigned int root_num,
411 const unsigned int max_iters) {
416 lower_kr = ref_sol_range.first->get_root(root_num).kr,
417 lower_g = ref_sol_range.first->get_root(root_num).g,
418 upper_kr = ref_sol_range.second->get_root(root_num).kr,
419 upper_g = ref_sol_range.second->get_root(root_num).g,
421 unsigned int n_iters = 0;
424 std::pair<bool, MAST::FlutterSolutionBase*> rval(
false,
nullptr);
426 while (n_iters < max_iters) {
430 << upper_g <<
" " << std::endl
432 << lower_g <<
" " << std::endl;
435 (upper_kr-lower_kr)/(upper_g-lower_g)*(0.-lower_g);
437 new_sol =
_analyze(new_kr, ref_sol_range.first).release();
445 (new_kr, new_sol)).second;
447 libmesh_assert(if_success);
453 if (fabs(root.
g) <= g_tol) {
456 rval.second = new_sol;
477 rval.second = new_sol;
485 std::unique_ptr<MAST::FlutterSolutionBase>
490 <<
" ====================================================" << std::endl
491 <<
"Eigensolution" << std::endl
492 <<
" kr_ref = " << std::setw(10) << kr_ref << std::endl;
508 root->
sort(*prev_sol);
511 <<
"Finished Eigensolution" << std::endl
512 <<
" ====================================================" << std::endl;
515 return std::unique_ptr<MAST::FlutterSolutionBase> (root);
536 m = RealMatrixX::Zero(n, n),
537 k = RealMatrixX::Zero(n, n);
540 a = ComplexMatrixX::Zero(n, n);
544 std::map<MAST::StructuralQuantityType, RealMatrixX*> qty_map;
555 assemble_generalized_aerodynamic_force_matrix(*
_basis_vectors, a);
579 const libMesh::NumericVector<Real>& dXdp,
594 m = RealMatrixX::Zero(n, n),
595 k = RealMatrixX::Zero(n, n);
598 a = ComplexMatrixX::Zero(n, n);
602 std::map<MAST::StructuralQuantityType, RealMatrixX*> qty_map;
654 m = RealMatrixX::Zero(n, n);
657 a = ComplexMatrixX::Zero(n, n);
661 std::map<MAST::StructuralQuantityType, RealMatrixX*> qty_map;
684 B = ComplexMatrixX::Zero(n, n);
695 const Real tol = 1.0e-5, max_allowable_g = 0.75;
699 libmesh_assert(nvals);
708 std::vector<bool> modes_to_neglect(nvals);
709 std::fill(modes_to_neglect.begin(),
710 modes_to_neglect.end(),
false);
714 for (
unsigned int i=0; i<nvals; i++) {
715 std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
718 Real max_g_val = 0., val = 0.;
719 for ( ; sol_it!=sol_end; sol_it++) {
720 val = fabs(sol_it->second->get_root(i).g);
726 modes_to_neglect[i] =
true;
732 std::map<Real, MAST::FlutterSolutionBase*>::const_iterator
735 if (sol_it == sol_end)
739 if (fabs(sol_it->second->ref_val()) < tol) {
744 for (
unsigned int i=0; i<nvals; i++) {
745 if (!sol_it->second->get_root(i).if_nonphysical_root &&
746 fabs(sol_it->second->get_root(i).g) < tol) {
751 cross->
root = &sol_it->second->get_root(i);
753 std::pair<Real, MAST::FlutterRootCrossoverBase*>
754 val( cross->
root->
V, cross);
763 for (
unsigned int i=0; i<nvals; i++) {
764 std::map<Real, MAST::FlutterSolutionBase*>::const_reverse_iterator
768 if (sol_rit == sol_rend)
772 bool if_process =
false;
774 while (sol_ritp1 != sol_rend) {
777 (!sol_rit->second->get_root(i).if_nonphysical_root &&
778 !sol_ritp1->second->get_root(i).if_nonphysical_root) &&
780 (fabs(sol_rit->second->ref_val()) > tol ||
781 fabs(sol_ritp1->second->ref_val()) > tol) &&
783 (fabs(sol_rit->second->get_root(i).g) < max_allowable_g &&
784 fabs(sol_ritp1->second->get_root(i).g) < max_allowable_g) &&
787 !modes_to_neglect[i]);
792 *upper = sol_ritp1->second;
795 (upper->get_root(i).g > 0.)) {
801 std::pair<Real, MAST::FlutterRootCrossoverBase*>
806 (upper->get_root(i).g <= 0.)) {
812 std::pair<Real, MAST::FlutterRootCrossoverBase*>
813 val( upper->get_root(i).V, cross);
831 (!sol_rit->second->get_root(i).if_nonphysical_root &&
832 !sol_ritp1->second->get_root(i).if_nonphysical_root) &&
834 (fabs(sol_rit->second->ref_val()) > tol ||
835 fabs(sol_ritp1->second->ref_val()) > tol) &&
837 (fabs(sol_rit->second->get_root(i).g) < max_allowable_g &&
838 fabs(sol_ritp1->second->get_root(i).g) < max_allowable_g) &&
841 !modes_to_neglect[i]);
843 Real g_val = sol_rit->second->get_root(i).g;
846 g_val < max_allowable_g &&
858 std::pair<Real, MAST::FlutterRootCrossoverBase*>
859 val( sol_rit->second->get_root(i).V, cross);
873 libMesh::NumericVector<Real>* dXdp,
874 libMesh::NumericVector<Real>* dXdkr) {
879 <<
" ====================================================" << std::endl
880 <<
"UG Sensitivity Solution" << std::endl
881 <<
" k_red = " << std::setw(10) << root.
kr << std::endl
882 <<
" V_ref = " << std::setw(10) << root.
V << std::endl;
910 libMesh::NumericVector<Real>* sol_sens = dXdp;
911 std::unique_ptr<libMesh::NumericVector<Real> > zero_sol_sens;
913 zero_sol_sens.reset(
_assembly->
system().solution->zero_clone().release());
914 sol_sens = zero_sol_sens.get();
944 sol_sens = zero_sol_sens.get();
965 deig_dp.imag()/eig.real() - eig.imag()/pow(eig.real(),2) * deig_dp.real();
967 deig_dkr.imag()/eig.real() - eig.imag()/pow(eig.real(),2) * deig_dkr.real();
975 dkr_dp = -dg_dp / dg_dkr;
980 root.
root_sens = deig_dp + deig_dkr * dkr_dp;
985 <<
"Finished Flutter Sensitivity Solution" << std::endl
986 <<
" ====================================================" << std::endl;
unsigned int _n_kr_divs
number of division in the reference value range for initial scanning
const MAST::NonlinearSystem & system() const
virtual ~UGFlutterSolver()
ComplexVectorX eig_vec_left
std::vector< libMesh::NumericVector< Real > * > * _basis_vectors
basis vector used to define the reduced order model
virtual void compute(const ComplexMatrixX &A, const ComplexMatrixX &B, bool computeEigenvectors=true)
computes the eigensolution for .
virtual void print(std::ostream &output)=0
prints the data and modes from this solution
virtual void print_sorted_roots()
Prints the sorted roots to the output.
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
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.
std::ofstream * _output
file to which the result will be written
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 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.
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 print_crossover_points()
Prints the crossover points output.
Matrix< Real, Dynamic, Dynamic > RealMatrixX
Matrix< Complex, Dynamic, Dynamic > ComplexMatrixX
bool _include_highest_kr_unstable
flag allows check to see if the root started out as critical at the highest k value.
const MAST::FlutterRootBase & get_root(const unsigned int i) const
virtual void calculate_sensitivity(MAST::FlutterRootBase &root, const MAST::FunctionBase &f, libMesh::NumericVector< Real > *dXdp=nullptr, libMesh::NumericVector< Real > *dXdkr=nullptr)
Calculate the sensitivity of the flutter root with respect to the f parameter.
std::pair< Real, Real > _kr_range
range of reference values within which to find flutter roots
void _initialize_matrix_sensitivity_for_param(const MAST::FunctionBase &f, const libMesh::NumericVector< Real > &dXdp, Real kr, ComplexMatrixX &A, ComplexMatrixX &B)
Assembles the reduced order system structural and aerodynmaic matrices for specified flight velocity ...
void _initialize_matrices(Real kr, ComplexMatrixX &A, ComplexMatrixX &B)
Assembles the reduced order system structural and aerodynmaic matrices for specified reduced freq kr...
void init(const MAST::UGFlutterSolver &solver, const Real v_ref, const Real b_ref, const MAST::LAPACK_ZGGEV_Base &eig_sol)
initializes the root
virtual void scan_for_roots()
Scans for flutter roots in the analyzed points, and identified the divergence (if k_red = 0...
std::multimap< Real, MAST::FlutterRootCrossoverBase * > _flutter_crossovers
the map of flutter crossover points versus average kr of the two bounding roots
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
void _initialize_matrix_sensitivity_for_kr(Real kr, ComplexMatrixX &A, ComplexMatrixX &B)
Assembles the sensitivity of matrices wrt kr.
MAST::Parameter * _bref_param
reference chord
MAST::Parameter * _kr_param
Parameter that define the reduced frequency.
std::pair< MAST::FlutterSolutionBase *, MAST::FlutterSolutionBase * > crossover_solutions
virtual void _identify_crossover_points()
identifies all cross-over and divergence points from analyzed roots
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 void sort(const MAST::FlutterSolutionBase &sol)
sort this root with respect to the given solution from a previous eigen solution. ...
std::map< Real, MAST::FlutterSolutionBase * > _flutter_solutions
map of kr sorted flutter solutions
virtual std::unique_ptr< MAST::FlutterSolutionBase > _analyze(const Real kr_ref, const MAST::FlutterSolutionBase *prev_sol=nullptr)
performs an eigensolution at the specified reference value, and sort the roots based on the provided ...
void initialize(MAST::Parameter &kr_param, MAST::Parameter &bref_param, Real rho, 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.
MAST::StructuralFluidInteractionAssembly * _assembly
structural assembly that provides the assembly of the system matrices.
RealVectorX modal_participation
ComplexVectorX eig_vec_right
right and left eigenvevtors
UGFlutterSolver()
defalut constructor
void clear()
clears the solution and other data from this solver
virtual void clear()
clears the solution and other data from this solver
virtual void clear_solutions()
clears the solutions stored from a previous analysis.
bool has_sensitivity_data
void initialize(std::vector< libMesh::NumericVector< Real > *> &basis)
initializes the data structres for a flutter solution.
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