Пример #1
0
    def initialise(self, data, custom_settings=None, caller=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.settings_options)

        self.dir = self.data.case_route + 'output/' + self.data.case_name + '/' + 'GenerateFlowField/'
        if not os.path.isdir(self.dir):
            os.makedirs(self.dir)

        # init velocity generator
        velocity_generator_type = gen_interface.generator_from_string(
            self.settings['velocity_field_generator'])
        self.velocity_generator = velocity_generator_type()
        self.velocity_generator.initialise(
            self.settings['velocity_field_input'])

        # init postproc grid generator
        postproc_grid_generator_type = gen_interface.generator_from_string(
            self.settings['postproc_grid_generator'])
        self.postproc_grid_generator = postproc_grid_generator_type()
        self.postproc_grid_generator.initialise(
            self.settings['postproc_grid_input'])
        self.caller = caller
Пример #2
0
    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)

        # update beam orientation
        # beam orientation is used as the parametrisation of the aero orientation
        # too (it will come handy for the fully coupled simulation)
        # euler = np.array([self.settings['roll'].value,
        #                   self.settings['alpha'].value,
        #                   self.settings['beta'].value])
        # euler_rot = algebra.euler2rot(euler)  # this is Cag
        # quat = algebra.mat2quat(euler_rot.T)
        # self.data.structure.update_orientation(quat, self.data.ts)
        # self.data.aero.update_orientation(quat, self.data.ts)
        self.update_step()

        # init velocity generator
        velocity_generator_type = gen_interface.generator_from_string(
            self.settings['velocity_field_generator'])
        self.velocity_generator = velocity_generator_type()
        self.velocity_generator.initialise(
            self.settings['velocity_field_input'])
Пример #3
0
    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)'])
Пример #4
0
    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.update_step()

        # init velocity generator
        velocity_generator_type = gen_interface.generator_from_string(
            self.settings['velocity_field_generator'])
        self.velocity_generator = velocity_generator_type()
        self.velocity_generator.initialise(self.settings['velocity_field_input'])
Пример #5
0
    def initialise(self, data):
        self.data = data
        self.settings = data.settings[self.solver_id]

        # init settings
        settings_utils.to_custom_types(self.settings, self.settings_types,
                                       self.settings_default)

        # read input file (aero)
        self.read_files()

        wake_shape_generator_type = gen_interface.generator_from_string(
            self.settings['wake_shape_generator'])
        self.wake_shape_generator = wake_shape_generator_type()
        self.wake_shape_generator.initialise(
            data, self.settings['wake_shape_generator_input'])
Пример #6
0
    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.data.structure.add_unsteady_information(
            self.data.structure.dyn_dict, self.settings['n_time_steps'].value)

        # init velocity generator
        velocity_generator_type = gen_interface.generator_from_string(
            self.settings['velocity_field_generator'])
        self.velocity_generator = velocity_generator_type()
        self.velocity_generator.initialise(
            self.settings['velocity_field_input'])
Пример #7
0
    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.data.structure.add_unsteady_information(self.data.structure.dyn_dict, self.settings['n_time_steps'].value)

        # init velocity generator
        velocity_generator_type = gen_interface.generator_from_string(
            self.settings['velocity_field_generator'])
        self.velocity_generator = velocity_generator_type()
        self.velocity_generator.initialise(self.settings['velocity_field_input'])

        # Checks
        if not self.settings['convection_scheme'].value == 2:
            sys.exit("ERROR: convection_scheme: %u. Only 2 supported" % self.settings['convection_scheme'].value)
Пример #8
0
    def initialise(self, data, custom_settings=None):
        """
        To be called just once per simulation.
        """
        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.settings_options)

        self.data.structure.add_unsteady_information(
            self.data.structure.dyn_dict,
            self.settings['n_time_steps'].value)

        # Filtering
        if self.settings['gamma_dot_filtering'].value == 1:
            cout.cout_wrap(
                "gamma_dot_filtering cannot be one. Changing it to None", 2)
            self.settings['gamma_dot_filtering'] = None
        if self.settings['gamma_dot_filtering'] is not None:
            if self.settings['gamma_dot_filtering'].value:
                if not self.settings['gamma_dot_filtering'].value % 2:
                    cout.cout_wrap(
                        "gamma_dot_filtering does not support even numbers." +
                        "Changing " +
                        str(self.settings['gamma_dot_filtering'].value) +
                        " to " +
                        str(self.settings['gamma_dot_filtering'].value + 1),
                        2)
                    self.settings['gamma_dot_filtering'] = (
                        ct.c_int(self.settings['gamma_dot_filtering'].value + 1))

        # init velocity generator
        velocity_generator_type = gen_interface.generator_from_string(
            self.settings['velocity_field_generator'])
        self.velocity_generator = velocity_generator_type()
        self.velocity_generator.initialise(
            self.settings['velocity_field_input'])
Пример #9
0
    def generate(self, aero_dict, beam, aero_settings, ts):
        self.aero_dict = aero_dict
        self.beam = beam
        self.aero_settings = aero_settings

        # number of total nodes (structural + aero&struc)
        self.n_node = len(aero_dict['aero_node'])
        # number of elements
        self.n_elem = len(aero_dict['surface_distribution'])
        # surface distribution
        self.surface_distribution = aero_dict['surface_distribution']
        # number of surfaces
        temp = set(aero_dict['surface_distribution'])
        self.n_surf = sum(1 for i in temp if i >= 0)
        # number of chordwise panels
        self.surface_m = aero_dict['surface_m']
        # number of aero nodes
        self.n_aero_node = sum(aero_dict['aero_node'])

        # get N per surface
        self.calculate_dimensions()

        # write grid info to screen
        self.output_info()

        # allocating initial grid storage
        self.ini_info = AeroTimeStepInfo(self.aero_dimensions,
                                         self.aero_dimensions_star)

        # load airfoils db
        # for i_node in range(self.n_node):
        for i_elem in range(self.n_elem):
            for i_local_node in range(self.beam.num_node_elem):
                try:
                    self.airfoil_db[self.aero_dict['airfoil_distribution'][
                        i_elem, i_local_node]]
                except KeyError:
                    airfoil_coords = self.aero_dict['airfoils'][str(
                        self.aero_dict['airfoil_distribution'][i_elem,
                                                               i_local_node])]
                    self.airfoil_db[self.aero_dict['airfoil_distribution'][
                        i_elem, i_local_node]] = (scipy.interpolate.interp1d(
                            airfoil_coords[:, 0],
                            airfoil_coords[:, 1],
                            kind='quadratic',
                            copy=False,
                            fill_value='extrapolate',
                            assume_sorted=True))
        try:
            self.n_control_surfaces = np.sum(
                np.unique(self.aero_dict['control_surface']) >= 0)
        except KeyError:
            pass

        # Backward compatibility: check whether control surface deflection settings have been specified. If not, create
        # section with empty list, such that no cs generator is appended
        try:
            aero_settings['control_surface_deflection']
        except KeyError:
            aero_settings.update(
                {'control_surface_deflection': [''] * self.n_control_surfaces})

        # pad ctrl surfaces dict with empty strings if not defined
        if len(aero_settings['control_surface_deflection']
               ) != self.n_control_surfaces:
            undef_ctrl_sfcs = [''] * (self.n_control_surfaces - len(
                aero_settings['control_surface_deflection']))
            aero_settings['control_surface_deflection'].extend(undef_ctrl_sfcs)

        # initialise generators
        for i_cs in range(self.n_control_surfaces):
            if aero_settings['control_surface_deflection'][i_cs] == '':
                self.cs_generators.append(None)
            else:
                generator_type = gen_interface.generator_from_string(
                    aero_settings['control_surface_deflection'][i_cs])
                self.cs_generators.append(generator_type())
                self.cs_generators[i_cs].initialise(aero_settings[
                    'control_surface_deflection_generator_settings'][i_cs])

        self.add_timestep()
        self.generate_mapping()
        self.generate_zeta(self.beam, self.aero_settings, ts)

        if 'polars' in aero_dict:
            import sharpy.aero.utils.airfoilpolars as ap
            self.polars = []
            nairfoils = np.amax(self.aero_dict['airfoil_distribution']) + 1
            for iairfoil in range(nairfoils):
                new_polar = ap.polar()
                new_polar.initialise(aero_dict['polars'][str(iairfoil)])
                self.polars.append(new_polar)
Пример #10
0
    def initialise(self, data, custom_settings=None):
        r"""
        Initialises the Linear UVLM aerodynamic solver and the chosen velocity generator.

        Settings are parsed into the standard SHARPy settings format for solvers. It then checks whether there is
        any previous information about the linearised system (in order for a solution to be restarted without
        overwriting the linearisation).

        If a linearised system does not exist, a linear UVLM system is created linearising about the current time step.

        The reference values for the input and output are transformed into column vectors :math:`\mathbf{u}`
        and :math:`\mathbf{y}`, respectively.

        The information pertaining to the linear system is stored in a dictionary ``self.data.aero.linear`` within
        the main ``data`` variable.

        Args:
            data (PreSharpy): class containing the problem information
            custom_settings (dict): custom settings dictionary

        """

        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,
                                 no_ctype=True)
        settings.to_custom_types(self.settings['ScalingDict'],
                                 self.scaling_settings_types,
                                 self.scaling_settings_default,
                                 no_ctype=True)

        # Check whether linear UVLM has been initialised
        try:
            self.data.aero.linear
        except AttributeError:
            self.data.aero.linear = dict()
            aero_tstep = self.data.aero.timestep_info[-1]

            ### Record body orientation/velocities at time 0
            # This option allows to rotate the linearised UVLM with the A frame
            # or a specific body (multi-body solution)
            if self.settings['track_body']:

                self.num_body_track = self.settings['track_body_number']

                # track A frame
                if self.num_body_track == -1:
                    self.quat0 = self.data.structure.timestep_info[
                        -1].quat.copy()
                    self.for_vel0 = self.data.structure.timestep_info[
                        -1].for_vel.copy()
                else:  # track a specific body
                    self.quat0 = \
                        self.data.structure.timestep_info[-1].mb_quat[self.num_body_track,:].copy()
                    self.for_vel0 = \
                        self.data.structure.timestep_info[-1].mb_FoR_vel[self.num_body_track ,:].copy()

                # convert to G frame
                self.Cga0 = algebra.quat2rotation(self.quat0)
                self.Cga = self.Cga0.copy()
                self.for_vel0[:3] = self.Cga0.dot(self.for_vel0[:3])
                self.for_vel0[3:] = self.Cga0.dot(self.for_vel0[3:])

            else:  # check/record initial rotation speed
                self.num_body_track = None
                self.quat0 = None
                self.Cag0 = None
                self.Cga = None
                self.for_vel0 = np.zeros((6, ))

            # TODO: verify of a better way to implement rho
            aero_tstep.rho = self.settings['density']

            # Generate instance of linuvlm.Dynamic()
            lin_uvlm_system = linuvlm.DynamicBlock(
                aero_tstep,
                dynamic_settings=self.settings,
                # dt=self.settings['dt'].value,
                # integr_order=self.settings['integr_order'].value,
                # ScalingDict=self.settings['ScalingDict'],
                # RemovePredictor=self.settings['remove_predictor'].value,
                # UseSparse=self.settings['use_sparse'].value,
                for_vel=self.for_vel0)

            # add rotational speed
            for ii in range(lin_uvlm_system.MS.n_surf):
                lin_uvlm_system.MS.Surfs[ii].omega = self.for_vel0[3:]

            # Save reference values
            # System Inputs
            u_0 = self.pack_input_vector()

            # Linearised state
            dt = self.settings['dt']
            x_0 = self.pack_state_vector(aero_tstep, None, dt,
                                         self.settings['integr_order'])

            # Reference forces
            f_0 = np.concatenate([
                aero_tstep.forces[ss][0:3].reshape(-1, order='C')
                for ss in range(aero_tstep.n_surf)
            ])

            # Assemble the state space system
            lin_uvlm_system.assemble_ss()
            self.data.aero.linear['System'] = lin_uvlm_system
            self.data.aero.linear['SS'] = lin_uvlm_system.SS
            self.data.aero.linear['x_0'] = x_0
            self.data.aero.linear['u_0'] = u_0
            self.data.aero.linear['y_0'] = f_0
            # self.data.aero.linear['gamma_0'] = gamma
            # self.data.aero.linear['gamma_star_0'] = gamma_star
            # self.data.aero.linear['gamma_dot_0'] = gamma_dot

            # TODO: Implement in AeroTimeStepInfo a way to store the state vectors
            # aero_tstep.linear.x = x_0
            # aero_tstep.linear.u = u_0
            # aero_tstep.linear.y = f_0

        # Initialise velocity generator
        velocity_generator_type = gen_interface.generator_from_string(
            self.settings['velocity_field_generator'])
        self.velocity_generator = velocity_generator_type()
        self.velocity_generator.initialise(
            self.settings['velocity_field_input'])
Пример #11
0
    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)