def initialise(self, data): self.data = data self.settings = data.settings[self.solver_id] settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.dt = self.settings['dt'] self.aero_solver = solver_interface.initialise_solver(self.settings['aero_solver']) self.aero_solver.initialise(self.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data # if there's data in timestep_info[>0], copy the last one to # timestep_info[0] and remove the rest self.cleanup_timestep_info() # initialise postprocessors self.postprocessors = dict() if len(self.settings['postprocessors']) > 0: self.with_postprocessors = True for postproc in self.settings['postprocessors']: self.postprocessors[postproc] = solver_interface.initialise_solver(postproc) self.postprocessors[postproc].initialise( self.data, self.settings['postprocessors_settings'][postproc], caller=self) self.residual_table = cout.TablePrinter(2, 14, ['g', 'f']) self.residual_table.field_length[0] = 6 self.residual_table.field_length[1] = 6 self.residual_table.print_header(['ts', 't'])
def initialise(self, data, input_dict=None): self.data = data if input_dict is None: self.settings = data.settings[self.solver_id] else: self.settings = input_dict settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.print_info = self.settings['print_info'] self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data if self.print_info: self.residual_table = cout.TablePrinter( 9, 8, ['g', 'g', 'f', 'f', 'f', 'f', 'f', 'f', 'f']) self.residual_table.field_length[0] = 3 self.residual_table.field_length[1] = 3 self.residual_table.field_length[2] = 10 self.residual_table.print_header([ 'iter', 'step', 'log10(res)', 'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz' ])
def initialise(self, data, custom_settings=None): self.data = data if custom_settings is None: self.settings = data.settings[self.solver_id] else: self.settings = custom_settings settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.dt = self.settings['dt'] self.print_info = self.settings['print_info'].value self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data # initialise postprocessors self.postprocessors = dict() if len(self.settings['postprocessors']) > 0: self.with_postprocessors = True for postproc in self.settings['postprocessors']: self.postprocessors[postproc] = solver_interface.initialise_solver( postproc) self.postprocessors[postproc].initialise( self.data, self.settings['postprocessors_settings'][postproc]) if self.print_info: self.residual_table = cout.TablePrinter(2, 14, ['g', 'f']) self.residual_table.print_header(['ts', 't'])
def initialise(self, data, input_dict=None): self.data = data if input_dict is None: self.settings = data.settings[self.solver_id] else: self.settings = input_dict settings.to_custom_types(self.settings, self.settings_types, self.settings_default, options=self.settings_options) self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data # load info from dyn dictionary self.data.structure.add_unsteady_information( self.data.structure.dyn_dict, 1) # Define the function to correct aerodynamic forces if self.settings['correct_forces_method'] is not '': self.correct_forces = True self.correct_forces_function = cf.dict_of_corrections[ self.settings['correct_forces_method']]
def initialise(self, data): self.data = data self.settings = data.settings[self.solver_id] settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data
def run(self): config = configobj.ConfigObj() file_name = self.folder + '/' + self.data.settings['SHARPy']['case'] + '.pmor.sharpy' config.filename = file_name config['parameters'] = dict() for k, v in self.settings['parameters'].items(): cout.cout_wrap('\tWriting parameter %s: %s' % (k, str(v)), 1) config['parameters'][k] = v sim_info = dict() sim_info['case'] = self.data.settings['SHARPy']['case'] if 'PickleData' not in self.data.settings['SHARPy']['flow'] and self.settings['save_case']: self.data.settings['PickleData'] = {'folder': self.settings['folder']} pickle_solver = initialise_solver('PickleData') pickle_solver.initialise(self.data) self.data = pickle_solver.run() sim_info['path_to_data'] = os.path.abspath(self.settings['folder']) else: sim_info['path_to_data'] = os.path.abspath(self.settings['folder']) config['sim_info'] = sim_info config.write() return self.data
def initialise(self, data, custom_settings=None): self.data = data if custom_settings: self.settings = custom_settings else: self.settings = data.settings[self.solver_id] settings.to_custom_types(self.settings, self.settings_types, self.settings_default) # Read initial state and input data and store in dictionary self.read_files() # Output folder self.folder = self.settings['folder'] + '/' + self.data.settings[ 'SHARPy']['case'] + '/lindynamicsim/' if not os.path.exists(self.folder): os.makedirs(self.folder) # initialise postprocessors self.postprocessors = dict() if len(self.settings['postprocessors']) > 0: self.with_postprocessors = True for postproc in self.settings['postprocessors']: self.postprocessors[postproc] = initialise_solver(postproc) self.postprocessors[postproc].initialise( self.data, self.settings['postprocessors_settings'][postproc])
def main(args): import time import sharpy.utils.input_arg as input_arg import sharpy.utils.solver_interface as solver_interface from sharpy.presharpy.presharpy import PreSharpy from sharpy.utils.cout_utils import start_writer, finish_writer # Loading solvers and postprocessors import sharpy.solvers import sharpy.postproc import sharpy.generators # ------------ # output writer start_writer() # timing t = time.process_time() settings = input_arg.read_settings(args) # Loop for the solvers specified in *.solver.txt['SHARPy']['flow'] # run preSHARPy data = PreSharpy(settings) for solver_name in settings['SHARPy']['flow']: solver = solver_interface.initialise_solver(solver_name) solver.initialise(data) data = solver.run() elapsed_time = time.process_time() - t cout.cout_wrap('FINISHED - Elapsed time = %f6 seconds' % elapsed_time, 2) finish_writer()
def initialise(self, data, custom_settings=None): self.data = data if custom_settings is None: self.settings = data.settings[self.solver_id] else: self.settings = custom_settings settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.dt = self.settings['dt'] self.print_info = self.settings['print_info'] if self.settings['cleanup_previous_solution']: # if there's data in timestep_info[>0], copy the last one to # timestep_info[0] and remove the rest self.cleanup_timestep_info() self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data if self.print_info: self.residual_table = cout.TablePrinter( 7, 14, ['g', 'f', 'g', 'f', 'f', 'f', 'e']) self.residual_table.field_length[0] = 6 self.residual_table.field_length[1] = 6 self.residual_table.field_length[1] = 6 self.residual_table.print_header([ 'ts', 't', 'iter', 'residual pos', 'residual vel', 'residual acc', 'FoR_vel(z)' ]) # initialise postprocessors self.postprocessors = dict() if len(self.settings['postprocessors']) > 0: self.with_postprocessors = True for postproc in self.settings['postprocessors']: self.postprocessors[postproc] = solver_interface.initialise_solver( postproc) self.postprocessors[postproc].initialise( self.data, self.settings['postprocessors_settings'][postproc])
def initialise(self, data, input_dict=None): self.data = data if input_dict is None: self.settings = data.settings[self.solver_id] else: self.settings = input_dict settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data
def initialise(self, data): self.data = data self.settings = data.settings[self.solver_id] settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.solver = solver_interface.initialise_solver(self.settings['solver']) self.solver.initialise(self.data, self.settings['solver_settings']) self.table = cout.TablePrinter(10, 8, ['g', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f']) self.table.print_header(['iter', 'alpha', 'elev', 'thrust', 'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'])
def initialise(self, data): self.data = data self.settings = data.settings[self.solver_id] settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.dt = self.settings['dt'].value self.solver = solver_interface.initialise_solver( self.settings['trajectory_solver']) self.settings['trajectory_solver_settings']['n_time_steps'] = 1 self.solver.initialise(self.data, self.settings['trajectory_solver_settings']) self.n_controlled_points = len(self.settings['nodes_trajectory']) # initialized controllers for the trayectory nodes # there will be 3 controllers per node (one per dimension) for i_trajec in range(self.n_controlled_points): self.controllers.append(list()) for i_dim in range(3): self.controllers[i_trajec].append( PID(self.settings['PID_P_gain'].value, self.settings['PID_I_gain'].value, self.settings['PID_D_gain'].value, self.dt)) self.trajectory = np.zeros((self.settings['n_time_steps'].value, len(self.settings['nodes_trajectory']), 3)) self.input_trajectory = np.zeros( (self.settings['n_time_steps'].value, len(self.settings['nodes_trajectory']), 3)) self.force_history = np.zeros( (self.settings['n_time_steps'].value, len(self.settings['nodes_trajectory']), 3)) # initialise trayectory generator trajectory_generator_type = gen_interface.generator_from_string( self.settings['trajectory_generator']) self.trajectory_generator = trajectory_generator_type() self.trajectory_generator.initialise( self.settings['trajectory_generator_input']) self.trajectory_steps = self.trajectory_generator.get_n_steps() # generate coordinates offset in order to be able to use only one # generator self.ini_coord_a = self.data.structure.ini_info.glob_pos( include_rbm=False) self.print_info = self.settings['print_info'] if self.print_info: self.residual_table = cout.TablePrinter(4, 14, ['g', 'f', 'f', 'e']) self.residual_table.field_length[0] = 6 self.residual_table.field_length[1] = 6 self.residual_table.field_length[1] = 6 self.residual_table.print_header( ['ts', 't', 'traj. offset', 'norm(force)'])
def __init__(self, pklFile): # Find location of X-Plane self.BeaconData = self.find_ip_xplane() self._byte_ordering = '<' _host, _port = self.find_local_ip() settings = dict() settings['UDPout'] = { 'output_network_settings': { 'destination_address': [self.BeaconData['IP']], 'destination_ports': [self.BeaconData['Port']], 'address': _host, 'port': _port, }, 'variables_filename': os.getcwd() + '/variables.yaml', } self.timestep_counter = 0 self.data = pklFile self.udpSolver = solver_interface.initialise_solver('UDPout') self.udpSolver.initialise(data, custom_settings=settings['UDPout']) # Longitude and Latitude of LHR (arbitrarily set) self.locLat = 51.470020 # 0 self.locLon = -0.454295 # 0 self.prevX = 0 self.prevY = 0 self.drefPaths = {} self.drefPaths['overrideCS'] = "sim/operation/override/override_control_surfaces" ### Ailerons ### self.drefPaths['leftAileronDef'] = "sim/flightmodel/controls/wing1l_ail1def" self.drefPaths['rightAileronDef'] = "sim/flightmodel/controls/wing1r_ail1def" ### Stabilisers ### self.drefPaths['elevatorDef'] = "sim/flightmodel/controls/hstab1_elv1def" self.drefPaths['rudderDef'] = "sim/flightmodel/controls/vstab1_rud1def" # Cockpit Panel Indicator # Dref for: The indicated pitch on the panel for the first vacuum instrument self.drefPaths['vertIndicator'] = "sim/cockpit/gyros/the_vac_ind_deg" # Dref for: The indicated roll on the panel for the first vacuum instrument self.drefPaths['horzIndicator'] = "sim/cockpit/gyros/phi_vac_ind_deg" # The flightmodel2 section contains data about how the actual aircraft is being drawn # Actual sweep in ratio (0=> no sweep, 1 => max sweep) [float, ratio] self.drefPaths['variableSweep'] = "sim/flightmodel2/controls/wingsweep_ratio" # Acutal dihedral [float, ratio] self.drefPaths['variableDihedral'] = "sim/flightmodel2/controls/dihedral_ratio" # Actual incidence [float, ratio] self.drefPaths['variableIncidence'] = "sim/flightmodel2/controls/incidence_ratio"
def process_controller_output(self, controlled_state): """ This function modified the solver properties and parameters as requested from the controller. This keeps the main loop much cleaner, while allowing for flexibility Please, if you add options in here, always code the possibility of that specific option not being there without the code complaining to the user. If it possible, use the same Key for the new setting as for the setting in the solver. For example, if you want to modify the `structural_substeps` variable in settings, use that Key in the `info` dictionary. As a convention: a value of None returns the value to the initial one specified in settings, while the key not being in the dict is ignored, so if any change was made before, it will stay there. """ try: info = controlled_state['info'] except KeyError: return controlled_state['structural'], controlled_state['aero'] # general copy-if-exists, restore if == None for info_k, info_v in info.items(): if info_k in self.settings: if info_v is not None: self.settings[info_k] = info_v else: self.settings[info_k] = self.original_settings[info_k] # specifics of every option for info_k, info_v in info.items(): if info_k in self.settings: if info_k == 'structural_substeps': if info_v is not None: self.substep_dt = ( self.settings['dt'].value / (self.settings['structural_substeps'].value + 1)) if info_k == 'structural_solver': if info_v is not None: self.structural_solver = solver_interface.initialise_solver( info['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) return controlled_state['structural'], controlled_state['aero']
def initialise(self, data, input_dict=None): self.data = data if input_dict is None: self.settings = data.settings[self.solver_id] else: self.settings = input_dict settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data # load info from dyn dictionary self.data.structure.add_unsteady_information( self.data.structure.dyn_dict, 1)
def initialise(self, data, input_dict=None): self.data = data if input_dict is None: self.settings = data.settings[self.solver_id] else: self.settings = input_dict settings.to_custom_types(self.settings, self.settings_types, self.settings_default, options=self.settings_options) self.print_info = self.settings['print_info'] self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data if self.print_info: self.residual_table = cout.TablePrinter( 9, 8, ['g', 'g', 'f', 'f', 'f', 'f', 'f', 'f', 'f']) self.residual_table.field_length[0] = 3 self.residual_table.field_length[1] = 3 self.residual_table.field_length[2] = 10 self.residual_table.print_header([ 'iter', 'step', 'log10(res)', 'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz' ]) # Define the function to correct aerodynamic forces if self.settings['correct_forces_method'] is not '': self.correct_forces = True self.correct_forces_function = cf.dict_of_corrections[ self.settings['correct_forces_method']]
def main(args): """ Main ``SHARPy`` routine This is the main ``SHARPy`` routine. It starts the solution process by reading the settings that are included in the ``.solver.txt`` file that is parsed as an argument. It reads the solvers specific settings and runs them in order Args: args (str): ``.solver.txt`` file with the problem information and settings Returns: ``PreSharpy`` class object """ import time import sharpy.utils.input_arg as input_arg import sharpy.utils.solver_interface as solver_interface from sharpy.presharpy.presharpy import PreSharpy from sharpy.utils.cout_utils import start_writer, finish_writer # Loading solvers and postprocessors import sharpy.solvers import sharpy.postproc import sharpy.generators # ------------ # output writer start_writer() # timing t = time.process_time() settings = input_arg.read_settings(args) # Loop for the solvers specified in *.solver.txt['SHARPy']['flow'] # run preSHARPy data = PreSharpy(settings) for solver_name in settings['SHARPy']['flow']: solver = solver_interface.initialise_solver(solver_name) solver.initialise(data) data = solver.run() elapsed_time = time.process_time() - t cout.cout_wrap('FINISHED - Elapsed time = %f6 seconds' % elapsed_time, 2) finish_writer() return data
def initialise(self, data): self.data = data self.settings = data.settings[self.solver_id] settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.solver = solver_interface.initialise_solver( self.settings['solver']) self.solver.initialise(self.data, self.settings['solver_settings']) folder = self.settings['folder'] + '/' + self.data.settings['SHARPy'][ 'case'] + '/statictrim/' if not os.path.exists(folder): os.makedirs(folder) self.table = cout.TablePrinter( 10, 8, ['g', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f'], filename=folder + 'trim_iterations.txt') self.table.print_header([ 'iter', 'alpha[deg]', 'elev[deg]', 'thrust', 'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz' ])
def initialise(self, data, custom_settings=None): """ Controls the initialisation process of the solver, including processing the settings and initialising the aero and structural solvers, postprocessors and controllers. """ self.data = data if custom_settings is None: self.settings = data.settings[self.solver_id] else: self.settings = custom_settings settings.to_custom_types(self.settings, self.settings_types, self.settings_default, options=self.settings_options) self.original_settings = copy.deepcopy(self.settings) self.dt = self.settings['dt'] self.substep_dt = (self.dt.value / (self.settings['structural_substeps'].value + 1)) self.initial_n_substeps = self.settings['structural_substeps'].value self.print_info = self.settings['print_info'] if self.settings['cleanup_previous_solution']: # if there's data in timestep_info[>0], copy the last one to # timestep_info[0] and remove the rest self.cleanup_timestep_info() self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data # initialise postprocessors self.postprocessors = dict() if self.settings['postprocessors']: self.with_postprocessors = True for postproc in self.settings['postprocessors']: self.postprocessors[postproc] = solver_interface.initialise_solver( postproc) self.postprocessors[postproc].initialise( self.data, self.settings['postprocessors_settings'][postproc], caller=self) # initialise controllers self.controllers = dict() self.with_controllers = False if self.settings['controller_id']: self.with_controllers = True for controller_id, controller_type in self.settings[ 'controller_id'].items(): self.controllers[controller_id] = ( controller_interface.initialise_controller(controller_type)) self.controllers[controller_id].initialise( self.settings['controller_settings'][controller_id], controller_id) # print information header if self.print_info: self.residual_table = cout.TablePrinter( 8, 12, ['g', 'f', 'g', 'f', 'f', 'f', 'e', 'e']) self.residual_table.field_length[0] = 5 self.residual_table.field_length[1] = 6 self.residual_table.field_length[2] = 4 self.residual_table.print_header([ 'ts', 't', 'iter', 'struc ratio', 'iter time', 'residual vel', 'FoR_vel(x)', 'FoR_vel(z)' ]) # Define the function to correct aerodynamic forces if self.settings['correct_forces_method'] is not '': self.correct_forces = True self.correct_forces_function = cf.dict_of_corrections[ self.settings['correct_forces_method']] # check for empty dictionary if self.settings['network_settings']: self.network_loader = network_interface.NetworkLoader() self.network_loader.initialise( in_settings=self.settings['network_settings']) # initialise runtime generators self.runtime_generators = dict() if self.settings['runtime_generators']: self.with_runtime_generators = True for id, param in self.settings['runtime_generators'].items(): gen = gen_interface.generator_from_string(id) self.runtime_generators[id] = gen() self.runtime_generators[id].initialise(param, data=self.data)
def initialise(self, data, custom_settings=None): """ Controls the initialisation process of the solver, including processing the settings and initialising the aero and structural solvers, postprocessors and controllers. """ self.data = data if custom_settings is None: self.settings = data.settings[self.solver_id] else: self.settings = custom_settings settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.original_settings = copy.deepcopy(self.settings) self.dt = self.settings['dt'] self.substep_dt = (self.dt.value / (self.settings['structural_substeps'].value + 1)) self.initial_n_substeps = self.settings['structural_substeps'].value self.print_info = self.settings['print_info'] if self.settings['cleanup_previous_solution']: # if there's data in timestep_info[>0], copy the last one to # timestep_info[0] and remove the rest self.cleanup_timestep_info() self.structural_solver = solver_interface.initialise_solver( self.settings['structural_solver']) self.structural_solver.initialise( self.data, self.settings['structural_solver_settings']) self.aero_solver = solver_interface.initialise_solver( self.settings['aero_solver']) self.aero_solver.initialise(self.structural_solver.data, self.settings['aero_solver_settings']) self.data = self.aero_solver.data # initialise postprocessors self.postprocessors = dict() if self.settings['postprocessors']: self.with_postprocessors = True for postproc in self.settings['postprocessors']: self.postprocessors[postproc] = solver_interface.initialise_solver( postproc) self.postprocessors[postproc].initialise( self.data, self.settings['postprocessors_settings'][postproc]) # initialise controllers self.controllers = dict() self.with_controllers = False if self.settings['controller_id']: self.with_controllers = True for controller_id, controller_type in self.settings[ 'controller_id'].items(): self.controllers[controller_id] = ( controller_interface.initialise_controller(controller_type)) self.controllers[controller_id].initialise( self.settings['controller_settings'][controller_id], controller_id) # print information header if self.print_info: self.residual_table = cout.TablePrinter( 8, 12, ['g', 'f', 'g', 'f', 'f', 'f', 'e', 'e']) self.residual_table.field_length[0] = 5 self.residual_table.field_length[1] = 6 self.residual_table.field_length[2] = 4 self.residual_table.print_header([ 'ts', 't', 'iter', 'struc ratio', 'iter time', 'residual vel', 'FoR_vel(x)', 'FoR_vel(z)' ])
def initialise(self, data): self.data = data self.settings = data.settings[self.solver_id] settings.to_custom_types(self.settings, self.settings_types, self.settings_default) self.solver = solver_interface.initialise_solver( self.settings['solver']) self.solver.initialise(self.data, self.settings['solver_settings']) # generate x_info (which elements of the x array are what) counter = 0 self.x_info['n_variables'] = 0 # alpha self.x_info['i_alpha'] = counter counter += 1 # beta self.x_info['i_beta'] = counter counter += 1 # roll self.x_info['i_roll'] = counter counter += 1 # control surfaces n_control_surfaces = len(self.settings['cs_indices']) self.x_info['i_control_surfaces'] = [] # indices in the state vector self.x_info['control_surfaces_id'] = [ ] # indices of the trimmed control surfaces for i_cs in range(n_control_surfaces): self.x_info['i_control_surfaces'].append(counter) self.x_info['control_surfaces_id'].append( self.settings['cs_indices'][i_cs]) counter += 1 # thrust n_thrust_nodes = len(self.settings['thrust_nodes']) self.x_info['i_thrust'] = [] self.x_info['thrust_nodes'] = [] self.x_info['thrust_direction'] = [] for i_thrust in range(n_thrust_nodes): self.x_info['i_thrust'].append(counter) self.x_info['thrust_nodes'].append( self.settings['thrust_nodes'][i_thrust]) self.x_info['thrust_direction'].append( self.settings['thrust_direction']) counter += 1 self.x_info['n_variables'] = counter # special cases self.with_special_case = self.settings['special_case'] if self.with_special_case: if self.settings['special_case'][ 'case_name'] == 'differential_thrust': self.x_info['special_case'] = 'differential_thrust' self.x_info['i_base_thrust'] = counter counter += 1 self.x_info['i_differential_parameter'] = counter counter += 1 self.x_info['initial_base_thrust'] = self.settings[ 'special_case']['initial_base_thrust'] self.x_info['initial_differential_parameter'] = self.settings[ 'special_case']['initial_differential_parameter'] self.x_info['base_thrust_nodes'] = [ int(e) for e in self.settings['special_case']['base_thrust_nodes'] ] self.x_info['negative_thrust_nodes'] = [ int(e) for e in self.settings['special_case'] ['negative_thrust_nodes'] ] self.x_info['positive_thrust_nodes'] = [ int(e) for e in self.settings['special_case'] ['positive_thrust_nodes'] ] self.x_info['n_variables'] = counter # initial state vector self.initial_state = np.zeros(self.x_info['n_variables']) self.initial_state[ self.x_info['i_alpha']] = self.settings['initial_alpha'].value self.initial_state[ self.x_info['i_beta']] = self.settings['initial_beta'].value self.initial_state[ self.x_info['i_roll']] = self.settings['initial_roll'].value for i_cs in range(n_control_surfaces): self.initial_state[self.x_info['i_control_surfaces'][ i_cs]] = self.settings['initial_cs_deflection'][i_cs] for i_thrust in range(n_thrust_nodes): self.initial_state[self.x_info['i_thrust'][ i_thrust]] = self.settings['initial_thrust'][i_thrust] if self.with_special_case: if self.settings['special_case'][ 'case_name'] == 'differential_thrust': self.initial_state[self.x_info['i_base_thrust']] = self.x_info[ 'initial_base_thrust'] self.initial_state[ self.x_info['i_differential_parameter']] = self.x_info[ 'initial_differential_parameter'] # bounds # NOTE probably not necessary anymore, as Nelder-Mead method doesn't use them self.bounds = self.x_info['n_variables'] * [None] for k, v in self.x_info.items(): if k == 'i_alpha': self.bounds[v] = (self.initial_state[self.x_info['i_alpha']] - 3 * np.pi / 180, self.initial_state[self.x_info['i_alpha']] + 3 * np.pi / 180) elif k == 'i_beta': self.bounds[v] = (self.initial_state[self.x_info['i_beta']] - 2 * np.pi / 180, self.initial_state[self.x_info['i_beta']] + 2 * np.pi / 180) elif k == 'i_roll': self.bounds[v] = (self.initial_state[self.x_info['i_roll']] - 2 * np.pi / 180, self.initial_state[self.x_info['i_roll']] + 2 * np.pi / 180) elif k == 'i_thrust': for ii, i in enumerate(v): self.bounds[i] = ( self.initial_state[self.x_info['i_thrust'][ii]] - 2, self.initial_state[self.x_info['i_thrust'][ii]] + 2) elif k == 'i_control_surfaces': for ii, i in enumerate(v): self.bounds[i] = ( self.initial_state[self.x_info['i_control_surfaces'] [ii]] - 4 * np.pi / 180, self.initial_state[self.x_info['i_control_surfaces'] [ii]] + 4 * np.pi / 180) elif k == 'i_base_thrust': if self.with_special_case: if self.settings['special_case'][ 'case_name'] == 'differential_thrust': self.bounds[v] = ( float(self.x_info['initial_base_thrust']) * 0.5, float(self.x_info['initial_base_thrust']) * 1.5) elif k == 'i_differential_parameter': if self.with_special_case: if self.settings['special_case'][ 'case_name'] == 'differential_thrust': self.bounds[v] = (-0.5, 0.5)
def main(args=None, sharpy_input_dict=None): """ Main ``SHARPy`` routine This is the main ``SHARPy`` routine. It starts the solution process by reading the settings that are included in the ``.sharpy`` file that is parsed as an argument, or an equivalent dictionary given as ``sharpy_input_dict``. It reads the solvers specific settings and runs them in order Args: args (str): ``.sharpy`` file with the problem information and settings sharpy_input_dict (dict): ``dict`` with the same contents as the ``solver.txt`` file would have. Returns: sharpy.presharpy.presharpy.PreSharpy: object containing the simulation results. """ import time import argparse import sharpy.utils.input_arg as input_arg import sharpy.utils.solver_interface as solver_interface from sharpy.presharpy.presharpy import PreSharpy from sharpy.utils.cout_utils import start_writer, finish_writer import logging import os import h5py import sharpy.utils.h5utils as h5utils # Loading solvers and postprocessors import sharpy.solvers import sharpy.postproc import sharpy.generators import sharpy.controllers # ------------ try: # output writer start_writer() # timing t = time.process_time() t0_wall = time.perf_counter() if sharpy_input_dict is None: parser = argparse.ArgumentParser(prog='SHARPy', description= """This is the executable for Simulation of High Aspect Ratio Planes.\n Imperial College London 2020""") parser.add_argument('input_filename', help='path to the *.sharpy input file', type=str, default='') parser.add_argument('-r', '--restart', help='restart the solution with a given snapshot', type=str, default=None) parser.add_argument('-d', '--docs', help='generates the solver documentation in the specified location. ' 'Code does not execute if running this flag', action='store_true') if args is not None: args = parser.parse_args(args[1:]) else: args = parser.parse_args() if args.docs: import subprocess import sharpy.utils.docutils as docutils import sharpy.utils.sharpydir as sharpydir docutils.generate_documentation() # run make cout.cout_wrap('Running make html in sharpy/docs') subprocess.Popen(['make', 'html'], stdout=None, cwd=sharpydir.SharpyDir + '/docs') return 0 if args.input_filename == '': parser.error('input_filename is a required argument of SHARPy.') settings = input_arg.read_settings(args) if args.restart is None: # run preSHARPy data = PreSharpy(settings) else: try: with open(args.restart, 'rb') as restart_file: data = pickle.load(restart_file) except FileNotFoundError: raise FileNotFoundError('The file specified for the snapshot \ restart (-r) does not exist. Please check.') # update the settings data.update_settings(settings) # Read again the dyn.h5 file data.structure.dynamic_input = [] dyn_file_name = data.case_route + '/' + data.case_name + '.dyn.h5' if os.path.isfile(dyn_file_name): fid = h5py.File(dyn_file_name, 'r') data.structure.dyn_dict = h5utils.load_h5_in_dict(fid) # for it in range(self.num_steps): # data.structure.dynamic_input.append(dict()) # Loop for the solvers specified in *.sharpy['SHARPy']['flow'] for solver_name in settings['SHARPy']['flow']: solver = solver_interface.initialise_solver(solver_name) solver.initialise(data) data = solver.run() cpu_time = time.process_time() - t wall_time = time.perf_counter() - t0_wall cout.cout_wrap('FINISHED - Elapsed time = %f6 seconds' % wall_time, 2) cout.cout_wrap('FINISHED - CPU process time = %f6 seconds' % cpu_time, 2) finish_writer() except Exception as e: try: logdir = settings['SHARPy']['log_folder'] except KeyError: logdir = './' except NameError: logdir = './' logdir = os.path.abspath(logdir) cout.cout_wrap(('Exception raised, writing error log in %s/error.log' % logdir), 4) logging.basicConfig(filename='%s/error.log' % logdir, filemode='w', format='%(asctime)s-%(levelname)s-%(message)s', datefmt='%d-%b-%y %H:%M:%S', level=logging.INFO) logging.info('SHARPy Error Log') logging.error("Exception occurred", exc_info=True) raise e return data
def main(args=None, sharpy_input_dict=None): """ Main ``SHARPy`` routine This is the main ``SHARPy`` routine. It starts the solution process by reading the settings that are included in the ``.solver.txt`` file that is parsed as an argument, or an equivalent dictionary given as ``sharpy_input_dict``. It reads the solvers specific settings and runs them in order Args: args (str): ``.solver.txt`` file with the problem information and settings sharpy_input_dict (dict): ``dict`` with the same contents as the ``solver.txt`` file would have. Returns: ``PreSharpy`` class object """ import time import argparse import sharpy.utils.input_arg as input_arg import sharpy.utils.solver_interface as solver_interface from sharpy.presharpy.presharpy import PreSharpy from sharpy.utils.cout_utils import start_writer, finish_writer # Loading solvers and postprocessors import sharpy.solvers import sharpy.postproc import sharpy.generators import sharpy.controllers # ------------ # output writer start_writer() # timing t = time.process_time() t0_wall = time.perf_counter() if sharpy_input_dict is None: parser = argparse.ArgumentParser(prog='SHARPy', description= """This is the executable for Simulation of High Aspect Ratio Planes.\n Imperial College London 2019""") parser.add_argument('input_filename', help='path to the *.solver.txt input file', type=str, default='') parser.add_argument('-r', '--restart', help='restart the solution with a given snapshot', type=str, default=None) parser.add_argument('-d', '--docs', help='generates the solver documentation in the specified location. Code does not execute if running this flag', action='store_true') if args is not None: args = parser.parse_args(args[1:]) else: args = parser.parse_args() if args.docs: import subprocess import sharpy.utils.docutils as docutils import sharpy.utils.sharpydir as sharpydir docutils.generate_documentation() # run make cout.cout_wrap('Running make html in sharpy/docs') subprocess.Popen(['make', 'html'], stdout=None, cwd=sharpydir.SharpyDir + '/docs') return 0 if args.input_filename == '': parser.error('input_filename is a required argument of sharpy.') settings = input_arg.read_settings(args) if args.restart is None: # run preSHARPy data = PreSharpy(settings) else: try: with open(args.restart, 'rb') as restart_file: data = pickle.load(restart_file) except FileNotFoundError: raise FileNotFoundError('The file specified for the snapshot \ restart (-r) does not exist. Please check.') # update the settings data.update_settings(settings) # else: # # Case for input from dictionary # settings = input_arg.read_settings(args) # # run preSHARPy # data = PreSharpy(settings) # Loop for the solvers specified in *.solver.txt['SHARPy']['flow'] for solver_name in settings['SHARPy']['flow']: solver = solver_interface.initialise_solver(solver_name) solver.initialise(data) data = solver.run() cpu_time = time.process_time() - t wall_time = time.perf_counter() - t0_wall cout.cout_wrap('FINISHED - Elapsed time = %f6 seconds' % wall_time, 2) cout.cout_wrap('FINISHED - CPU process time = %f6 seconds' % cpu_time, 2) finish_writer() return data
def plot_modes(self): """ Warnings: Under development Plot the aeroelastic mode shapes for the first ``n_modes_to_plot`` """ try: import matplotlib.pyplot as plt except ModuleNotFoundError: cout.cout_wrap( 'Could not plot in asymptoticstability beacuse there is no Matplotlib', 4) return mode_shape_list = self.settings['modes_to_plot'] for mode in mode_shape_list: # Scale mode aero_states = self.data.linear.linear_system.uvlm.ss.states displacement_states = self.data.linear.linear_system.beam.ss.states // 2 amplitude_factor = modalutils.scale_mode( self.data, self.eigenvectors[aero_states:aero_states + displacement_states - 9, mode], rot_max_deg=10, perc_max=0.1) fact_rbm = self.scale_rigid_body_mode( self.eigenvectors[:, mode], self.eigenvalues[mode].imag) * 100 print(fact_rbm) t, x = self.mode_time_domain(amplitude_factor, fact_rbm, mode) # Initialise postprocessors - new folder for each mode # initialise postprocessors route = self.settings['folder'] + '/stability/mode_%06d/' % mode postprocessors = dict() postprocessor_list = ['AerogridPlot', 'BeamPlot'] postprocessors_settings = dict() postprocessors_settings['AerogridPlot'] = { 'folder': route, 'include_rbm': 'on', 'include_applied_forces': 'on', 'minus_m_star': 0, 'u_inf': 1 } postprocessors_settings['BeamPlot'] = { 'folder': route + '/', 'include_rbm': 'on', 'include_applied_forces': 'on' } for postproc in postprocessor_list: postprocessors[postproc] = initialise_solver(postproc) postprocessors[postproc].initialise( self.data, postprocessors_settings[postproc]) # Plot reference for postproc in postprocessor_list: self.data = postprocessors[postproc].run(online=True) for n in range(t.shape[1]): aero_tstep, struct_tstep = lindynamicsim.state_to_timestep( self.data, x[:, n]) self.data.aero.timestep_info.append(aero_tstep) self.data.structure.timestep_info.append(struct_tstep) for postproc in postprocessor_list: self.data = postprocessors[postproc].run(online=True) # Delete 'modal' timesteps ready for next mode del self.data.structure.timestep_info[1:] del self.data.aero.timestep_info[1:]