def update_derived_params(self, ea, ga, gj, eiy, eiz, mu, j_tors): ### Derived # time-step self.dt = self.main_chord / self.M / self.u_inf * self.dt_factor self.n_tstep = int(np.round(self.physical_time / self.dt)) # angles self.alpha_rad = self.alpha * np.pi / 180. self.roll_rad = self.roll * np.pi / 180. self.beta_rad = self.beta * np.pi / 180. self.sweep_rad = self.sweep * np.pi / 180. # FoR A orientation if self.RollNodes: self.quat = algebra.euler2quat( np.array([0., self.alpha_rad, self.beta_rad])) else: if np.abs(self.roll) > 1e-3: warnings.warn( 'FoR A quaternion will be built with inverted '+\ 'roll angle sign to compensate bug in algebra.euler2quat') self.quat = algebra.euler2quat( np.array([-self.roll_rad, self.alpha_rad, self.beta_rad])) # geometry self.wing_span = self.aspect_ratio * self.main_chord #/np.cos(self.sweep_rad) self.S = self.wing_span * self.main_chord # discretisation assert self.n_surfaces < 3, "use 1 or 2 surfaces only!" assert self.N%2 != 1,\ 'UVLM spanwise panels must be even when using 3-noded FEs!' self.num_elem_tot = self.N // 2 assert self.num_elem_tot%self.n_surfaces != 1,\ "Can't distribute equally FEM elements over surfaces" self.num_elem_surf = self.num_elem_tot // self.n_surfaces self.num_node_surf = self.N // self.n_surfaces + 1 self.num_node_tot = self.N + 1 # FEM connectivity, coords definition and mapping self.update_fem_prop() # Mass/stiffness properties # self.update_mass_stiff() self.update_mass_stiff(ea, ga, gj, eiy, eiz, mu, j_tors) # Aero props self.update_aero_prop()
def wing_tip_deflection(self, frame='a', alpha=0, reference_line=np.array([0, 0, 0], dtype=float)): param_array = [] deflection = [] if frame == 'g': try: import sharpy.utils.algebra as algebra except ModuleNotFoundError: raise (ModuleNotFoundError('Please load sharpy')) else: cga = algebra.quat2rotation( algebra.euler2quat(np.array([0, alpha * np.pi / 180, 0]))) for case in self.cases['aeroelastic']: param_array.append(case.parameter_value) if frame == 'a': deflection.append( case.get_deflection_at_line(reference_line)[-1, -3:]) elif frame == 'g': deflection.append( cga.dot( case.get_deflection_at_line(reference_line)[-1, -3:])) param_array = np.array(param_array) order = np.argsort(param_array) param_array = param_array[order] deflection = np.array([deflection[ith] for ith in order]) return param_array, deflection
def test_rotation_G_to_A(self): """ Tests the rotation of a vector in G frame to a vector in A frame by a roll, pitch and yaw considering that SHARPy employs an SEU frame. In the inertial frame, the ``x_g`` axis is aligned with the longitudinal axis of the aircraft pointing backwards, ``z_g`` points upwards and ``y_g`` completes the set Returns: """ aircraft_nose = np.array([-1, 0, 0]) z_A = np.array([0, 0, 1]) euler = np.array([90, 90, 90]) * np.pi / 180 quat = algebra.euler2quat(euler) aircraft_nose_rotated = np.array([0, 0, 1]) # in G frame pointing upwards z_A_rotated_g = np.array([1, 0, 0]) Cga = algebra.euler2rot(euler) Cga_quat = algebra.quat2rotation(quat) np.testing.assert_array_almost_equal( Cga.dot(aircraft_nose), aircraft_nose_rotated, err_msg='Rotation using Euler angles not performed properly') np.testing.assert_array_almost_equal( Cga_quat.dot(aircraft_nose), aircraft_nose_rotated, err_msg='Rotation using quaternions not performed properly') np.testing.assert_array_almost_equal( Cga.dot(z_A), z_A_rotated_g, err_msg='Rotation using Euler angles not performed properly') np.testing.assert_array_almost_equal( Cga_quat.dot(z_A), z_A_rotated_g, err_msg='Rotation using quaternions not performed properly') # Check projections Pag = Cga.T Pag_quat = Cga_quat.T np.testing.assert_array_almost_equal( Pag.dot(z_A_rotated_g), z_A, err_msg='Error in projection from A to G using Euler angles') np.testing.assert_array_almost_equal( Pag.dot(aircraft_nose_rotated), aircraft_nose, err_msg='Error in projection from A to G using Euler angles') np.testing.assert_array_almost_equal( Pag_quat.dot(z_A_rotated_g), z_A, err_msg='Error in projection from A to G using quaternions') np.testing.assert_array_almost_equal( Pag_quat.dot(aircraft_nose_rotated), aircraft_nose, err_msg='Error in projection from A to G using quaternions')
def change_trim(self, alpha, thrust, thrust_nodes, tail_deflection, tail_cs_index): # self.cleanup_timestep_info() self.data.structure.timestep_info = [] self.data.structure.timestep_info.append( self.data.structure.ini_info.copy()) aero_copy = self.data.aero.timestep_info[-1] self.data.aero.timestep_info = [] self.data.aero.timestep_info.append(aero_copy) self.data.ts = 0 # alpha orientation_quat = algebra.euler2quat(np.array([0.0, alpha, 0.0])) self.data.structure.timestep_info[0].quat[:] = orientation_quat[:] try: self.force_orientation except AttributeError: self.force_orientation = np.zeros((len(thrust_nodes), 3)) for i_node, node in enumerate(thrust_nodes): self.force_orientation[i_node, :] = (algebra.unit_vector( self.data.structure.ini_info.steady_applied_forces[node, 0:3])) # print(self.force_orientation) # thrust # thrust is scaled so that the direction of the forces is conserved # in all nodes. # the `thrust` parameter is the force PER node. # if there are two or more nodes in thrust_nodes, the total forces # is n_nodes_in_thrust_nodes*thrust # thrust forces have to be indicated in structure.ini_info # print(algebra.unit_vector(self.data.structure.ini_info.steady_applied_forces[0, 0:3])*thrust) for i_node, node in enumerate(thrust_nodes): # self.data.structure.ini_info.steady_applied_forces[i_node, 0:3] = ( # algebra.unit_vector(self.data.structure.ini_info.steady_applied_forces[i_node, 0:3])*thrust) self.data.structure.ini_info.steady_applied_forces[node, 0:3] = ( self.force_orientation[i_node, :] * thrust) self.data.structure.timestep_info[0].steady_applied_forces[ node, 0:3] = (self.force_orientation[i_node, :] * thrust) # tail deflection try: self.data.aero.aero_dict['control_surface_deflection'][ tail_cs_index] = tail_deflection except KeyError: raise Exception('This model has no control surfaces') except IndexError: raise Exception( 'The tail control surface index > number of surfaces') # update grid self.aero_solver.update_step()
def generate_solver_file(horseshoe=False): file_name = route + '/' + case_name + '.sharpy' # config = configparser.ConfigParser() import configobj config = configobj.ConfigObj() config.filename = file_name config['SHARPy'] = { 'case': case_name, 'route': route, 'flow': [ 'BeamLoader', 'AerogridLoader', 'StaticCoupled', 'DynamicCoupled', # 'AerogridPlot', # 'BeamPlot', ], 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } config['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) } config['StaticCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-5, 'min_delta': 1e-13, 'gravity_on': 'on', 'gravity': 9.754, 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) }, 'aero_solver': 'StaticUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho, 'alpha': alpha_rad, 'beta': beta }, 'max_iter': 80, 'n_load_steps': 1, 'tolerance': 1e-5, 'relaxation_factor': 0.0 } config['DynamicCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearDynamicMultibody', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 550, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': 1e-6, 'newmark_damp': 1e-2, 'gravity_on': 'on', 'gravity': 9.754, 'num_steps': num_steps, 'dt': dt }, 'aero_solver': 'StepUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 1, 'convection_scheme': 3, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'gamma_dot_filter': 9, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': 10.0 * main_chord, 'gust_intensity': 0.15 * u_inf, 'offset': 20.0, 'span': main_span, 'relative_motion': 'on' }, 'rho': rho, 'n_time_steps': num_steps, 'dt': dt }, 'controller_id': ['controller_tip'], 'controller_type': { 'controller_tip': 'ControlSurfacePidController' }, 'controller_settings': { 'controller_tip': { 'P': gains[0], 'I': gains[1], 'D': gains[2], 'dt': dt, 'input_type': 'roll', 'controller_log_route': './output/' + case_name + '/', 'controlled_surfaces': 0, 'time_history_input_file': 'roll.csv' } }, 'postprocessors': ['BeamLoads', 'BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'BeamLoads': {}, 'BeamPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 } }, 'fsi_substeps': 100, # 'fsi_substeps': 1, 'fsi_tolerance': 1e-5, 'relaxation_factor': 0.2, 'dynamic_relaxation': 'off', 'minimum_steps': 1, 'relaxation_steps': 25, 'include_unsteady_force_contribution': 'off', 'steps_without_unsteady_force': 10, 'pseudosteps_ramp_unsteady_force': 6, 'structural_substeps': n_structural_substeps, 'n_time_steps': num_steps, 'dt': dt, 'structural_substeps': 0 } if horseshoe is True: config['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['1', '0', '0'] } else: config['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', 'mstar': int(m_main * wake_length), 'freestream_dir': ['1', '0', '0'] } config['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 } config['AeroForcesCalculator'] = { 'folder': route + '/output/forces', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } config['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' } config['BeamCsvOutput'] = { 'folder': route + '/output/', 'output_pos': 'on', 'output_psi': 'on', 'output_for_pos': 'on', 'screen_output': 'off' } config.write()
def generate_solver_file(horseshoe=False): import sharpy.utils.algebra as algebra file_name = route + '/' + case_name + '.sharpy' # config = configparser.ConfigParser() import configobj config = configobj.ConfigObj() config.filename = file_name config['SHARPy'] = { 'case': case_name, 'route': route, 'flow': [ 'BeamLoader', 'AerogridLoader', 'StaticUvlm', 'AerogridPlot', 'AeroForcesCalculator' ], 'write_screen': 'off', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } config['BeamLoader'] = { 'unsteady': 'off', 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) } if horseshoe is True: config['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['1', '0', '0'] } config['StaticUvlm'] = { 'print_info': 'off', 'horseshoe': 'on', 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': 1.225, 'alpha': alpha_rad, 'beta': beta } else: config['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': 90, 'freestream_dir': ['1', '0', '0'] } config['StaticUvlm'] = { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 100, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': 1.225, 'alpha': alpha_rad, 'beta': beta } minus_m_star = 0 if config['StaticUvlm']['horseshoe'] is 'on': minus_m_star = max(m_main - 1, 1) config['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0 } config['AeroForcesCalculator'] = { 'folder': route + '/output/', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } config.write()
def generate_solver_file(): file_name = cases_folder + case_name + '.sharpy' settings = dict() settings['SHARPy'] = {'case': case_name, 'route': cases_folder, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/' + case_name, 'log_file': case_name + '.log'} settings['BeamLoader'] = {'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([roll, alpha, beta]))} settings['AerogridLoader'] = {'unsteady': 'on', 'aligned_grid': 'on', 'mstar': m_star_factor * m, 'freestream_dir': ['1', '0', '0'], 'wake_shape_generator': 'StraightWake', 'wake_shape_generator_input': {'dt': dt, 'u_inf': u_inf, 'u_inf_direction': [1, 0, 0.]}} settings['NonLinearStatic'] = {'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 9.81} settings['StaticUvlm'] = {'print_info': 'on', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'vortex_radius': 1e-8, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': {'u_inf': u_inf, 'u_inf_direction': [1., 0, 0]}, 'rho': rho} settings['StaticCoupled'] = {'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': n_step, 'tolerance': fsi_tolerance, 'relaxation_factor': structural_relaxation_factor} settings['StaticTrim'] = {'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust} settings['NonLinearDynamicCoupledStep'] = {'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf} settings['NonLinearDynamicPrescribedStep'] = {'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf*int(free_flight)} relative_motion = 'off' if not free_flight: relative_motion = 'on' settings['StepUvlm'] = {'print_info': 'off', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'vortex_radius': 1e-8, 'gamma_dot_filtering': 6, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': {'u_inf': int(not free_flight)*u_inf, 'u_inf_direction': [1., 0, 0]}, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt} if free_flight: solver = 'NonLinearDynamicCoupledStep' else: solver = 'NonLinearDynamicPrescribedStep' settings['DynamicCoupled'] = {'structural_solver': solver, 'structural_solver_settings': settings[solver], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'runtime_generators': {'ModifyStructure': structural_generator_settings}, 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.5, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'on', 'postprocessors': ['BeamLoads', 'BeamPlot', 'StallCheck', 'AerogridPlot', 'WriteVariablesTime'], 'postprocessors_settings': {'BeamLoads': {'folder': route + '/output/', 'csv_output': 'off'}, 'BeamPlot': {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on'}, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0}, 'StallCheck': { 'print_info': 'on', 'airfoil_stall_angles': { '0': (-10 * np.pi / 180, 10 * np.pi / 180), '1': (-10 * np.pi / 180, 10 * np.pi / 180), '2': (-10 * np.pi / 180, 10 * np.pi / 180), }, 'output_degrees': 'on', }, 'WriteVariablesTime': { 'folder': route + '/output/', 'FoR_variables': ['for_pos', 'for_vel', 'for_acc', 'quat'], 'FoR_number': [0], 'cleanup_old_solution': 'on', } } } settings['BeamLoads'] = {'folder': route + '/output/', 'csv_output': 'off'} settings['BeamPlot'] = {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on'} settings['AerogridPlot'] = {'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf, 'dt': dt} settings['Modal'] = {'print_info': True, 'use_undamped_modes': True, 'NumLambda': 30, 'rigid_body_modes': True, 'write_modes_vtk': 'on', 'print_matrices': 'on', 'write_data': 'on', 'continuous_eigenvalues': 'off', 'dt': dt, 'plot_eigenvalues': False} settings['LinearAssembler'] = {'linear_system': 'LinearAeroelastic', 'linear_system_settings': { 'beam_settings': {'modal_projection': False, 'inout_coords': 'nodes', 'discrete_time': True, 'newmark_damp': 0.05, 'discr_method': 'newmark', 'dt': dt, 'proj_modes': 'undamped', 'use_euler': 'off', 'num_modes': 40, 'print_info': 'on', 'gravity': 'on', 'remove_dofs': []}, 'aero_settings': {'dt': dt, 'integr_order': 2, 'density': rho, 'remove_predictor': False, 'use_sparse': True, 'rigid_body_motion': free_flight, 'use_euler': False, 'remove_inputs': ['u_gust']}, 'rigid_body_motion': free_flight}} settings['AsymptoticStability'] = {'sys_id': 'LinearAeroelastic', 'print_info': 'on', 'modes_to_plot': [], 'display_root_locus': 'off', 'frequency_cutoff': 0, 'export_eigenvalues': 'off', 'num_evals': 40, 'folder': route + '/output/'} import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def generate_solver_file(): file_name = route + '/' + case_name + '.solver.txt' settings = dict() settings['SHARPy'] = {'case': case_name, 'route': route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log'} settings['BeamLoader'] = {'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0.0, alpha, beta]))} settings['NonLinearStatic'] = {'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-15, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 9.81*0} settings['StaticUvlm'] = {'print_info': 'on', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 1, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': {'u_inf': u_inf, 'u_inf_direction': [1., 0, 0]}, 'rho': rho*0} settings['StaticCoupled'] = {'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'structural_substeps': 1, 'n_load_steps': n_step, 'tolerance': tolerance, 'relaxation_factor': relaxation_factor} settings['StaticTrim'] = {'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust} settings['NonLinearDynamicCoupledStep'] = {'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-9, 'min_delta': 1e-5, 'newmark_damp': 1e-2, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt} # print('Convection scheme is 2') settings['StepUvlm'] = {'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 100, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': {'u_inf': u_inf, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': 60, 'gust_intensity': gust_intensity*u_inf, 'offset': 10.0, 'span': span_main}, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt} settings['DynamicCoupled'] = {'print_info': 'off', 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': settings['NonLinearDynamicCoupledStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': 1e-7, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'off', 'postprocessors': ['BeamLoads', 'BeamPlot', 'AerogridPlot'], 'postprocessors_settings': {'BeamLoads': {}, 'BeamPlot': {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on'}, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0}}} settings['DynamicPrescribedCoupled'] = {'structural_solver': 'NonLinearDynamicPrescribedStep', 'structural_solver_settings': settings['NonLinearDynamicCoupledStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': 1e-9, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, # 'postprocessors': ['BeamPlot', 'AerogridPlot'], 'postprocessors_settings': {'BeamPlot': {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on'}, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0}}} settings['PIDTrajectoryControl'] = {'print_info': 'on', 'trajectory_solver': 'DynamicCoupled', 'trajectory_solver_settings': settings['DynamicCoupled'], 'trajectory_generator': 'TrajectoryGenerator', 'trajectory_generator_input': {'angle_end': alpha, 'veloc_end': trajectory_end_velocity, 'shape': 'linear', 'acceleration': 'linear', 'dt': dt, 'coords_end': trajectory_coords_end, 'time_offset': 280*dt, 'plot': 'on', 'print_info': 'on'}, 'n_time_steps': n_tstep, 'dt': dt, # 'PID_P_gain': 25*100, # 'PID_I_gain': 50.*100, # 'PID_D_gain': 20*10, # 'PID_P_gain': 25*100, 'PID_P_gain': 30*100, 'PID_I_gain': 25.*100, 'PID_D_gain': 25*10, 'nodes_trajectory': [0, end_of_fuselage_node], 'transient_nsteps': 250} # 'transient_nsteps': 200} # print('Small mstar') settings['AerogridLoader'] = {'unsteady': 'on', 'aligned_grid': 'on', 'mstar': 40, # 'mstar': 20, 'freestream_dir': ['1', '0', '0']} settings['AerogridPlot'] = {'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf, 'dt': dt} settings['AeroForcesCalculator'] = {'folder': route + '/output/forces', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off'} settings['BeamPlot'] = {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on'} settings['BeamCsvOutput'] = {'folder': route + '/output/', 'output_pos': 'on', 'output_psi': 'on', 'screen_output': 'off'} settings['BeamLoads'] = {} import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def unpack_ss_vector(self, x_n, u_n, struct_tstep): """ Warnings: Under development. Missing: * Accelerations * Double check the cartesian rotation vector * Tangential operator for the moments Takes the state :math:`x = [\eta, \dot{\eta}]` and input vectors :math:`u = N` of a linearised beam and returns a SHARPy timestep instance, including the reference values. Args: x_n (np.ndarray): Structural beam state vector in nodal space y_n (np.ndarray): Beam input vector (nodal forces) struct_tstep (utils.datastructures.StructTimeStepInfo): Reference timestep used for linearisation Returns: utils.datastructures.StructTimeStepInfo: new timestep with linearised values added to the reference value """ # check if clamped vdof = self.sys.structure.vdof num_node = struct_tstep.num_node num_dof = 6 * sum(vdof >= 0) if self.sys.clamped: clamped = True rig_dof = 0 else: clamped = False if self.settings['use_euler']: rig_dof = 9 else: rig_dof = 10 q = np.zeros_like(struct_tstep.q) q = np.zeros((num_dof + rig_dof)) dqdt = np.zeros_like(q) dqddt = np.zeros_like(q) pos = np.zeros_like(struct_tstep.pos) pos_dot = np.zeros_like(struct_tstep.pos_dot) psi = np.zeros_like(struct_tstep.psi) psi_dot = np.zeros_like(struct_tstep.psi_dot) for_pos = np.zeros_like(struct_tstep.for_pos) for_vel = np.zeros_like(struct_tstep.for_vel) for_acc = np.zeros_like(struct_tstep.for_acc) quat = np.zeros_like(struct_tstep.quat) gravity_forces = np.zeros_like(struct_tstep.gravity_forces) total_gravity_forces = np.zeros_like(struct_tstep.total_gravity_forces) steady_applied_forces = np.zeros_like( struct_tstep.steady_applied_forces) unsteady_applied_forces = np.zeros_like( struct_tstep.unsteady_applied_forces) q[:num_dof + rig_dof] = x_n[:num_dof + rig_dof] dqdt[:num_dof + rig_dof] = x_n[num_dof + rig_dof:] # Missing the forces # dqddt = self.sys.Minv.dot(-self.sys.Cstr.dot(dqdt) - self.sys.Kstr.dot(q)) for i_node in vdof[vdof >= 0]: pos[i_node + 1, :] = q[6 * i_node:6 * i_node + 3] pos_dot[i_node + 1, :] = dqdt[6 * i_node + 0:6 * i_node + 3] # TODO: CRV of clamped node and double check that the CRV takes this form for i_elem in range(struct_tstep.num_elem): for i_node in range(struct_tstep.num_node_elem): psi[i_elem, i_node, :] = np.linalg.inv( algebra.crv2tan(struct_tstep.psi[i_elem, i_node]).T).dot( q[i_node + 3:i_node + 6]) psi_dot[i_elem, i_node, :] = dqdt[i_node + 3:i_node + 6] if not clamped: for_vel = dqdt[-rig_dof:-rig_dof + 6] if self.settings['use_euler']: euler = dqdt[-4:-1] quat = algebra.euler2quat(euler) else: quat = dqdt[-4:] for_pos = q[-rig_dof:-rig_dof + 6] for_acc = dqddt[-rig_dof:-rig_dof + 6] if u_n is not None: for i_node in vdof[vdof >= 0]: steady_applied_forces[i_node + 1] = u_n[6 * i_node:6 * i_node + 6] steady_applied_forces[0] = u_n[-10:-4] - np.sum( steady_applied_forces[1:, :], 0) # gravity forces - careful - debug C_grav = np.zeros((q.shape[0], q.shape[0])) K_grav = np.zeros_like(C_grav) try: Crr = self.sys.Crr_grav Csr = self.sys.Csr_grav C_grav[:-rig_dof, -rig_dof:] = Csr # TODO: sort out changing q vector with euler C_grav[-rig_dof:, -rig_dof:] = Crr K_grav[-rig_dof:, :-rig_dof] = self.sys.Krs_grav K_grav[:-rig_dof, :-rig_dof] = self.sys.Kss_grav fgrav = -C_grav.dot(dqdt) - K_grav.dot(q) for i in range(gravity_forces.shape[0] - 1): #add bc at node - doing it manually here gravity_forces[i + 1, :] = fgrav[6 * i:6 * (i + 1)] gravity_forces[0, :] = fgrav[-rig_dof:-rig_dof + 6] - np.sum( gravity_forces[1:], 0) except AttributeError: pass current_time_step = struct_tstep.copy() current_time_step.q[:len(q)] = q + struct_tstep.q[:len(q)] current_time_step.dqdt[:len(q)] = dqdt + struct_tstep.dqdt[:len(q)] current_time_step.dqddt[:len(q)] = dqddt + struct_tstep.dqddt[:len(q)] current_time_step.pos = pos + struct_tstep.pos current_time_step.pos_dot = pos + struct_tstep.pos_dot current_time_step.psi = psi + struct_tstep.psi current_time_step.psi_dot = psi_dot + struct_tstep.psi_dot current_time_step.for_vel = for_vel + struct_tstep.for_vel current_time_step.for_acc = for_acc + struct_tstep.for_acc current_time_step.for_pos = for_pos + struct_tstep.for_pos current_time_step.gravity_forces = gravity_forces + struct_tstep.gravity_forces current_time_step.total_gravity_forces = total_gravity_forces + struct_tstep.total_gravity_forces current_time_step.unsteady_applied_forces = unsteady_applied_forces + struct_tstep.unsteady_applied_forces new_quat = quat + struct_tstep.quat current_time_step.quat = new_quat / np.linalg.norm(new_quat) current_time_step.steady_applied_forces = steady_applied_forces + struct_tstep.steady_applied_forces return current_time_step
def generate_solver_file(): file_name = cases_folder + case_name + '.sharpy' settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': cases_folder, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/' + case_name, 'log_file': case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([roll, alpha, beta])) } settings['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', 'mstar': m_star_factor * m, 'freestream_dir': ['1', '0', '0'] } settings['NonLinearStatic'] = { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 9.81 } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'vortex_radius': 1e-8, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho } settings['StaticCoupled'] = { 'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': n_step, 'tolerance': fsi_tolerance, 'relaxation_factor': structural_relaxation_factor } settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust } settings['NonLinearDynamicCoupledStep'] = { 'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf } settings['NonLinearDynamicPrescribedStep'] = { 'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf * int(free_flight) } relative_motion = 'off' if not free_flight: relative_motion = 'on' settings['StepUvlm'] = { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'gamma_dot_filtering': 6, 'vortex_radius': 1e-8, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': { 'u_inf': int(not free_flight) * u_inf, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': gust_length, 'gust_intensity': gust_intensity * u_inf, 'offset': gust_offset, 'span': span_main, 'relative_motion': relative_motion }, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt } if free_flight: solver = 'NonLinearDynamicCoupledStep' else: solver = 'NonLinearDynamicPrescribedStep' settings['DynamicCoupled'] = { 'structural_solver': solver, 'structural_solver_settings': settings[solver], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.5, 'n_time_steps': 1, 'dt': dt, 'include_unsteady_force_contribution': 'off', 'postprocessors': ['BeamLoads', 'BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'BeamLoads': { 'folder': route + '/output/', 'csv_output': 'off' }, 'BeamPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 }, } } settings['BeamLoads'] = {'folder': route + '/output/', 'csv_output': 'off'} settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on' } settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf, 'dt': dt } settings['Modal'] = { 'print_info': 'on', 'use_undamped_modes': 'on', 'NumLambda': num_modes, 'rigid_body_modes': free_flight, 'write_modes_vtk': 'on', 'print_matrices': 'off', 'write_data': 'on', 'rigid_modes_cg': 'on' } settings['LinearAssembler'] = { 'linear_system': 'LinearAeroelastic', 'linear_system_settings': { 'beam_settings': { 'modal_projection': 'on', 'inout_coords': 'modes', 'discrete_time': 'on', 'newmark_damp': 5e-4, 'discr_method': 'newmark', 'dt': dt, 'proj_modes': 'undamped', 'use_euler': 'on', 'num_modes': num_modes, 'print_info': 'on', 'gravity': 'on', 'remove_dofs': [] }, 'aero_settings': { 'dt': dt, 'ScalingDict': { 'density': rho, 'length': chord_main / 0.5, 'speed': u_inf }, 'integr_order': 2, 'density': rho, 'remove_predictor': 'off', 'use_sparse': 'on', 'vortex_radius': 1e-8, 'remove_inputs': ['u_gust'] }, 'rigid_body_motion': free_flight, 'use_euler': 'on', } } if rom: settings['LinearAssembler']['linear_system_settings']['aero_settings'][ 'rom_method'] = ['Krylov'] settings['LinearAssembler']['linear_system_settings']['aero_settings'][ 'rom_method_settings'] = { 'Krylov': { 'algorithm': 'mimo_rational_arnoldi', 'frequency': [0.], 'r': 4, 'single_side': 'observability' } } settings['AsymptoticStability'] = { 'sys_id': 'LinearAeroelastic', 'print_info': 'on', 'modes_to_plot': [], 'display_root_locus': 'off', 'frequency_cutoff': 0, 'export_eigenvalues': 'off', 'num_evals': 40, 'folder': route + '/output/' } settings['FrequencyResponse'] = { 'folder': route + '/output/', 'target_system': ['aerodynamic'], 'num_freqs': 100 } settings['SaveData'] = { 'folder': route + '/output/' + case_name + '/', 'save_aero': 'off', 'save_struct': 'off', 'save_linear': 'on', 'save_linear_uvlm': 'on', 'format': 'h5' } settings['LinDynamicSim'] = { 'folder': route + '/output/', 'n_tsteps': n_tstep, 'dt': dt, 'postprocessors': ['AerogridPlot'], 'postprocessors_settings': { 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 }, } } settings['PickleData'] = {'folder': route + '/output/'} import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def generate_solver_file(): file_name = route + '/' + case_name + '.solver.txt' settings = dict() aux_settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } # AUX DICTIONARIES aux_settings['velocity_field_input'] = { 'u_inf': WSP, 'u_inf_direction': [1., 0, 0] } # LOADERS settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0.0, alpha, beta])) } settings['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', 'mstar': mstar, 'freestream_dir': ['1', '0', '0'] } # POSTPROCESS settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': WSP, 'dt': dt } #settings['AeroForcesCalculator'] = {'folder': route + '/output/forces', #'write_text_file': 'on', #'text_file_name': case_name + '_aeroforces.csv', #'screen_output': 'on', #'unsteady': 'off'} settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on' } #settings['BeamCsvOutput'] = {'folder': route + '/output/', #'output_pos': 'on', #'output_psi': 'on', #'screen_output': 'off'} settings['BeamLoads'] = {} settings['WriteVariablesTime'] = { 'delimiter': ' ', 'structure_variables': [ 'AFoR_steady_forces', 'AFoR_unsteady_forces', 'AFoR_position', 'AFoR_velocity' ], 'structure_nodes': [4], 'aero_panels_variables': ['gamma', 'norm_gamma', 'norm_gamma_star'], 'aero_panels_isurf': [0], 'aero_panels_im': [0], 'aero_panels_in': [4], 'aero_nodes_variables': ['GFoR_steady_force', 'GFoR_unsteady_force'], 'aero_nodes_isurf': [0], 'aero_nodes_im': [0], 'aero_nodes_in': [4] } settings['SaveData'] = {} # STATIC COUPLED settings['NonLinearStatic'] = { 'print_info': 'on', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-15, 'min_delta': 1e-8, 'gravity_on': gravity, 'gravity': 9.81 } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': aux_settings['velocity_field_input'], 'rho': 0.0 } settings['StaticCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': 4, 'tolerance': 1e-8, 'relaxation_factor': 0 } # DYNAMIC PRESCRIBED COUPLED settings['NonLinearDynamicPrescribedStep'] = { 'print_info': 'on', 'max_iterations': 95000, 'delta_curved': 1e-9, 'min_delta': 1e-6, 'newmark_damp': 1e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt } settings['StepUvlm'] = { 'print_info': 'on', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 0, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': aux_settings['velocity_field_input'], 'rho': airDensity, 'n_time_steps': n_tstep, 'dt': dt } settings['DynamicPrescribedCoupled'] = { 'structural_solver': 'NonLinearDynamicPrescribedStep', 'structural_solver_settings': settings['NonLinearDynamicPrescribedStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 20000, 'fsi_tolerance': 1e-9, 'fsi_vel_tolerance': 1e-5, 'relaxation_factor': 0, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'off', 'print_info': 'on', 'rigid_structure': 'on', 'postprocessors': ['WriteVariablesTime'], 'postprocessors_settings': { 'WriteVariablesTime': settings['WriteVariablesTime'] } } # STEADY HELICOIDAL WAKE settings['SteadyHelicoidalWake'] = settings['DynamicPrescribedCoupled'] import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def generate_solver_file(): file_name = route + '/' + case_name + '.solver.txt' settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0.0, alpha, beta])) } settings['NonLinearStatic'] = { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-3, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 9.81 * 0 } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 1, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho * 0 } settings['StaticCoupled'] = { 'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'structural_substeps': 1, 'n_load_steps': n_step, 'tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor } settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust } settings['NonLinearDynamicCoupledStep'] = { 'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-3, 'min_delta': tolerance, 'newmark_damp': 1e-2, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt } # print('Convection scheme is 2') settings['StepUvlm'] = { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 100, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, # 'velocity_field_generator': 'GustVelocityField', # 'velocity_field_input': {'u_inf': u_inf, # 'u_inf_direction': [1., 0, 0], # 'gust_shape': '1-cos', # 'gust_length': 60, # 'gust_intensity': gust_intensity*u_inf, # 'offset': 10.0, # 'span': span_main}, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt } settings['DynamicCoupled'] = { 'print_info': 'off', 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': settings['NonLinearDynamicCoupledStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'off', 'postprocessors': ['StallCheck', 'BeamLoads', 'BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'StallCheck': { 'output_degrees': True, 'stall_angles': { '0': [-12 * np.pi / 180, 12 * np.pi / 180], '1': [-12 * np.pi / 180, 12 * np.pi / 180], '2': [-12 * np.pi / 180, 12 * np.pi / 180] } }, 'BeamLoads': {}, 'BeamPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 } } } settings['DynamicPrescribedCoupled'] = { 'structural_solver': 'NonLinearDynamicPrescribedStep', 'structural_solver_settings': settings['NonLinearDynamicCoupledStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': 1e-9, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, # 'postprocessors': ['BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'BeamPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 } } } settings['PIDTrajectoryControl'] = { 'print_info': 'on', 'write_trajectory_data': 'on', 'trajectory_solver': 'DynamicCoupled', 'trajectory_solver_settings': settings['DynamicCoupled'], 'trajectory_generator': 'TrajectoryGenerator', 'trajectory_generator_input': { 'angle_end': alpha, 'veloc_end': trajectory_end_velocity, 'shape': 'linear', 'acceleration': 'linear', 'dt': dt, 'coords_end': trajectory_coords_end, 'time_offset': 300 * dt, 'plot': 'off', 'print_info': 'on' }, 'n_time_steps': n_tstep, 'dt': dt, 'PID_P_gain': 22500, 'PID_I_gain': 1000, 'PID_D_gain': 1000, # 'PID_P_gain': 25*100, 'controller_scaling': [1.0, 0.05], 'controller_axis_scaling': [0.50, 0.50, 1.0], 'nodes_trajectory': [0, end_of_fuselage_node], 'transient_nsteps': 200 } # 'transient_nsteps': 200} # print('Small mstar') settings['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', # 'mstar': 40, # 'mstar': 4*m, 'mstar': 15 * m, 'freestream_dir': ['1', '0', '0'] } settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf, 'dt': dt } settings['AeroForcesCalculator'] = { 'folder': route + '/output/forces', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on' } settings['BeamCsvOutput'] = { 'folder': route + '/output/', 'output_pos': 'on', 'output_psi': 'on', 'screen_output': 'off' } settings['BeamLoads'] = {} settings['Modal'] = { 'print_info': 'on', 'use_undamped_modes': 'on', 'NumLambda': 40, 'rigid_body_modes': 'on', 'write_modes_vtk': 'on', 'print_matrices': 'on', 'write_data': 'on', 'continuous_eigenvalues': 'off', 'dt': dt, 'plot_eigenvalues': 'off' } # Linear Model aero_settings = dict() aero_settings['remove_inputs'] = ['u_gust'] aero_settings['dt'] = dt aero_settings['density'] = rho beam_settings = dict() beam_settings['modal_projection'] = False beam_settings['discrete_time'] = True beam_settings['dt'] = dt beam_settings['use_euler'] = False beam_settings['gravity'] = True beam_settings['remove_dofs'] = [] beam_settings['print_info'] = True settings['LinearAssembler'] = { 'flow': ['LinearAeroelastic'], 'join_series': False, # 'LinearCustom':{'solver_name': 'plunge_solver', # 'solver_path': '../CC_DevTests/01_LinearAssembly/FlatPlate/cases'}, # 'LinearBeam': beam_settings, # 'LinearUVLM': aero_settings, 'LinearAeroelastic': { 'aero_settings': aero_settings, 'beam_settings': beam_settings, 'rigid_body_motion': True } } settings['AsymptoticStability'] = { 'sys_id': 'LinearAeroelastic', 'print_info': 'on', 'postprocessors': ['AerogridPlot'], 'postprocessors_settings': { 'AerogridPlot': settings['AerogridPlot'] } } import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
int(np.round(100*SideVecDeg[ii])) , int(np.round(100*RollVecDeg[ii])) ) case_here=case_main+'_ainf%.4da%.4ds%.4dr%.4d'%tplparams route_here=route_main os.system('mkdir -p %s'%(route_here,)) ### ------------------------------------------------------ Build wing model ws=flying_wings.Goland( M=M,N=N,Mstar_fact=Mstar_fact,n_surfaces=Nsurf, u_inf=u_inf, alpha=AlphaVecDeg[ii], beta=-SideVecDeg[ii], route=route_here, case_name=case_here) # updte wind direction quat_wind=algebra.euler2quat(-np.pi/180.*np.array([0.,AlphaInfVecDeg[ii],0.])) u_inf_dir=np.dot( algebra.quat2rotation(quat_wind),np.array([1.,0.,0.])) ws.main_ea-=.25/M ws.main_cg-=.25/M ws.root_airfoil_P = 4 ws.root_airfoil_M = 2 ws.tip_airfoil_P = 4 ws.tip_airfoil_M = 2 ws.clean_test_files() ws.update_derived_params() ws.generate_fem_file() ws.generate_aero_file()
def generate_horten(u_inf, output_folder): M = 6 N = 11 Msf = 5 rho_fact = 1. track_body = True payload = 0 u_inf = u_inf output_folder = output_folder use_euler = True if use_euler: orient = 'euler' else: orient = 'quat' case_rmks = 'M%gN%gMsf%g_u%g' % (M, N, Msf, u_inf) # M4N11Msf5 alpha_deg = 3.135 cs_deflection = 0.2514 thrust = 5.118 # M8N11Msf5 # alpha_deg = 4.5162 # cs_deflection = 0.2373 # thrust = 5.5129 # ROM settings rom_settings = dict() rom_settings['algorithm'] = 'mimo_rational_arnoldi' rom_settings['r'] = 5 rom_settings['frequency'] = np.array([0], dtype=float) rom_settings['single_side'] = 'observability' case_rmks += 'rom_%g_%s' % (rom_settings['r'], rom_settings['single_side'][:3]) ws = Baseline( M=M, N=N, Mstarfactor=Msf, u_inf=u_inf, rho=1.02, alpha_deg=alpha_deg, # 7.7563783342984385, roll_deg=0, cs_deflection_deg=cs_deflection, # -6.733360628875144, thrust=thrust, # 10.140622253017584, physical_time=20, case_name='horten_s05', case_name_format=4, case_remarks=case_rmks) ws.set_properties() ws.initialise() # ws.sweep_LE = 0*np.pi/180 # ws.n_tstep = 2 ws.clean_test_files() ws.tolerance = 1e-6 ws.fsi_tolerance = 1e-6 # ws.update_mass_stiffness(sigma=1., sigma_mass=1.5) ws.update_mass_stiffness(sigma=.5, sigma_mass=1.0, payload=payload) ws.update_fem_prop() ws.generate_fem_file() ws.update_aero_properties() ws.generate_aero_file() flow = [ 'BeamLoader', 'AerogridLoader', # 'StaticUvlm', # 'StaticCoupled', 'StaticTrim', 'BeamPlot', 'AerogridPlot', 'AeroForcesCalculator', 'DynamicCoupled', 'Modal', 'LinearAssembler', # 'LinDynamicSim', # 'SaveData', 'AsymptoticStability', 'FrequencyResponse', # 'StabilityDerivatives', # 'LinDynamicSim', 'PickleData', 'SaveParametricCase', 'SaveStateSpace' ] settings = dict() settings['SHARPy'] = { 'case': ws.case_name, 'route': ws.case_route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': output_folder + ws.case_name + '/', 'log_file': ws.case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'off', 'orientation': algebra.euler2quat(np.array([ws.roll, ws.alpha, ws.beta])) } settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': int(ws.M * ws.Mstarfactor), 'freestream_dir': ['1', '0', '0'], 'control_surface_deflection': [''], 'wake_shape_generator': 'StraightWake', 'wake_shape_generator_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0., 0.], 'dt': ws.dt }, } if ws.horseshoe is True: settings['AerogridLoader']['mstar'] = 1 settings['StaticCoupled'] = { 'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 200, 'num_load_steps': 1, 'delta_curved': 1e-5, 'min_delta': ws.tolerance, 'gravity_on': 'on', 'gravity': 9.81 }, 'aero_solver': 'StaticUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': ws.horseshoe, 'num_cores': 4, 'n_rollup': int(0), 'vortex_radius': 1e-6, 'rollup_dt': ws.dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': ws.u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': ws.rho }, 'max_iter': 200, 'n_load_steps': 2, 'tolerance': ws.tolerance, 'relaxation_factor': 0.1 } settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'thrust_nodes': ws.thrust_nodes, 'initial_alpha': ws.alpha, 'initial_deflection': ws.cs_deflection, 'initial_thrust': ws.thrust, 'max_iter': 50, 'fz_tolerance': 1e-2, 'fx_tolerance': 1e-2, 'm_tolerance': 1e-2, 'save_info': 'off', 'folder': output_folder } settings['AerogridPlot'] = { 'folder': output_folder, 'include_rbm': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': ws.u_inf } settings['AeroForcesCalculator'] = { 'folder': output_folder, 'write_text_file': 'on', 'text_file_name': 'aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off', 'coefficients': True, 'q_ref': 0.5 * ws.rho * ws.u_inf**2, 'S_ref': 12.809, } settings['BeamPlot'] = { 'folder': output_folder, 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_FoR': 'on' } struct_solver_settings = { 'print_info': 'off', 'initial_velocity_direction': [-1., 0., 0.], 'max_iterations': 950, 'delta_curved': 1e-6, 'min_delta': ws.tolerance, 'newmark_damp': 5e-3, 'gravity_on': True, 'gravity': 9.81, 'num_steps': ws.n_tstep, 'dt': ws.dt, 'initial_velocity': ws.u_inf * 1 } step_uvlm_settings = { 'print_info': 'on', 'horseshoe': ws.horseshoe, 'num_cores': 4, 'n_rollup': 1, 'convection_scheme': ws.wake_type, 'rollup_dt': ws.dt, 'vortex_radius': 1e-6, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': ws.u_inf * 0, 'u_inf_direction': [1., 0., 0.] }, 'rho': ws.rho, 'n_time_steps': ws.n_tstep, 'dt': ws.dt, 'gamma_dot_filtering': 3 } settings['DynamicCoupled'] = { 'print_info': 'on', # 'structural_substeps': 1, # 'dynamic_relaxation': 'on', # 'clean_up_previous_solution': 'on', 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': struct_solver_settings, 'aero_solver': 'StepUvlm', 'aero_solver_settings': step_uvlm_settings, 'fsi_substeps': 200, 'fsi_tolerance': ws.fsi_tolerance, 'relaxation_factor': ws.relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.5, 'n_time_steps': 1, # ws.n_tstep, 'dt': ws.dt, 'include_unsteady_force_contribution': 'off', 'postprocessors': ['BeamPlot', 'AerogridPlot', 'WriteVariablesTime'], 'postprocessors_settings': { 'BeamLoads': { 'folder': output_folder, 'csv_output': 'off' }, 'BeamPlot': { 'folder': output_folder, 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'u_inf': ws.u_inf, 'folder': output_folder, 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 }, 'WriteVariablesTime': { 'folder': output_folder, 'cleanup_old_solution': 'on', 'delimiter': ',', 'FoR_variables': ['total_forces', 'total_gravity_forces', 'for_pos', 'quat'], } } } settings['Modal'] = { 'print_info': True, 'use_undamped_modes': True, 'NumLambda': 30, 'rigid_body_modes': True, 'write_modes_vtk': 'on', 'print_matrices': 'on', 'write_data': 'on', 'continuous_eigenvalues': 'off', 'dt': ws.dt, 'plot_eigenvalues': False, 'rigid_modes_cg': 'off', 'folder': output_folder } settings['LinearAssembler'] = { 'linear_system': 'LinearAeroelastic', 'linear_system_settings': { 'beam_settings': { 'modal_projection': 'on', 'inout_coords': 'modes', 'discrete_time': True, 'newmark_damp': 0.5e-3, 'discr_method': 'newmark', 'dt': ws.dt, 'proj_modes': 'undamped', 'use_euler': use_euler, 'num_modes': 20, 'print_info': 'on', 'gravity': 'on', 'remove_dofs': [] }, 'aero_settings': { 'dt': ws.dt, # 'ScalingDict': {'length': ws.c_root, # 'speed': ws.u_inf, # 'density': ws.rho}, 'integr_order': 2, 'density': ws.rho * rho_fact, 'remove_predictor': False, 'use_sparse': False, 'rigid_body_motion': True, 'use_euler': use_euler, 'vortex_radius': 1e-6, 'remove_inputs': ['u_gust'], 'rom_method': ['Krylov'], 'rom_method_settings': { 'Krylov': rom_settings } }, 'rigid_body_motion': True, 'track_body': track_body, 'use_euler': use_euler, 'linearisation_tstep': -1 } } settings['AsymptoticStability'] = { 'print_info': 'on', 'modes_to_plot': [], # 'velocity_analysis': [27, 29, 3], 'display_root_locus': 'off', 'frequency_cutoff': 0, 'export_eigenvalues': 'on', 'num_evals': 1000, 'target_system': ['aeroelastic', 'aerodynamic', 'structural'], 'folder': output_folder } settings['FrequencyResponse'] = { 'print_info': 'on', 'folder': output_folder, 'compute_fom': 'on', 'frequency_bounds': [0.1, 100], 'frequency_spacing': 'log', 'target_system': ['aeroelastic', 'aerodynamic', 'structural'], 'num_freqs': 200, 'compute_hinf': 'on' } settings['LinDynamicSim'] = { 'dt': ws.dt, 'n_tsteps': ws.n_tstep, 'sys_id': 'LinearAeroelastic', # 'reference_velocity': ws.u_inf, 'write_dat': ['x', 'y', 't', 'u'], # 'write_dat': 'on', 'postprocessors': ['BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'AerogridPlot': { 'u_inf': ws.u_inf, 'folder': './output', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 }, 'BeamPlot': { 'folder': output_folder, 'include_rbm': 'on', 'include_applied_forces': 'on' } } } settings['StabilityDerivatives'] = { 'u_inf': ws.u_inf, 'S_ref': 12.809, 'b_ref': ws.span, 'c_ref': 0.719 } settings['SaveData'] = { 'folder': output_folder, 'save_aero': 'off', 'save_struct': 'off', 'save_linear': 'on', 'save_linear_uvlm': 'on' } settings['PickleData'] = {'folder': output_folder + ws.case_name + '/'} settings['SaveParametricCase'] = { 'folder': output_folder + ws.case_name + '/', 'parameters': { 'u_inf': u_inf } } settings['SaveStateSpace'] = { 'folder': output_folder, 'target_system': ['aeroelastic', 'aerodynamic', 'structural'] } config = configobj.ConfigObj() file_name = ws.case_route + '/' + ws.case_name + '.solver.txt' config.filename = file_name for k, v in settings.items(): config[k] = v config.write() delta = np.zeros((ws.n_tstep, 1)) delta_dot = np.zeros_like(delta) d_elev = 1 * np.pi / 180 * 0.01 t_init = 1.0 t_ramp = 2.0 t_final = 5.0 delta[int(t_init // ws.dt):(int(t_ramp // ws.dt)), 0] = np.linspace(0, d_elev, (int(t_ramp // ws.dt)) - int(t_init // ws.dt)) delta[int(t_ramp // ws.dt):(int(t_final // ws.dt)), 0] = d_elev delta[int(t_final // ws.dt):(int((t_final + 1.0) // ws.dt)), 0] = np.linspace(d_elev, 0, (int( (t_final + 1) // ws.dt)) - int(t_final // ws.dt)) delta_dot[int(t_init // ws.dt):int(t_ramp // ws.dt), 0] = d_elev / (t_ramp - t_init) * 1 delta_dot[int(t_final // ws.dt):(int((t_final + 1.0) // ws.dt)), 0] = -d_elev / 1. * 1 ws.create_linear_simulation(delta, delta_dot) data = sharpy.sharpy_main.main( ['', ws.case_route + '/' + ws.case_name + '.solver.txt'])
def generate_solver_file(horseshoe=False): file_name = route + '/' + case_name + '.solver.txt' # config = configparser.ConfigParser() import configobj config = configobj.ConfigObj() config.filename = file_name config['SHARPy'] = { 'case': case_name, 'route': route, 'flow': [ 'BeamLoader', 'AerogridLoader', 'StaticCoupled', 'DynamicCoupled', # 'DynamicPrescribedCoupled', 'AerogridPlot', 'BeamLoads', 'BeamPlot', # 'AeroForcesCalculator', 'BeamCsvOutput' ], 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } config['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) } config['BeamLoads'] = {} config['StaticCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 10, 'delta_curved': 1e-18, 'min_delta': 1e-5, 'gravity_on': gravity, 'gravity': 9.81, 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) }, 'aero_solver': 'StaticUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho, 'alpha': alpha_rad, 'beta': beta }, 'max_iter': 80, 'n_load_steps': 4, 'tolerance': 1e-5, 'relaxation_factor': 0.4 } config['DynamicCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-6, 'min_delta': 1e-7, 'newmark_damp': 0 * 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': num_steps, 'dt': dt }, 'aero_solver': 'StepUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 100, 'convection_scheme': 3, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': 5, 'gust_intensity': 0.2 * u_inf, 'offset': 1.0, 'span': main_span }, 'rho': rho, 'alpha': alpha_rad, 'beta': beta, 'n_time_steps': num_steps, 'dt': dt }, 'fsi_substeps': 100, 'fsi_tolerance': 1e-7, 'relaxation_factor': 0.2, 'minimum_steps': 2, 'relaxation_steps': 1000, 'n_time_steps': num_steps, 'dt': dt, 'structural_substeps': 0 } config['DynamicPrescribedCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearDynamicPrescribedStep', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 15, 'delta_curved': 1e-5, 'min_delta': 1e-5, 'newmark_damp': 0 * 5e-4, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': num_steps, 'dt': dt }, 'aero_solver': 'StepUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 50, 'convection_scheme': 2, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho, 'alpha': alpha_rad, 'beta': beta, 'n_time_steps': num_steps, 'dt': dt }, 'fsi_substeps': 100, 'fsi_tolerance': 1e-6, 'relaxation_factor': 0.2, 'minimum_steps': 1, 'relaxation_steps': 15, 'n_time_steps': num_steps, 'dt': dt, 'structural_substeps': 0 } if horseshoe is True: config['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['1', '0', '0'] } else: config['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', 'mstar': 30, 'freestream_dir': ['1', '0', '0'] } config['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf, 'dt': dt } config['AeroForcesCalculator'] = { 'folder': route + '/output/forces', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } config['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on' } config['BeamCsvOutput'] = { 'folder': route + '/output/', 'output_pos': 'on', 'output_psi': 'on', 'screen_output': 'off' } config.write()
def __init__( self, M, # chordwise panelling Nv, # panelling VTP Nh, # panelling HTP (total, not half) Mstar_fact, u_inf, # flight cond rho, # size chord_htp_root, chord_htp_tip, chord_vtp_root, span_htp, height_vtp, # elastic axis main_ea, # from LE. # angles alpha_htp_deg=0.0, # positive if upward sweep_htp_deg=0.0, # positive if backward sweep_vtp_deg=0.0, # positive if backward # others alpha_inf_deg=0.0, beta_inf_deg=0.0, rotate_frame_A=True, route='.', # saving case_name='Ttail'): ### parametrisation assert Nv%2 != 1,\ 'vertical panelling of VTP must be divisible by 2 (using 3-noded FEs!)' assert Nh%4 != 1,\ 'spanwise panelling of full HTP must be divisible by 4 (using 3-noded FEs!)' # chordwise self.M = M # vtp self.Nv = Nv # htp self.Nh = Nh self.Nh_semi = Nh // 2 # wake self.Mstar_fact = Mstar_fact # wake chord-wise panel factor # beam elements self.n_surfaces = 3 self.num_nodes_elem = 3 self.num_elem_vtp = self.Nv // 2 self.num_elem_htpL = self.Nh_semi // 2 # port self.num_elem_htpR = self.Nh_semi // 2 # starboard self.num_elem_tot = self.num_elem_vtp + self.num_elem_htpL + self.num_elem_htpR self.num_nodes_vtp = 2 * self.num_elem_vtp + 1 self.num_nodes_htpL = 2 * self.num_elem_htpL + 1 self.num_nodes_htpR = 2 * self.num_elem_htpR + 1 self.num_nodes_tot = 2 * self.num_elem_vtp + 2 * self.num_elem_htpL + 2 * self.num_elem_htpR + 1 ### store input self.u_inf = u_inf # flight cond self.rho = rho self.chord_htp_root = chord_htp_root self.chord_htp_tip = chord_htp_tip self.chord_vtp_root = chord_vtp_root self.span_htp = span_htp self.height_vtp = height_vtp self.main_ea = main_ea self.alpha_htp_deg = alpha_htp_deg self.sweep_htp_deg = sweep_htp_deg self.sweep_vtp_deg = sweep_vtp_deg # FoR A orientation self.alpha_inf_deg = alpha_inf_deg self.beta_inf_deg = beta_inf_deg self.rotate_frame_A = rotate_frame_A if self.rotate_frame_A: self.quat = algebra.euler2quat( np.pi / 180. * np.array([0.0, alpha_inf_deg, beta_inf_deg])) self.u_inf_direction = np.array([1., 0., 0.]) else: self.quat = algebra.euler2quat(np.array([0., 0., 0.])) self.u_inf_direction = np.dot( algebra.euler2rot( np.pi / 180. * np.array([0.0, alpha_inf_deg, beta_inf_deg])), np.array([1., 0., 0.])) # time-step self.dt = self.chord_htp_root / self.M / self.u_inf self.route = route + '/' self.case_name = case_name
def generate_solver_file(): file_name = route + '/' + case_name + '.solver.txt' settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([roll, alpha, beta])) } settings['NonLinearStatic'] = { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 9.81, 'initial_position': initial_position } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho } settings['StaticCoupled'] = { 'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': n_step, 'tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor } settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust } settings['Trim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_beta': beta, 'cs_indices': [0, 1], 'initial_cs_deflection': [cs_deflection, rudder_static_deflection], 'initial_thrust': [thrust] } settings['NonLinearDynamicCoupledStep'] = { 'print_info': 'off', 'max_iterations': 350, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 1e-2, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf - turb_avg_vel } settings['StepUvlm'] = { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': 2, 'n_rollup': 0, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'gamma_dot_filtering': 6, # 'velocity_field_generator': 'TurbVelocityField', # 'velocity_field_input': { # # 'turbulent_field': '/home/ad214/dev/dev_time-domain-turbfield/turbfield/visu.xdmf', # # 'turbulent_field': '/2TB/2019YA_1/turbulent_fields/C2/visu.xdmf', # 'turbulent_field': '/run/media/ad214/4TB/HALE/C1/visu.xdmf', # 'periodicity': 'xy', # 'print_info': 'on', # 'frozen': 'off', # 'centre_y': 'on', # 'store_field': 'on' # }, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': gust_length, 'gust_intensity': gust_intensity * u_inf, 'offset': gust_offset, 'span': span_main }, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt } settings['PlotFlowField'] = { 'postproc_grid_generator': 'MovingGridBox', 'postproc_grid_input': { 'x0': -20, 'y0': -10, 'z0': -10, 'x1': 15, 'y1': 10, 'z1': 20, 'dx': 2.0, 'dy': 10.0, 'dz': 2.0 }, 'velocity_field_generator': settings['StepUvlm']['velocity_field_generator'], 'velocity_field_input': settings['StepUvlm']['velocity_field_input'], 'dt': dt, 'include_external': 'on', 'include_induced': 'on' } settings['DynamicCoupled'] = { 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': settings['NonLinearDynamicCoupledStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 550, 'final_relaxation_factor': 0.5, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'on', 'postprocessors': [ # 'PlotFlowField', 'WriteVariablesTime', 'Cleanup', 'BeamLoads', 'StallCheck', 'BeamPlot', 'AerogridPlot', 'CreateSnapshot' ], 'postprocessors_settings': { 'PlotFlowField': settings['PlotFlowField'], 'BeamLoads': { 'folder': route + '/output/', 'csv_output': 'off' }, 'StallCheck': { 'output_degrees': True, 'stall_angles': { '0': [-12 * np.pi / 180, 12 * np.pi / 180], '1': [-12 * np.pi / 180, 12 * np.pi / 180], '2': [-12 * np.pi / 180, 12 * np.pi / 180] } }, 'BeamPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 }, 'CreateSnapshot': { 'frequency': 100, 'keep': 5 }, 'Cleanup': { 'remaining_steps': 2000 }, 'WriteVariablesTime': { 'FoR_variables': ['quat', 'for_pos', 'for_vel', 'for_acc'], 'cleanup_old_solution': 'on', 'delimiter': ', ', # 'structure_variables': [''], # 'aero_panels_variables': [''], # 'aero_nodes_variables': [''], } } } settings['Modal'] = { 'print_info': 'on', 'use_undamped_modes': 'on', 'NumLambda': 40, 'rigid_body_modes': 'on', 'write_modes_vtk': 'on', 'print_matrices': 'on', 'write_data': 'on', 'continuous_eigenvalues': 'off', 'dt': dt, 'plot_eigenvalues': 'off' } settings['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', # 'mstar': int(120/tstep_factor), 'mstar': int(wake_length * m), 'freestream_dir': ['1', '0', '0'], 'control_surface_deflection': ['', ''], 'control_surface_deflection_generator': { '0': {}, '1': {} } } settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf, 'dt': dt } settings['AeroForcesCalculator'] = { 'folder': route + '/output/forces', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on' } # settings['BeamCsvOutput'] = {'folder': route + '/output/', # 'output_pos': 'on', # 'output_psi': 'on', # 'screen_output': 'off'} settings['BeamLoads'] = {'folder': route + '/output/', 'csv_output': 'off'} # Linear Model aero_settings = dict() aero_settings['remove_inputs'] = ['u_gust'] aero_settings['dt'] = dt aero_settings['density'] = rho beam_settings = dict() beam_settings['modal_projection'] = False beam_settings['discrete_time'] = True beam_settings['dt'] = dt beam_settings['use_euler'] = False beam_settings['gravity'] = True beam_settings['remove_dofs'] = [] beam_settings['print_info'] = True settings['LinearAssembler'] = { 'flow': ['LinearAeroelastic'], 'join_series': False, # 'LinearCustom':{'solver_name': 'plunge_solver', # 'solver_path': '../CC_DevTests/01_LinearAssembly/FlatPlate/cases'}, # 'LinearBeam': beam_settings, # 'LinearUVLM': aero_settings, 'LinearAeroelastic': { 'aero_settings': aero_settings, 'beam_settings': beam_settings, 'rigid_body_motion': True } } settings['AsymptoticStability'] = { 'sys_id': 'LinearAeroelastic', 'print_info': 'on', 'postprocessors': ['AerogridPlot'], 'postprocessors_settings': { 'AerogridPlot': settings['AerogridPlot'] } } import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def set_default_config_dict(self, route=None, case_name=None): """ Generates default solver configuration file Returns: """ if not route: route = self.case_route if not case_name: case_name = self.case_name u_inf = self.u_inf rho = self.rho dt = self.dt tolerance = self.tolerance alpha = self.alpha beta = self.beta thrust = self.thrust thrust_nodes = self.thrust_nodes cs_deflection = self.cs_deflection fsi_tolerance = self.fsi_tolerance n_tstep = self.n_tstep gust_intensity = self.gust_intensity relaxation_factor = self.relaxation_factor file_name = route + '/' + case_name + '.solver.txt' settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': route, 'flow': [ 'BeamLoader', 'AerogridLoader', 'StaticCoupled', 'AerogridPlot', 'BeamPlot', 'SaveData' ], 'write_screen': 'off', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'off', 'orientation': algebra.euler2quat(np.array([0.0, self.alpha, self.beta])) } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': self.horseshoe, 'num_cores': 4, 'n_rollup': 1, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho } settings['StaticCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 200, 'num_load_steps': 1, 'delta_curved': 1e-5, 'min_delta': tolerance, 'gravity_on': 'on', 'gravity': 9.81 }, 'aero_solver': 'StaticUvlm', 'aero_solver_settings': { 'print_info': 'on', 'horseshoe': self.horseshoe, 'num_cores': 4, 'n_rollup': int(1), 'rollup_dt': self.c_root / self.M / self.u_inf, 'n_rollup': int(1), 'rollup_dt': dt, #self.c_root / self.M / self.u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho }, 'max_iter': 200, 'n_load_steps': 1, 'tolerance': tolerance, 'relaxation_factor': 0.2 } if self.horseshoe is True: settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['1', '0', '0'], 'control_surface_deflection': [''] } else: settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': int(self.M * self.Mstarfactor), 'freestream_dir': ['1', '0', '0'], 'control_surface_deflection': [''] } settings['NonLinearStatic'] = { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-8, 'min_delta': tolerance, 'gravity_on': True, 'gravity': 9.81 } settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'thrust_nodes': thrust_nodes, 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust, 'max_iter': 200, 'fz_tolerance': 1e-2, 'fx_tolerance': 1e-2, 'm_tolerance': 1e-2 } settings['Trim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_beta': beta, 'cs_indices': [0], 'initial_cs_deflection': [cs_deflection], 'thrust_nodes': thrust_nodes, 'initial_thrust': [thrust, thrust] } settings['NonLinearDynamicCoupledStep'] = { 'print_info': 'off', 'initial_velocity_direction': [-1., 0., 0.], 'max_iterations': 950, 'delta_curved': 1e-6, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': True, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf * 0 } settings['NonLinearDynamicPrescribedStep'] = { 'print_info': 'off', 'initial_velocity_direction': [-1., 0., 0.], 'max_iterations': 950, 'delta_curved': 1e-6, 'min_delta': self.tolerance, 'newmark_damp': 5e-3, 'gravity_on': True, 'gravity': 9.81, 'num_steps': self.n_tstep, 'dt': self.dt } settings['StepLinearUVLM'] = { 'dt': self.dt, 'integr_order': 1, 'remove_predictor': True, 'use_sparse': True, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0., 0.], 'gust_shape': '1-cos', 'gust_length': 1., 'gust_intensity': self.gust_intensity * u_inf, 'offset': 30., 'span': self.span } } settings['StepUvlm'] = { 'print_info': 'off', 'horseshoe': self.horseshoe, 'num_cores': 4, 'n_rollup': 100, 'convection_scheme': self.wake_type, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': { 'u_inf': u_inf * 1, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': 1., 'gust_intensity': gust_intensity * u_inf, 'offset': 30.0, 'span': self.span }, # 'velocity_field_generator': 'SteadyVelocityField', # 'velocity_field_input': {'u_inf': u_inf*1, # 'u_inf_direction': [1., 0., 0.]}, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt, 'gamma_dot_filtering': 3 } settings['DynamicCoupled'] = { 'print_info': 'on', 'structural_substeps': 1, 'dynamic_relaxation': 'on', 'clean_up_previous_solution': 'on', 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': settings['NonLinearDynamicCoupledStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'off', 'postprocessors': ['BeamLoads', 'StallCheck', 'BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'BeamLoads': { 'folder': route + '/output/', 'csv_output': 'off' }, 'StallCheck': { 'output_degrees': True, 'stall_angles': { '0': [-12 * np.pi / 180, 6 * np.pi / 180], '1': [-12 * np.pi / 180, 6 * np.pi / 180], '2': [-12 * np.pi / 180, 6 * np.pi / 180] } }, 'BeamPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'u_inf': u_inf, 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 }, # 'WriteVariablesTime': { # # 'delimeter': ',', # # 'structure_nodes': [0], # # 'structure_variables': ['Z'] # # settings['WriteVariablesTime'] = {'delimiter': ' ', # 'FoR_variables': ['GFoR_pos', 'GFoR_vel', 'GFoR_acc'], # 'FoR_number': [], # 'structure_variables': ['AFoR_steady_forces', 'AFoR_unsteady_forces','AFoR_position'], # 'structure_nodes': [0,-1], # 'aero_panels_variables': ['gamma', 'gamma_dot'], # 'aero_panels_isurf': [0,1,2], # 'aero_panels_im': [1,1,1], # 'aero_panels_in': [-2,-2,-2], # 'aero_nodes_variables': ['GFoR_steady_force', 'GFoR_unsteady_force'], # 'aero_nodes_isurf': [0,1,2], # 'aero_nodes_im': [1,1,1], # 'aero_nodes_in': [-2,-2,-2] # }}} } } settings['Modal'] = { 'print_info': True, 'use_undamped_modes': False, 'NumLambda': 30, 'rigid_body': False, 'write_modes_vtk': 'on', 'print_matrices': 'on', 'write_data': 'on', 'continuous_eigenvalues': 'off', 'dt': dt, 'plot_eigenvalues': False } settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf } settings['AeroForcesCalculator'] = { 'folder': route + '/output/', 'write_text_file': 'off', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' } settings['BeamLoads'] = { 'folder': route + '/output/', 'csv_output': 'off' } settings['SaveData'] = {'folder': route + '/output'} config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write() self.settings = settings self.config = config
def generate_derivatives(alpha=0., elevator=0., thrust=0., dt=0.1, case_name='hale_static', case_route='./', **kwargs): output_route = kwargs.get('output_route', './output/') m = kwargs.get('M', 4) rho = kwargs.get('rho', 1.225) tolerance = kwargs.get('tolerance', 1e-5) hale = aircraft.Hale(case_name, case_route, output_route) hale.clean() hale.init_structure(**kwargs) hale.init_aero(m) hale.set_flight_controls(thrust=thrust, elevator=elevator) hale.generate() settings = dict() u_inf = kwargs.get('u_inf', 10) settings['SHARPy'] = {'case': case_name, 'route': case_route, 'flow': kwargs.get('flow', []), 'write_screen': 'on', 'write_log': 'on', 'log_folder': './output/', 'log_file': case_name + '.log'} settings['BeamLoader'] = {'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0., alpha, 0.]))} settings['AerogridLoader'] = {'unsteady': 'on', 'aligned_grid': 'on', 'mstar': int(kwargs.get('wake_length', 10) * m), 'control_surface_deflection': ['', ''], 'control_surface_deflection_generator_settings': {'0': {}, '1': {}}, 'wake_shape_generator': 'StraightWake', 'wake_shape_generator_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0., 0.], 'dt': dt, }, } settings['NonLinearStatic'] = {'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': tolerance, 'gravity_on': kwargs.get('gravity', 'on'), 'gravity': 10.6235, 'initial_position': [0., 0., 0.]} settings['StaticUvlm'] = {'print_info': 'on', 'horseshoe': kwargs.get('horseshoe', 'off'), 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': {'u_inf': u_inf, 'u_inf_direction': [1., 0, 0]}, 'rho': rho} settings['StaticCoupled'] = {'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': kwargs.get('n_load_steps', 1), 'tolerance': kwargs.get('fsi_tolerance', 1e-5), 'relaxation_factor': kwargs.get('relaxation_factor', 0.2)} settings['StaticTrim'] = {'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': elevator, 'initial_thrust': thrust, 'fz_tolerance': 0.1, 'fx_tolerance': 0.1, 'm_tolerance': 0.1, 'save_info': 'on', } settings['BeamPlot'] = { 'include_FoR': 'on'} settings['AerogridPlot'] = { 'include_rbm': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf } settings['AeroForcesCalculator'] = { 'write_text_file': 'on', 'text_file_name': 'aeroforces.txt', 'screen_output': 'on', 'coefficients': True, 'q_ref': 0.5 * rho * u_inf ** 2, 'S_ref': hale.structure.span_main * hale.aero.chord_main, } settings['BeamPlot'] = { 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_FoR': 'on'} struct_solver_settings = {'print_info': 'off', 'initial_velocity_direction': [-1., 0., 0.], 'max_iterations': 950, 'delta_curved': 1e-6, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': kwargs.get('gravity', 'on'), 'gravity': 10.6235, 'num_steps': 1, 'dt': dt, 'initial_velocity': u_inf * 1} step_uvlm_settings = {'print_info': 'on', 'num_cores': 4, 'convection_scheme': 2, #ws.wake_type, 'vortex_radius': 1e-6, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': {'u_inf': u_inf * 0, 'u_inf_direction': [1., 0., 0.]}, 'rho': rho, 'n_time_steps': 1, 'dt': dt, 'gamma_dot_filtering': 3} settings['DynamicCoupled'] = {'print_info': 'on', # 'structural_substeps': 1, # 'dynamic_relaxation': 'on', # 'clean_up_previous_solution': 'on', 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': struct_solver_settings, 'aero_solver': 'StepUvlm', 'aero_solver_settings': step_uvlm_settings, 'fsi_substeps': 200, 'fsi_tolerance': tolerance, 'relaxation_factor': 0.3, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.5, 'n_time_steps': 1, # ws.n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'off'} # 'postprocessors': ['BeamPlot', 'AerogridPlot', 'WriteVariablesTime'], # 'postprocessors_settings': {'BeamLoads': {'folder': output_route, # 'csv_output': 'off'}, # 'BeamPlot': {'folder': output_route, # 'include_rbm': 'on', # 'include_applied_forces': 'on'}, # 'AerogridPlot': { # 'u_inf': ws.u_inf, # 'folder': output_route, # 'include_rbm': 'on', # 'include_applied_forces': 'on', # 'minus_m_star': 0}, # 'WriteVariablesTime': { # 'folder': output_route, # 'cleanup_old_solution': 'on', # 'delimiter': ',', # 'FoR_variables': ['total_forces', # 'total_gravity_forces', # 'for_pos', 'quat'], # }}} settings['StabilityDerivatives'] = { 'u_inf': u_inf, 'c_ref': hale.aero.chord_main, 'b_ref': hale.structure.span_main * 2, 'S_ref': 2 * hale.structure.span_main * hale.aero.chord_main, } settings['Modal'] = {'print_info': True, 'use_undamped_modes': True, 'NumLambda': 50, 'rigid_body_modes': True, 'write_modes_vtk': 'on', 'print_matrices': 'on', 'save_data': 'on', 'continuous_eigenvalues': 'off', 'dt': dt, 'plot_eigenvalues': False, 'rigid_modes_ppal_axes': 'off', 'rigid_modes_cg': 'on', } # ROM settings rom_settings = dict() rom_settings['algorithm'] = 'mimo_rational_arnoldi' rom_settings['r'] = 4 rom_settings['frequency'] = np.array([0], dtype=float) rom_settings['single_side'] = 'observability' settings['LinearAssembler'] = {'linear_system': 'LinearAeroelastic', 'linear_system_settings': { 'beam_settings': {'modal_projection': 'on', 'inout_coords': 'modes', 'discrete_time': 'off', 'newmark_damp': 0.5e-3, 'discr_method': 'newmark', 'dt': dt, 'proj_modes': 'undamped', 'use_euler': 'on', 'num_modes': 20, 'print_info': 'on', 'gravity': kwargs.get('gravity', 'on'), 'remove_dofs': [], 'remove_rigid_states': 'on'}, 'aero_settings': {'dt': dt, # 'ScalingDict': {'length': hale.aero.chord_main / 2, # 'speed': u_inf, # 'density': rho}, 'integr_order': 2, 'density': rho, 'remove_predictor': 'off', 'use_sparse': False, 'vortex_radius': 1e-7, 'remove_inputs': ['u_gust'], 'convert_to_ct': 'on', # 'rom_method': ['Krylov'], # 'rom_method_settings': {'Krylov': rom_settings}, }, 'track_body': 'off', }} settings['AsymptoticStability'] = { 'print_info': 'on', 'modes_to_plot': [], # 'velocity_analysis': [27, 29, 3], 'display_root_locus': 'off', 'frequency_cutoff': 0, 'export_eigenvalues': 'on', 'num_evals': 1000, 'target_system': ['aeroelastic', 'aerodynamic', 'structural'], 'folder': output_route} settings['FrequencyResponse'] = {'target_system': ['aeroelastic', 'aerodynamic', 'structural'], 'quick_plot': 'off', 'frequency_spacing': 'log', 'frequency_unit': 'w', 'frequency_bounds': [1e-3, 1e3], 'num_freqs': 200, 'print_info': 'on'} settings['PickleData'] = {} hale.create_settings(settings) return hale
def generate_solver_file(horseshoe=False): file_name = route + '/' + case_name + '.solver.txt' # config = configparser.ConfigParser() settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': horseshoe_on, 'num_cores': 4, 'n_rollup': 1, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho } settings['StaticCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-5, 'min_delta': tolerance, 'gravity_on': 'on', 'gravity': 9.81 }, 'aero_solver': 'StaticUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': horseshoe_on, 'num_cores': 4, 'n_rollup': int(0 * 100), 'rollup_dt': c_root / m / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho, 'alpha': alpha_rad, 'beta': beta }, 'max_iter': 100, 'n_load_steps': 1, 'tolerance': fsi_tolerance, 'relaxation_factor': 0. } if horseshoe is True: settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['1', '0', '0'] } else: settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': int(wake_length / dt / u_inf), 'freestream_dir': ['1', '0', '0'] } settings['NonLinearStatic'] = { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-8, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 9.81 } # settings['StaticCoupled'] = {'print_info': 'off', # 'structural_solver': 'NonLinearStatic', # 'structural_solver_settings': settings['NonLinearStatic'], # 'aero_solver': 'StaticUvlm', # 'aero_solver_settings': settings['StaticUvlm'], # 'max_iter': 100, # 'n_load_steps': n_step, # 'tolerance': fsi_tolerance, # 'relaxation_factor': relaxation_factor} settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'thrust_nodes': thrust_nodes, 'initial_alpha': alpha_rad, 'initial_deflection': cs_deflection, 'initial_thrust': thrust } settings['Trim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha_rad, 'initial_beta': beta, 'cs_indices': [0], 'initial_cs_deflection': [cs_deflection], 'thrust_nodes': thrust_nodes, 'initial_thrust': [thrust] } settings['NonLinearDynamicCoupledStep'] = { 'print_info': 'off', 'initial_velocity_direction': [-1., 0., 0.], 'max_iterations': 950, 'delta_curved': 1e-6, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf * 0 } settings['StepUvlm'] = { 'print_info': 'off', 'horseshoe': horseshoe_on, 'num_cores': 4, 'n_rollup': 100, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, # 'velocity_field_generator': 'TurbSimVelocityField', # 'velocity_field_input': {'turbulent_field': '/2TB/turbsim_fields/TurbSim_wide_long_A_low.h5', # 'offset': [30., 0., -10], # 'u_inf': 0.}, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': .5, 'gust_intensity': gust_intensity * u_inf, 'offset': 30.0, 'span': span }, # 'velocity_field_generator': 'SteadyVelocityField', # 'velocity_field_input': {'u_inf': u_inf*1, # 'u_inf_direction': [1., 0., 0.]}, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt } settings['DynamicCoupled'] = { 'print_info': 'on', 'structural_substeps': 1, 'dynamic_relaxation': 'on', 'clean_up_previous_solution': 'on', 'structural_solver': 'NonLinearDynamicCoupledStep', 'structural_solver_settings': settings['NonLinearDynamicCoupledStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'off', 'postprocessors': ['BeamLoads', 'StallCheck', 'BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'BeamLoads': { 'folder': route + '/output/', 'csv_output': 'off' }, 'StallCheck': { 'output_degrees': True, 'stall_angles': { '0': [-12 * np.pi / 180, 6 * np.pi / 180], '1': [-12 * np.pi / 180, 6 * np.pi / 180], '2': [-12 * np.pi / 180, 6 * np.pi / 180] } }, 'BeamPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on' }, 'AerogridPlot': { 'u_inf': u_inf, 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0 } } } settings['Modal'] = { 'print_info': True, 'use_undamped_modes': False, 'NumLambda': 20, 'write_modes_vtk': 'on', 'print_matrices': 'on', 'write_data': 'on', 'continuous_eigenvalues': 'off', 'dt': dt, 'plot_eigenvalues': False } settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf } settings['AeroForcesCalculator'] = { 'folder': route + '/output/forces', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'off', 'include_applied_forces': 'on' } settings['BeamLoads'] = {'folder': route + '/output/', 'csv_output': 'off'} import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
] settings = dict() settings['SHARPy'] = { 'case': ws.case_name, 'route': ws.case_route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': './output/' + ws.case_name + '/', 'log_file': ws.case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'off', 'orientation': algebra.euler2quat(np.array([ws.roll, ws.alpha, ws.beta])) } if ws.horseshoe is True: settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['1', '0', '0'], 'control_surface_deflection': [''] } else: settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': int(ws.M * ws.Mstarfactor),
def generate_forces(alpha=0., elevator=0., thrust=0., dt=0.1, case_name='hale_forces', case_route='./', **kwargs): output_route = kwargs.get('output_route', './output/') m = kwargs.get('M', 4) rho = kwargs.get('rho', 1.225) tolerance = kwargs.get('tolerance', 1e-5) hale = aircraft.Hale(case_name, case_route, output_route) hale.clean() hale.init_structure(**kwargs) hale.init_aero(m) hale.set_flight_controls(thrust=thrust, elevator=elevator) hale.generate() settings = dict() u_inf = kwargs.get('u_inf', 10) settings['SHARPy'] = { 'case': case_name, 'route': case_route, 'flow': kwargs.get('flow', []), 'write_screen': 'on', 'write_log': 'on', 'log_folder': './output/', 'log_file': case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0., alpha, 0.])) } settings['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': int(kwargs.get('wake_length', 10) * m), 'control_surface_deflection': ['', ''], 'control_surface_deflection_generator_settings': { '0': {}, '1': {} }, 'wake_shape_generator': 'StraightWake', 'wake_shape_generator_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0., 0.], 'dt': dt, }, } settings['NonLinearStatic'] = { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': tolerance, 'gravity_on': kwargs.get('gravity', 'on'), 'gravity': 10.6235, 'initial_position': [0., 0., 0.] } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': kwargs.get('horseshoe', 'off'), 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho } settings['StaticCoupled'] = { 'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': kwargs.get('n_load_steps', 1), 'tolerance': kwargs.get('fsi_tolerance', 1e-5), 'relaxation_factor': kwargs.get('relaxation_factor', 0.2) } settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': elevator, 'initial_thrust': thrust, 'fz_tolerance': 0.1, 'fx_tolerance': 0.1, 'm_tolerance': 0.1, 'save_info': 'on', } settings['BeamPlot'] = {'include_FoR': 'on'} settings['AerogridPlot'] = { 'include_rbm': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf } settings['AeroForcesCalculator'] = { 'write_text_file': 'on', 'text_file_name': 'aeroforces.txt', 'screen_output': 'on', 'coefficients': True, 'q_ref': 0.5 * rho * u_inf**2, 'S_ref': 2 * hale.structure.span_main * hale.aero.chord_main, 'b_ref': 2 * hale.structure.span_main } settings['SaveParametricCase'] = { 'save_case': 'off', 'parameters': { 'alpha': alpha } } hale.create_settings(settings) hale.run()
def generate_solver_file(): file_name = route + '/' + case_name + '.solver.txt' aux_settings = dict() settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': route, 'flow': [ 'BeamLoader', 'AerogridLoader', 'StaticCoupled', 'BeamPlot', 'AerogridPlot', 'DynamicPrescribedCoupled', 'Modal' ], 'write_screen': 'off', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } # AUX DICTIONARIES aux_settings['velocity_field_input'] = { 'u_inf': 100.0, 'u_inf_direction': [0.0, -1.0, 0.0] } # LOADERS settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([0.0, 0.0, 0.0])) } settings['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['0', '-1', '0'] } # POSTPROCESS settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': 100.0, 'dt': dt } #settings['AeroForcesCalculator'] = {'folder': route + '/output/forces', #'write_text_file': 'on', #'text_file_name': case_name + '_aeroforces.csv', #'screen_output': 'on', #'unsteady': 'off'} settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on' } #settings['BeamCsvOutput'] = {'folder': route + '/output/', #'output_pos': 'on', #'output_psi': 'on', #'screen_output': 'off'} settings['BeamLoads'] = {} # STATIC COUPLED settings['NonLinearStatic'] = { 'print_info': 'on', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-15, 'min_delta': 1e-8, 'gravity_on': 'off', 'gravity': 9.81 } settings['StaticUvlm'] = { 'print_info': 'on', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': aux_settings['velocity_field_input'], 'rho': 0.0 } settings['StaticCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': 4, 'tolerance': 1e-8, 'relaxation_factor': 0 } # DYNAMIC PRESCRIBED COUPLED settings['NonLinearDynamicPrescribedStep'] = { 'print_info': 'on', 'max_iterations': 95000, 'delta_curved': 1e-9, 'min_delta': 1e-6, 'newmark_damp': 1e-3, 'gravity_on': 'off', 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt } settings['StepUvlm'] = { 'print_info': 'on', 'horseshoe': 'off', 'num_cores': 4, 'n_rollup': 0, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': aux_settings['velocity_field_input'], 'rho': 0.0, 'n_time_steps': n_tstep, 'dt': dt } settings['DynamicPrescribedCoupled'] = { 'structural_solver': 'NonLinearDynamicPrescribedStep', 'structural_solver_settings': settings['NonLinearDynamicPrescribedStep'], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 20000, 'fsi_tolerance': 1e-9, 'relaxation_factor': 0, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.0, 'n_time_steps': n_tstep, 'dt': dt, 'postprocessors': ['BeamPlot', 'AerogridPlot'], 'postprocessors_settings': { 'BeamPlot': settings['BeamPlot'], 'AerogridPlot': settings['AerogridPlot'] } } settings['Modal'] = { 'folder': route + '/output', 'include_rbm': 'on', 'NumLambda': 10000, 'num_steps': 1, 'print_matrices': 'on' } import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def generate_solver_file(): file_name = route + '/' + case_name + '.sharpy' settings = dict() settings['SHARPy'] = { 'case': case_name, 'route': route, 'flow': flow, 'write_screen': 'off', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } settings['BeamLoader'] = { 'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([roll, alpha, beta])) } settings['AerogridLoader'] = { 'unsteady': 'on', 'aligned_grid': 'on', # 'mstar': int(160/tstep_factor), 'mstar': int(100 / tstep_factor), 'freestream_dir': ['1', '0', '0'], 'control_surface_deflection': ['', ''], 'control_surface_deflection_generator': { '0': {}, '1': {} } } settings['NonLinearStatic'] = { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 0 * 9.81 } settings['StaticUvlm'] = { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_background, 'u_inf_direction': [1., 0, 0] }, 'rho': 0 * rho } settings['StaticCoupled'] = { 'print_info': 'off', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': n_step, 'tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor } settings['StaticTrim'] = { 'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust } settings['NonLinearDynamicCoupledStep'] = { 'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 1e-2, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': 0 } settings['NonLinearDynamicMultibody'] = { 'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 1e-2, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt } relative_motion = 'off' settings['StepUvlm'] = { 'print_info': 'off', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'gamma_dot_filtering': 6, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_background, 'u_inf_direction': [1., 0, 0] }, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt } solver = 'NonLinearDynamicMultibody' settings['PickleData'] = {'folder': route + '/'} settings['DynamicCoupled'] = {'structural_solver': solver, 'structural_solver_settings': settings[solver], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 2, 'relaxation_steps': 150, 'dynamic_relaxation': 'off', 'final_relaxation_factor': 0.5, 'n_time_steps': n_tstep, 'dt': dt, 'structural_substeps': structural_substeps, 'include_unsteady_force_contribution': 'on', 'steps_without_unsteady_force': 9, 'controller_id': {#'controller_right': 'TakeOffTrajectoryController', # 'controller_left': 'TakeOffTrajectoryController', 'controller_tail': 'TakeOffTrajectoryController', 'controller_cright': 'TakeOffTrajectoryController', 'controller_cleft': 'TakeOffTrajectoryController', }, 'controller_settings': { # 'controller_right': # { # 'trajectory_input_file': trajectory_file, # 'dt': dt, # 'trajectory_method': 'lagrange', # 'controlled_constraint': 'constraint_00', # 'initial_ramp_length_structural_substeps': controller_ramp, # 'write_controller_log': 'off', # }, # 'controller_left': # { # 'trajectory_input_file': trajectory_file, # 'dt': dt, # 'trajectory_method': 'lagrange', # 'controlled_constraint': 'constraint_01', # 'initial_ramp_length_structural_substeps': controller_ramp, # 'write_controller_log': 'off', # }, 'controller_tail': { 'trajectory_input_file': trajectory_file, 'dt': dt, 'trajectory_method': 'lagrange', 'controlled_constraint': 'constraint_00', 'initial_ramp_length_structural_substeps': controller_ramp, 'write_controller_log': 'off', }, 'controller_cright': { 'trajectory_input_file': trajectory_file, 'dt': dt, 'trajectory_method': 'lagrange', 'controlled_constraint': 'constraint_01', 'initial_ramp_length_structural_substeps': controller_ramp, 'write_controller_log': 'off', }, 'controller_cleft': { 'trajectory_input_file': trajectory_file, 'dt': dt, 'trajectory_method': 'lagrange', 'controlled_constraint': 'constraint_02', 'initial_ramp_length_structural_substeps': controller_ramp, 'write_controller_log': 'off', }}, 'postprocessors': ['BeamLoads'], 'postprocessors_settings': {'BeamLoads': {'folder': route + '/output/', 'csv_output': 'off'}, 'BeamPlot': {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on'}, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0}, } } settings['BeamLoads'] = { 'folder': route + '/output/', 'csv_output': 'off' } settings['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on' } settings['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': 0, 'dt': dt } settings['Notes'] = {'note': case_notes} import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def generate_from_excel_type02( chord_panels, rotation_velocity, pitch_deg, excel_file_name='database_excel_type02.xlsx', excel_sheet_parameters='parameters', excel_sheet_structural_blade='structural_blade', excel_sheet_discretization_blade='discretization_blade', excel_sheet_aero_blade='aero_blade', excel_sheet_airfoil_info='airfoil_info', excel_sheet_airfoil_coord='airfoil_coord', excel_sheet_structural_tower='structural_tower', m_distribution='uniform', h5_cross_sec_prop=None, n_points_camber=100, tol_remove_points=1e-3, user_defined_m_distribution_type=None, wsp=0., dt=0.): """ generate_from_excel_type02 Function needed to generate a wind turbine from an excel database according to OpenFAST inputs Args: chord_panels (int): Number of panels on the blade surface in the chord direction rotation_velocity (float): Rotation velocity of the rotor pitch_deg (float): pitch angle in degrees excel_file_name (str): excel_sheet_structural_blade (str): excel_sheet_aero_blade (str): excel_sheet_airfoil_coord (str): excel_sheet_parameters (str): excel_sheet_structural_tower (str): m_distribution (str): n_points_camber (int): number of points to define the camber of the airfoil, tol_remove_points (float): maximum distance to remove adjacent points user_defined_m_distribution_type (string): type of distribution of the chordwise panels when 'm_distribution' == 'user_defined' camber_effects_on_twist (bool): When true plain airfoils are used and the blade is twisted and preloaded based on thin airfoil theory wsp (float): wind speed (It may be needed for discretisation purposes) dt (float): time step (It may be needed for discretisation purposes) Returns: wt (sharpy.utils.generate_cases.AeroelasticInfromation): Aeroelastic infrmation of the wind turbine LC (list): list of all the Lagrange constraints needed in the cases (sharpy.utils.generate_cases.LagrangeConstraint) MB (list): list of the multibody information of each body (sharpy.utils.generate_cases.BodyInfrmation) """ rotor = rotor_from_excel_type02( chord_panels, rotation_velocity, pitch_deg, excel_file_name=excel_file_name, excel_sheet_parameters=excel_sheet_parameters, excel_sheet_structural_blade=excel_sheet_structural_blade, excel_sheet_discretization_blade=excel_sheet_discretization_blade, excel_sheet_aero_blade=excel_sheet_aero_blade, excel_sheet_airfoil_info=excel_sheet_airfoil_info, excel_sheet_airfoil_coord=excel_sheet_airfoil_coord, m_distribution=m_distribution, h5_cross_sec_prop=h5_cross_sec_prop, n_points_camber=n_points_camber, tol_remove_points=tol_remove_points, user_defined_m_distribution_type=user_defined_m_distribution_type, wsp=0., dt=0.) ###################################################################### ## TOWER ###################################################################### # Read from excel file HtFract = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'HtFract') TMassDen = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TMassDen') TwFAStif = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwFAStif') TwSSStif = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwSSStif') # TODO> variables to be defined TwGJStif = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwGJStif') TwEAStif = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwEAStif') TwFAIner = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwFAIner') TwSSIner = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwSSIner') TwFAcgOf = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwFAcgOf') TwSScgOf = gc.read_column_sheet_type01(excel_file_name, excel_sheet_structural_tower, 'TwSScgOf') # Define the TOWER TowerHt = gc.read_column_sheet_type01(excel_file_name, excel_sheet_parameters, 'TowerHt') Elevation = TowerHt * HtFract tower = gc.AeroelasticInformation() tower.StructuralInformation.num_elem = len(Elevation) - 2 tower.StructuralInformation.num_node_elem = 3 tower.StructuralInformation.compute_basic_num_node() # Interpolate excel variables into the correct locations node_r, elem_r = create_node_radial_pos_from_elem_centres( Elevation, tower.StructuralInformation.num_node, tower.StructuralInformation.num_elem, tower.StructuralInformation.num_node_elem) # Stiffness elem_EA = np.interp(elem_r, Elevation, TwEAStif) elem_EIz = np.interp(elem_r, Elevation, TwSSStif) elem_EIy = np.interp(elem_r, Elevation, TwFAStif) elem_GJ = np.interp(elem_r, Elevation, TwGJStif) # Stiffness: estimate unknown properties cout.cout_wrap.print_file = False cout.cout_wrap('WARNING: The poisson cofficient is assumed equal to 0.3', 3) cout.cout_wrap('WARNING: Cross-section area is used as shear area', 3) poisson_coef = 0.3 elem_GAy = elem_EA / 2.0 / (1.0 + poisson_coef) elem_GAz = elem_EA / 2.0 / (1.0 + poisson_coef) # Inertia elem_mass_per_unit_length = np.interp(elem_r, Elevation, TMassDen) elem_mass_iner_y = np.interp(elem_r, Elevation, TwFAIner) elem_mass_iner_z = np.interp(elem_r, Elevation, TwSSIner) # TODO: check yz axis and Flap-edge elem_pos_cg_B = np.zeros((tower.StructuralInformation.num_elem, 3), ) elem_pos_cg_B[:, 1] = np.interp(elem_r, Elevation, TwSScgOf) elem_pos_cg_B[:, 2] = np.interp(elem_r, Elevation, TwFAcgOf) # Stiffness: estimate unknown properties cout.cout_wrap( 'WARNING: Using perpendicular axis theorem to compute the inertia around xB', 3) elem_mass_iner_x = elem_mass_iner_y + elem_mass_iner_z # Create the tower tower.StructuralInformation.create_mass_db_from_vector( elem_mass_per_unit_length, elem_mass_iner_x, elem_mass_iner_y, elem_mass_iner_z, elem_pos_cg_B) tower.StructuralInformation.create_stiff_db_from_vector( elem_EA, elem_GAy, elem_GAz, elem_GJ, elem_EIy, elem_EIz) coordinates = np.zeros((tower.StructuralInformation.num_node, 3), ) coordinates[:, 0] = node_r tower.StructuralInformation.generate_1to1_from_vectors( num_node_elem=tower.StructuralInformation.num_node_elem, num_node=tower.StructuralInformation.num_node, num_elem=tower.StructuralInformation.num_elem, coordinates=coordinates, stiffness_db=tower.StructuralInformation.stiffness_db, mass_db=tower.StructuralInformation.mass_db, frame_of_reference_delta='y_AFoR', vec_node_structural_twist=np.zeros( (tower.StructuralInformation.num_node, ), ), num_lumped_mass=1) tower.StructuralInformation.boundary_conditions = np.zeros( (tower.StructuralInformation.num_node), dtype=int) tower.StructuralInformation.boundary_conditions[0] = 1 # Read overhang and nacelle properties from excel file overhang_len = gc.read_column_sheet_type01(excel_file_name, excel_sheet_parameters, 'overhang') # HubMass = gc.read_column_sheet_type01(excel_file_name, excel_sheet_nacelle, 'HubMass') NacelleMass = gc.read_column_sheet_type01(excel_file_name, excel_sheet_parameters, 'NacMass') # NacelleYawIner = gc.read_column_sheet_type01(excel_file_name, excel_sheet_nacelle, 'NacelleYawIner') # Include nacelle mass tower.StructuralInformation.lumped_mass_nodes = np.array( [tower.StructuralInformation.num_node - 1], dtype=int) tower.StructuralInformation.lumped_mass = np.array([NacelleMass], dtype=float) tower.AerodynamicInformation.set_to_zero( tower.StructuralInformation.num_node_elem, tower.StructuralInformation.num_node, tower.StructuralInformation.num_elem) # Assembly overhang with the tower # numberOfBlades = gc.read_column_sheet_type01(excel_file_name, excel_sheet_parameters, 'NumBl') tilt = gc.read_column_sheet_type01(excel_file_name, excel_sheet_parameters, 'ShftTilt') * deg2rad # cone = gc.read_column_sheet_type01(excel_file_name, excel_sheet_parameters, 'Cone')*deg2rad overhang = gc.AeroelasticInformation() overhang.StructuralInformation.num_node = 3 overhang.StructuralInformation.num_node_elem = 3 overhang.StructuralInformation.compute_basic_num_elem() node_pos = np.zeros((overhang.StructuralInformation.num_node, 3), ) node_pos[:, 0] += tower.StructuralInformation.coordinates[-1, 0] node_pos[:, 0] += np.linspace(0., overhang_len * np.sin(tilt * deg2rad), overhang.StructuralInformation.num_node) node_pos[:, 2] = np.linspace(0., -overhang_len * np.cos(tilt * deg2rad), overhang.StructuralInformation.num_node) # TODO: change the following by real values # Same properties as the last element of the tower cout.cout_wrap( "WARNING: Using the structural properties of the last tower section for the overhang", 3) oh_mass_per_unit_length = tower.StructuralInformation.mass_db[-1, 0, 0] oh_mass_iner = tower.StructuralInformation.mass_db[-1, 3, 3] oh_EA = tower.StructuralInformation.stiffness_db[-1, 0, 0] oh_GA = tower.StructuralInformation.stiffness_db[-1, 1, 1] oh_GJ = tower.StructuralInformation.stiffness_db[-1, 3, 3] oh_EI = tower.StructuralInformation.stiffness_db[-1, 4, 4] overhang.StructuralInformation.generate_uniform_sym_beam( node_pos, oh_mass_per_unit_length, oh_mass_iner, oh_EA, oh_GA, oh_GJ, oh_EI, num_node_elem=3, y_BFoR='y_AFoR', num_lumped_mass=0) overhang.StructuralInformation.boundary_conditions = np.zeros( (overhang.StructuralInformation.num_node), dtype=int) overhang.StructuralInformation.boundary_conditions[-1] = -1 overhang.AerodynamicInformation.set_to_zero( overhang.StructuralInformation.num_node_elem, overhang.StructuralInformation.num_node, overhang.StructuralInformation.num_elem) tower.assembly(overhang) tower.remove_duplicated_points(tol_remove_points) ###################################################################### ## WIND TURBINE ###################################################################### # Assembly the whole case wt = tower.copy() hub_position = tower.StructuralInformation.coordinates[-1, :] rotor.StructuralInformation.coordinates += hub_position wt.assembly(rotor) # Redefine the body numbers wt.StructuralInformation.body_number *= 0 wt.StructuralInformation.body_number[tower.StructuralInformation. num_elem:wt.StructuralInformation. num_elem] += 1 ###################################################################### ## MULTIBODY ###################################################################### # Define the boundary condition between the rotor and the tower tip LC1 = gc.LagrangeConstraint() LC1.behaviour = 'hinge_node_FoR_constant_vel' LC1.node_in_body = tower.StructuralInformation.num_node - 1 LC1.body = 0 LC1.body_FoR = 1 LC1.rot_axisB = np.array([1., 0., 0.0]) LC1.rot_vel = -rotation_velocity LC = [] LC.append(LC1) # Define the multibody infromation for the tower and the rotor MB1 = gc.BodyInformation() MB1.body_number = 0 MB1.FoR_position = np.zeros((6, ), ) MB1.FoR_velocity = np.zeros((6, ), ) MB1.FoR_acceleration = np.zeros((6, ), ) MB1.FoR_movement = 'prescribed' MB1.quat = np.array([1.0, 0.0, 0.0, 0.0]) MB2 = gc.BodyInformation() MB2.body_number = 1 MB2.FoR_position = np.array([ rotor.StructuralInformation.coordinates[0, 0], rotor.StructuralInformation.coordinates[0, 1], rotor.StructuralInformation.coordinates[0, 2], 0.0, 0.0, 0.0 ]) MB2.FoR_velocity = np.array([0., 0., 0., 0., 0., rotation_velocity]) MB2.FoR_acceleration = np.zeros((6, ), ) MB2.FoR_movement = 'free' MB2.quat = algebra.euler2quat(np.array([0.0, tilt, 0.0])) MB = [] MB.append(MB1) MB.append(MB2) ###################################################################### ## RETURN ###################################################################### return wt, LC, MB
def generate_solver_file(horseshoe=False): file_name = route + '/' + case_name + '.sharpy' # config = configparser.ConfigParser() import configobj config = configobj.ConfigObj() config.filename = file_name config['SHARPy'] = { 'case': case_name, 'route': route, 'flow': [ 'BeamLoader', 'AerogridLoader', 'StaticCoupled', 'AerogridPlot', 'BeamPlot', 'AeroForcesCalculator', 'WriteVariablesTime' ], # 'flow': ['BeamLoader', 'NonLinearStatic', 'BeamPlot'], 'write_screen': 'off', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log' } config['BeamLoader'] = { 'unsteady': 'off', 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) } config['StaticCoupled'] = { 'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': { 'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': 1e-6, 'gravity_on': 'on', 'gravity': 9.754, 'orientation': algebra.euler2quat(np.array([0.0, alpha_rad, beta * np.pi / 180])) }, 'aero_solver': 'StaticUvlm', 'aero_solver_settings': { 'print_info': 'off', 'horseshoe': 'on', 'num_cores': 4, 'n_rollup': 0, 'rollup_dt': main_chord / m_main / u_inf, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': { 'u_inf': u_inf, 'u_inf_direction': [1., 0, 0] }, 'rho': rho, 'alpha': alpha_rad, 'beta': beta }, 'max_iter': 50, # 'n_load_steps': 1, # 'n_load_steps': 5, 'tolerance': 1e-9, 'relaxation_factor': 0.0 } config['WriteVariablesTime'] = { 'cleanup_old_solution': 'on', 'folder': route + '/output/', 'structure_variables': ['pos'], 'structure_nodes': [num_node_main - 1] } if horseshoe is True: config['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': 1, 'freestream_dir': ['1', '0', '0'], 'wake_shape_generator': 'StraightWake', 'wake_shape_generator_input': { 'u_inf': u_inf, 'u_inf_direction': np.array([1., 0., 0.]), 'dt': main_chord / m_main / u_inf } } else: config['AerogridLoader'] = { 'unsteady': 'off', 'aligned_grid': 'on', 'mstar': 20, 'freestream_dir': ['1', '0', '0'], 'wake_shape_generator': 'StraightWake', 'wake_shape_generator_input': { 'u_inf': u_inf, 'u_inf_direction': np.array([1., 0., 0.]), 'dt': main_chord / m_main / u_inf } } config['AerogridPlot'] = { 'folder': route + '/output/', 'include_rbm': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0 } config['AeroForcesCalculator'] = { 'folder': route + '/output/forces', 'write_text_file': 'on', 'text_file_name': case_name + '_aeroforces.csv', 'screen_output': 'on', 'unsteady': 'off' } config['BeamPlot'] = { 'folder': route + '/output/', 'include_rbm': 'off', 'include_applied_forces': 'on' } config.write()
def generate_solver_file(): file_name = route + '/' + case_name + '.solver.txt' settings = dict() settings['SHARPy'] = {'case': case_name, 'route': route, 'flow': flow, 'write_screen': 'on', 'write_log': 'on', 'log_folder': route + '/output/', 'log_file': case_name + '.log'} settings['BeamLoader'] = {'unsteady': 'on', 'orientation': algebra.euler2quat(np.array([roll, alpha, beta]))} settings['AerogridLoader'] = {'unsteady': 'on', 'aligned_grid': 'on', 'mstar': int(20/tstep_factor), 'freestream_dir': ['1', '0', '0'], 'control_surface_deflection': ['', ''], 'control_surface_deflection_generator': {'0': {}, '1': {}}} settings['NonLinearStatic'] = {'print_info': 'off', 'max_iterations': 150, 'num_load_steps': 1, 'delta_curved': 1e-1, 'min_delta': tolerance, 'gravity_on': gravity, 'gravity': 9.81} settings['StaticUvlm'] = {'print_info': 'on', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'velocity_field_generator': 'SteadyVelocityField', 'velocity_field_input': {'u_inf': u_inf, 'u_inf_direction': [1., 0, 0]}, 'rho': rho} settings['StaticCoupled'] = {'print_info': 'on', 'structural_solver': 'NonLinearStatic', 'structural_solver_settings': settings['NonLinearStatic'], 'aero_solver': 'StaticUvlm', 'aero_solver_settings': settings['StaticUvlm'], 'max_iter': 100, 'n_load_steps': n_step, 'tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor} settings['StaticTrim'] = {'solver': 'StaticCoupled', 'solver_settings': settings['StaticCoupled'], 'initial_alpha': alpha, 'initial_deflection': cs_deflection, 'initial_thrust': thrust} settings['NonLinearDynamicCoupledStep'] = {'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf} settings['NonLinearDynamicPrescribedStep'] = {'print_info': 'off', 'max_iterations': 950, 'delta_curved': 1e-1, 'min_delta': tolerance, 'newmark_damp': 5e-3, 'gravity_on': gravity, 'gravity': 9.81, 'num_steps': n_tstep, 'dt': dt, 'initial_velocity': u_inf} relative_motion = 'off' settings['StepUvlm'] = {'print_info': 'off', 'horseshoe': 'off', 'num_cores': num_cores, 'n_rollup': 0, 'convection_scheme': 2, 'rollup_dt': dt, 'rollup_aic_refresh': 1, 'rollup_tolerance': 1e-4, 'gamma_dot_filtering': 6, 'velocity_field_generator': 'GustVelocityField', 'velocity_field_input': {'u_inf': 0, 'u_inf_direction': [1., 0, 0], 'gust_shape': '1-cos', 'gust_length': gust_length, 'gust_intensity': gust_intensity*u_inf, 'offset': gust_offset, 'span': span_main, 'relative_motion': relative_motion}, 'rho': rho, 'n_time_steps': n_tstep, 'dt': dt} solver = 'NonLinearDynamicCoupledStep' settings['DynamicCoupled'] = {'structural_solver': solver, 'structural_solver_settings': settings[solver], 'aero_solver': 'StepUvlm', 'aero_solver_settings': settings['StepUvlm'], 'fsi_substeps': 200, 'fsi_tolerance': fsi_tolerance, 'relaxation_factor': relaxation_factor, 'minimum_steps': 1, 'relaxation_steps': 150, 'final_relaxation_factor': 0.5, 'n_time_steps': n_tstep, 'dt': dt, 'include_unsteady_force_contribution': 'on', 'postprocessors': ['BeamLoads', 'BeamPlot', 'AerogridPlot'], 'postprocessors_settings': {'BeamLoads': {'folder': route + '/output/', 'csv_output': 'off'}, 'BeamPlot': {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on'}, 'AerogridPlot': { 'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0}, }} settings['BeamLoads'] = {'folder': route + '/output/', 'csv_output': 'off'} settings['BeamPlot'] = {'folder': route + '/output/', 'include_rbm': 'on', 'include_applied_forces': 'on', 'include_forward_motion': 'on'} settings['AerogridPlot'] = {'folder': route + '/output/', 'include_rbm': 'on', 'include_forward_motion': 'off', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': u_inf, 'dt': dt} import configobj config = configobj.ConfigObj() config.filename = file_name for k, v in settings.items(): config[k] = v config.write()
def solver_wrapper(x, x_info, solver_data, i_dim=-1): if solver_data.settings['print_info']: cout.cout_wrap('x = ' + str(x), 1) # print('x = ', x) alpha = x[x_info['i_alpha']] beta = x[x_info['i_beta']] roll = x[x_info['i_roll']] # change input data solver_data.data.structure.timestep_info[ solver_data.data.ts] = solver_data.data.structure.ini_info.copy() tstep = solver_data.data.structure.timestep_info[solver_data.data.ts] aero_tstep = solver_data.data.aero.timestep_info[solver_data.data.ts] orientation_quat = algebra.euler2quat(np.array([roll, alpha, beta])) tstep.quat[:] = orientation_quat # control surface deflection for i_cs in range(len(x_info['i_control_surfaces'])): solver_data.data.aero.aero_dict['control_surface_deflection'][ x_info['control_surfaces_id'][i_cs]] = x[ x_info['i_control_surfaces'][i_cs]] # thrust input tstep.steady_applied_forces[:] = 0.0 try: x_info['special_case'] except KeyError: for i_thrust in range(len(x_info['i_thrust'])): thrust = x[x_info['i_thrust'][i_thrust]] i_node = x_info['thrust_nodes'][i_thrust] solver_data.data.structure.ini_info.steady_applied_forces[ i_node, 0:3] = thrust * x_info['thrust_direction'][i_thrust] else: if x_info['special_case'] == 'differential_thrust': base_thrust = x[x_info['i_base_thrust']] pos_thrust = base_thrust * (1.0 + x[x_info['i_differential_parameter']]) neg_thrust = -base_thrust * (1.0 - x[x_info['i_differential_parameter']]) for i_base_node in x_info['base_thrust_nodes']: solver_data.data.structure.ini_info.steady_applied_forces[ i_base_node, 1] = base_thrust for i_pos_diff_node in x_info['positive_thrust_nodes']: solver_data.data.structure.ini_info.steady_applied_forces[ i_pos_diff_node, 1] = pos_thrust for i_neg_diff_node in x_info['negative_thrust_nodes']: solver_data.data.structure.ini_info.steady_applied_forces[ i_neg_diff_node, 1] = neg_thrust # run the solver solver_data.solver.run() # extract resultants forces, moments = solver_data.solver.extract_resultants() totals = np.zeros((6, )) totals[0:3] = forces totals[3:6] = moments if solver_data.settings['print_info']: cout.cout_wrap(' forces = ' + str(totals), 1) # print('total forces = ', totals) # try: # totals += x[x_info['i_none']] # except KeyError: # pass # return resultant forces and moments # return np.linalg.norm(totals) if i_dim >= 0: return totals[i_dim] elif i_dim == -1: # return [np.sum(totals[0:3]**2), np.sum(totals[4:6]**2)] return totals elif i_dim == -2: coeffs = np.array([1.0, 1.0, 1.0, 2, 2, 2]) # print('return = ', np.dot(coeffs*totals, coeffs*totals)) if solver_data.settings['print_info']: cout.cout_wrap( ' val = ' + str(np.dot(coeffs * totals, coeffs * totals)), 1) return np.dot(coeffs * totals, coeffs * totals)