Source code for feastruct.solvers.linstatic

from feastruct.solvers.feasolve import Solver


[docs]class LinearStatic(Solver): """Class for a linear static 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 LinearStatic 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, analysis_cases=analysis_cases, solver_settings=solver_settings)
[docs] def solve(self): """Executes the linear static finite element solver and saves the relevant results.""" if self.solver_settings.linear_static.time_info: print('\n-Starting the linear static solver...\n') # 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() # assemble the global stiffness matrix if self.solver_settings.linear_static.time_info: str = '--Assembling the global stiffness matrix...' (K, _) = self.function_timer(str, self.assemble_stiff_matrix) else: (K, _) = self.assemble_stiff_matrix() # loop through each analysis case for (i, analysis_case) in enumerate(self.analysis_cases): if self.solver_settings.linear_static.time_info: print('\n--Analysis case {0}:'.format(i)) # assemble the external force vector if self.solver_settings.linear_static.time_info: str = '---Assembling the external force vector...' (f_ext, f_eq) = self.function_timer(str, self.assemble_fext, analysis_case) else: (f_ext, f_eq) = self.assemble_fext(analysis_case=analysis_case) # apply the equivalent nodal loads f_ext -= f_eq # apply the boundary conditions (K_mod, f_ext) = self.apply_bcs(K=K, f_ext=f_ext, analysis_case=analysis_case) # solve for the displacement vector if self.solver_settings.linear_static.solver_type == 'direct': solver_func = self.direct_solver elif self.solver_settings.linear_static.solver_type == 'cgs': solver_func = self.cgs_solver if self.solver_settings.linear_static.time_info: str = '---Solving for the displacement vector using the {0} solver...'.format( self.solver_settings.linear_static.solver_type) u = self.function_timer(str, solver_func, K_mod, f_ext) else: u = solver_func(K_mod, f_ext) # save the displacements to the DoF objects inside the Node objects self.save_displacements(u=u, analysis_case=analysis_case) # calculate the reaction forces if self.solver_settings.linear_static.time_info: str = '---Calculating reactions...' self.function_timer(str, self.calculate_reactions, K, u, f_eq, analysis_case) else: self.calculate_reactions(K=K, u=u, f_eq=f_eq, analysis_case=analysis_case) # calculate the element stresses if self.solver_settings.linear_static.time_info: str = '---Calculating element stresses...' self.function_timer(str, self.calculate_stresses, analysis_case) else: self.calculate_stresses(analysis_case=analysis_case)