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::FlutterRootBase & get_root(const unsigned int i) 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 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_sorted_roots()
Prints the sorted roots to the output.
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.
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...
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.
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...
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
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.
bool _include_highest_kr_unstable
flag allows check to see if the root started out as critical at the highest k value.
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
void _initialize_matrix_sensitivity_for_kr(Real kr, ComplexMatrixX &A, ComplexMatrixX &B)
Assembles the sensitivity of matrices wrt kr.
void initialize(std::vector< libMesh::NumericVector< Real > * > &basis)
initializes the data structres for a flutter solution.
MAST::Parameter * _bref_param
reference chord
MAST::Parameter * _kr_param
Parameter that define the reduced frequency.
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 _identify_crossover_points()
identifies all cross-over and divergence points from analyzed roots
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 ...
MAST::StructuralFluidInteractionAssembly * _assembly
structural assembly that provides the assembly of the system matrices.
RealVectorX modal_participation
ComplexVectorX eig_vec_right
right and left eigenvevtors
const MAST::NonlinearSystem & system() const
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
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