Source code for feastruct.solvers.naturalfrequency

import numpy as np
from feastruct.solvers.feasolve import Solver


[docs]class NaturalFrequency(Solver): """Class for a natural frequency solver. :cvar analysis: Analysis object to solve :vartype analysis: :class:`~feastruct.fea.fea.FiniteElementAnalysis` :cvar analysis_cases: List of analysis cases to solve :vartype analysis_cases: list[:class:`~feastruct.fea.cases.AnalysisCase`] :cvar solver_settings: Settings to use in the solver :vartype solver_settings: :class:`~feastruct.solvers.feasolve.SolverSettings` :cvar int ndof: Number of degrees of freedom in the analysis """
[docs] def __init__(self, analysis, analysis_cases, solver_settings=None): """Inits the NaturalFrequency class. :param analysis: Analysis object to solve :type analysis: :class:`~feastruct.fea.fea.FiniteElementAnalysis` :param analysis_cases: List of analysis cases to solve :type analysis_cases: list[:class:`~feastruct.fea.cases.AnalysisCase`] :param solver_settings: Settings to use in the solver - if not supplied, the default settings are adopted :type solver_settings: :class:`~feastruct.solvers.feasolve.SolverSettings` """ super().__init__(analysis, analysis_cases, solver_settings)
# TODO: check that analysis_case results available
[docs] def solve(self): """Executes the natural frequency finite element solver and saves the relevant results.""" if self.solver_settings.natural_frequency.time_info: print('\n-Starting the natural frequency solver...') # assign the global degree of freedom numbers if self.solver_settings.linear_static.time_info: str = '--Assigning the global degree of freedom numbers...' self.function_timer(str, self.assign_dofs) else: self.assign_dofs() # loop through each analysis case for (i, analysis_case) in enumerate(self.analysis_cases): if self.solver_settings.natural_frequency.time_info: print('\n--Analysis case {0}:'.format(i)) # assemble the global stiffness matrix if self.solver_settings.natural_frequency.time_info: str = '---Assembling the global stiffness matrix...' (K, _) = self.function_timer(str, self.assemble_stiff_matrix) else: (K, _) = self.assemble_stiff_matrix() # assemble the global mass matrix if self.solver_settings.natural_frequency.time_info: str = '---Assembling the global mass matrix...' M = self.function_timer(str, self.assemble_mass_matrix) else: M = self.assemble_mass_matrix() # apply the boundary conditions K_mod = self.remove_constrained_dofs(K=K, analysis_case=analysis_case) M_mod = self.remove_constrained_dofs(K=M, analysis_case=analysis_case) # solve for the eigenvalues if self.solver_settings.natural_frequency.time_info: str = '---Solving for eigenvalues and eigenvectors ({0} modes)...'.format( self.solver_settings.natural_frequency.num_modes) (w, v) = self.function_timer( str, self.solve_eigenvalue, K_mod, M_mod, self.solver_settings.natural_frequency) else: (w, v) = self.solve_eigenvalue( A=K_mod, M=M_mod, eigen_settings=self.solver_settings.natural_frequency) # compute natural frequencies in Hz w = np.sqrt(w) / 2 / np.pi self.save_frequency_results(w=w, v=v, analysis_case=analysis_case)