Ejemplo n.º 1
0
    def get_body(self, ibody):
        """
        get_body

        Extract the body number 'ibody' from a multibody system

        Given 'self' as a Beam class of a multibody system, this
        function returns another Beam class (ibody_beam)
        that only includes the body number 'ibody' of the original system

        Args:
            self(Beam): structural information of the multibody system
            ibody(int): body number to be extracted

        Returns:
        	ibody_beam(Beam): structural information of the isolated body

        Examples:

        Notes:

        """

        ibody_beam = Beam()

        # Define the nodes and elements belonging to the body
        ibody_beam.global_elems_num, ibody_beam.global_nodes_num = mb.get_elems_nodes_list(self, ibody)

        # Renaming for clarity
        ibody_elements = ibody_beam.global_elems_num
        ibody_nodes = ibody_beam.global_nodes_num

        # Assign all the properties to the new StructTimeStepInfo
        ibody_beam.settings = self.settings.copy()

        ibody_beam.num_node_elem = self.num_node_elem.astype(dtype=ct.c_int, order='F', copy=True)
        ibody_beam.num_node = len(ibody_beam.global_nodes_num)
        ibody_beam.num_elem = len(ibody_beam.global_elems_num)

        ibody_beam.connectivities = self.connectivities[ibody_elements,:]
        # Renumber the connectivities
        int_list_nodes = np.arange(0, ibody_beam.num_node, 1)
        for ielem in range(ibody_beam.num_elem):
            for inode_in_elem in range(ibody_beam.num_node_elem):
                ibody_beam.connectivities[ielem, inode_in_elem] = int_list_nodes[ibody_nodes == ibody_beam.connectivities[ielem, inode_in_elem]]

        # TODO: I could copy only the needed stiffness and masses to save storage
        ibody_beam.elem_stiffness = self.elem_stiffness[ibody_elements].astype(dtype=ct.c_int, order='F', copy=True)
        ibody_beam.stiffness_db = self.stiffness_db.astype(dtype=ct.c_double, order='F', copy=True)
        ibody_beam.inv_stiffness_db = self.inv_stiffness_db.astype(dtype=ct.c_double, order='F', copy=True)
        ibody_beam.n_stiff = self.n_stiff

        ibody_beam.elem_mass = self.elem_mass[ibody_elements].astype(dtype=ct.c_int, order='F', copy=True)
        ibody_beam.mass_db = self.mass_db.astype(dtype=ct.c_double, order='F', copy=True)
        ibody_beam.n_mass = self.n_mass

        ibody_beam.frame_of_reference_delta = self.frame_of_reference_delta[ibody_elements,:,:].astype(dtype=ct.c_double, order='F', copy=True)
        ibody_beam.structural_twist = self.structural_twist[ibody_elements, :].astype(dtype=ct.c_double, order='F', copy=True)
        ibody_beam.boundary_conditions = self.boundary_conditions[ibody_nodes].astype(dtype=ct.c_int, order='F', copy=True)
        ibody_beam.beam_number = self.beam_number[ibody_elements].astype(dtype=ct.c_int, order='F', copy=True)

        if not self.lumped_mass_nodes is None:
            is_first = True
            ibody_beam.n_lumped_mass = 0
            for inode in range(len(self.lumped_mass_nodes)):
                if self.lumped_mass_nodes[inode] in ibody_nodes:
                    if is_first:
                        is_first = False
                        ibody_beam.lumped_mass_nodes = int_list_nodes[ibody_nodes == self.lumped_mass_nodes[inode]]
                        ibody_beam.lumped_mass = np.array([self.lumped_mass[inode]])
                        ibody_beam.lumped_mass_inertia = np.array([self.lumped_mass_inertia[inode]])
                        ibody_beam.lumped_mass_position = np.array([self.lumped_mass_position[inode]])
                        ibody_beam.n_lumped_mass += 1
                    else:
                        ibody_beam.lumped_mass_nodes = np.concatenate((ibody_beam.lumped_mass_nodes ,int_list_nodes[ibody_nodes == self.lumped_mass_nodes[inode]]), axis=0)
                        ibody_beam.lumped_mass = np.concatenate((ibody_beam.lumped_mass ,np.array([self.lumped_mass[inode]])), axis=0)
                        ibody_beam.lumped_mass_inertia = np.concatenate((ibody_beam.lumped_mass_inertia ,np.array([self.lumped_mass_inertia[inode]])), axis=0)
                        ibody_beam.lumped_mass_position = np.concatenate((ibody_beam.lumped_mass_position ,np.array([self.lumped_mass_position[inode]])), axis=0)
                        ibody_beam.n_lumped_mass += 1

        ibody_beam.steady_app_forces = self.steady_app_forces[ibody_nodes,:].astype(dtype=ct.c_double, order='F', copy=True)

        ibody_beam.num_bodies = 1

        ibody_beam.body_number = self.body_number[ibody_elements].astype(dtype=ct.c_int, order='F', copy=True)

        ibody_beam.generate_dof_arrays()

        ibody_beam.ini_info = self.ini_info.get_body(self, ibody_beam.num_dof, ibody)
        ibody_beam.timestep_info = self.timestep_info[-1].get_body(self, ibody_beam.num_dof, ibody)

        # generate the Element array
        for ielem in range(ibody_beam.num_elem):
            ibody_beam.elements.append(
                beamstructures.Element(
                    ielem,
                    ibody_beam.num_node_elem,
                    ibody_beam.connectivities[ielem, :],
                    ibody_beam.ini_info.pos[ibody_beam.connectivities[ielem, :], :],
                    ibody_beam.frame_of_reference_delta[ielem, :, :],
                    ibody_beam.structural_twist[ielem, :],
                    ibody_beam.beam_number[ielem],
                    ibody_beam.elem_stiffness[ielem],
                    ibody_beam.elem_mass[ielem]))
        # now we need to add the attributes like mass and stiffness index
        for ielem in range(ibody_beam.num_elem):
            dictionary = dict()
            dictionary['stiffness_index'] = ibody_beam.elem_stiffness[ielem]
            dictionary['mass_index'] = ibody_beam.elem_mass[ielem]
            ibody_beam.elements[ielem].add_attributes(dictionary)

        ibody_beam.generate_master_structure()

        if ibody_beam.lumped_mass is not None:
            ibody_beam.lump_masses()

        ibody_beam.generate_fortran()

        return ibody_beam
Ejemplo n.º 2
0
    def generate(self, in_data, settings):
        self.settings = settings
        # read and store data
        # type of node
        self.num_node_elem = in_data['num_node_elem']
        # node info
        self.num_node = in_data['num_node']
        self.num_elem = in_data['num_elem']
        # Body number
        try:
            self.body_number = in_data['body_number'].copy()
            self.num_bodies = np.max(self.body_number) + 1
        except KeyError:
            self.body_number = np.zeros((self.num_elem, ), dtype=int)
            self.num_bodies = 1

        # boundary conditions
        self.boundary_conditions = in_data['boundary_conditions'].copy()
        self.generate_dof_arrays()

        # ini info
        self.ini_info = StructTimeStepInfo(self.num_node, self.num_elem, self.num_node_elem, num_dof = self.num_dof, num_bodies = self.num_bodies)

        # mutibody: FoR information
        try:
            for ibody in range(self.num_bodies):
                self.ini_info.mb_FoR_pos[ibody,:] = self.ini_mb_dict["body_%02d" % ibody]["FoR_position"].copy()
                self.ini_info.mb_FoR_vel[ibody,:] = self.ini_mb_dict["body_%02d" % ibody]["FoR_velocity"].copy()
                self.ini_info.mb_FoR_acc[ibody,:] = self.ini_mb_dict["body_%02d" % ibody]["FoR_acceleration"].copy()
                self.ini_info.mb_quat[ibody,:] = self.ini_mb_dict["body_%02d" % ibody]["quat"].copy()
                self.ini_info.mb_dict = copy.deepcopy(self.ini_mb_dict)
        except KeyError:
            self.ini_info.mb_FoR_pos[0,:] = self.ini_info.for_pos
            self.ini_info.mb_FoR_vel[0,:] = self.ini_info.for_vel
            self.ini_info.mb_FoR_acc[0,:] = self.ini_info.for_acc
            self.ini_info.mb_quat[0,:] = self.ini_info.quat

        # attention, it has to be copied, not only referenced
        self.ini_info.pos = in_data['coordinates'].astype(dtype=ct.c_double, order='F')

        # connectivity information
        self.connectivities = in_data['connectivities'].astype(dtype=ct.c_int, order='F')

        self.global_nodes_num = list(set(self.connectivities.reshape(-1)))
        self.global_elems_num = np.arange(0, self.num_elem, 1)

        # stiffness data
        self.elem_stiffness = in_data['elem_stiffness'].copy()
        self.stiffness_db = in_data['stiffness_db'].copy()
        (self.n_stiff, _, _) = self.stiffness_db.shape
        self.inv_stiffness_db = np.zeros_like(self.stiffness_db, dtype=ct.c_double, order='F')
        for i in range(self.n_stiff):
            self.inv_stiffness_db[i, :, :] = np.linalg.inv(self.stiffness_db[i, :, :])

        # mass data
        self.elem_mass = in_data['elem_mass'].copy()
        self.mass_db = in_data['mass_db'].copy()
        (self.n_mass, _, _) = self.mass_db.shape

        # frame of reference delta
        self.frame_of_reference_delta = in_data['frame_of_reference_delta'].copy()
        # structural twist
        self.structural_twist = in_data['structural_twist'].copy()
        # boundary conditions
        # self.boundary_conditions = in_data['boundary_conditions'].copy()
        # beam number for every elem
        try:
            self.beam_number = in_data['beam_number'].copy()
        except KeyError:
            self.beam_number = np.zeros((self.num_elem, ), dtype=int)

        # applied forces
        try:
            in_data['app_forces'][self.num_node - 1, 5]
        except IndexError:
            in_data['app_forces'] = np.zeros((self.num_node, 6), dtype=ct.c_double, order='F')

        self.steady_app_forces = in_data['app_forces'].astype(dtype=ct.c_double, order='F')

        # generate the Element array
        for ielem in range(self.num_elem):
            self.elements.append(
                beamstructures.Element(
                    ielem,
                    self.num_node_elem,
                    self.connectivities[ielem, :],
                    self.ini_info.pos[self.connectivities[ielem, :], :],
                    self.frame_of_reference_delta[ielem, :, :],
                    self.structural_twist[ielem, :],
                    self.beam_number[ielem],
                    self.elem_stiffness[ielem],
                    self.elem_mass[ielem]))
        # now we need to add the attributes like mass and stiffness index
        for ielem in range(self.num_elem):
            dictionary = dict()
            dictionary['stiffness_index'] = self.elem_stiffness[ielem]
            dictionary['mass_index'] = self.elem_mass[ielem]
            self.elements[ielem].add_attributes(dictionary)

        # psi calculation
        self.generate_psi()

        # master-slave structure
        self.generate_master_structure()

        # the timestep_info[0] is the steady state or initial state for unsteady solutions
        self.ini_info.steady_applied_forces = self.steady_app_forces.astype(dtype=ct.c_double, order='F')
        # rigid body rotations
        self.ini_info.quat = self.settings['orientation'].astype(dtype=ct.c_double, order='F')

        self.timestep_info.append(self.ini_info.copy())
        self.timestep_info[-1].steady_applied_forces = self.steady_app_forces.astype(dtype=ct.c_double, order='F')

        # lumped masses
        try:
            self.lumped_mass = in_data['lumped_mass'].copy()
        except KeyError:
            self.lumped_mass = None
        else:
            self.lumped_mass_nodes = in_data['lumped_mass_nodes'].copy()
            self.lumped_mass_inertia = in_data['lumped_mass_inertia'].copy()
            self.lumped_mass_position = in_data['lumped_mass_position'].copy()
            self.n_lumped_mass, _ = self.lumped_mass_position.shape
        # lumped masses to element mass
        if self.lumped_mass is not None:
            self.lump_masses()

        # self.generate_dof_arrays()
        self.generate_fortran()
Ejemplo n.º 3
0
    def generate(self, in_data, settings):
        self.settings = settings
        # read and store data
        # type of node
        self.num_node_elem = in_data['num_node_elem']
        # node info
        self.num_node = in_data['num_node']
        self.num_elem = in_data['num_elem']
        # ini info
        self.ini_info = StructTimeStepInfo(self.num_node, self.num_elem,
                                           self.num_node_elem)
        # attention, it has to be copied, not only referenced
        self.ini_info.pos = in_data['coordinates'].astype(dtype=ct.c_double,
                                                          order='F')

        # connectivity information
        self.connectivities = in_data['connectivities'].astype(dtype=ct.c_int,
                                                               order='F')

        # stiffness data
        self.elem_stiffness = in_data['elem_stiffness'].copy()
        self.stiffness_db = in_data['stiffness_db'].copy()
        (self.n_stiff, _, _) = self.stiffness_db.shape
        self.inv_stiffness_db = np.zeros_like(self.stiffness_db,
                                              dtype=ct.c_double,
                                              order='F')
        for i in range(self.n_stiff):
            self.inv_stiffness_db[i, :, :] = np.linalg.inv(
                self.stiffness_db[i, :, :])

        # mass data
        self.elem_mass = in_data['elem_mass'].copy()
        self.mass_db = in_data['mass_db'].copy()
        (self.n_mass, _, _) = self.mass_db.shape

        # frame of reference delta
        self.frame_of_reference_delta = in_data[
            'frame_of_reference_delta'].copy()
        # structural twist
        self.structural_twist = in_data['structural_twist'].copy()
        # boundary conditions
        self.boundary_conditions = in_data['boundary_conditions'].copy()
        # beam number for every elem
        try:
            self.beam_number = in_data['beam_number'].copy()
        except KeyError:
            self.beam_number = np.zeros((self.num_elem, ), dtype=int)

        # applied forces
        self.steady_app_forces = np.zeros((self.num_node, 6))
        try:
            self.steady_app_forces = in_data['app_forces'].copy()
        except KeyError:
            pass

        # generate the Element array
        for ielem in range(self.num_elem):
            self.elements.append(
                beamstructures.Element(
                    ielem, self.num_node_elem, self.connectivities[ielem, :],
                    self.ini_info.pos[self.connectivities[ielem, :], :],
                    self.frame_of_reference_delta[ielem, :, :],
                    self.structural_twist[self.connectivities[ielem, :]],
                    self.beam_number[ielem], self.elem_stiffness[ielem],
                    self.elem_mass[ielem]))
        # now we need to add the attributes like mass and stiffness index
        for ielem in range(self.num_elem):
            dictionary = dict()
            dictionary['stiffness_index'] = self.elem_stiffness[ielem]
            dictionary['mass_index'] = self.elem_mass[ielem]
            self.elements[ielem].add_attributes(dictionary)

        # psi calculation
        self.generate_psi()

        # master-slave structure
        self.generate_master_structure()

        # the timestep_info[0] is the steady state or initial state for unsteady solutions
        self.ini_info.steady_applied_forces = self.steady_app_forces.astype(
            dtype=ct.c_double, order='F')
        # rigid body rotations
        self.ini_info.update_orientation(self.settings['orientation'])
        self.timestep_info.append(self.ini_info.copy())
        self.timestep_info[
            -1].steady_applied_forces = self.steady_app_forces.astype(
                dtype=ct.c_double, order='F')

        # lumped masses
        try:
            self.lumped_mass = in_data['lumped_mass'].copy()
        except KeyError:
            self.lumped_mass = None
        else:
            self.lumped_mass_nodes = in_data['lumped_mass_nodes'].copy()
            self.lumped_mass_inertia = in_data['lumped_mass_inertia'].copy()
            self.lumped_mass_position = in_data['lumped_mass_position'].copy()
            self.n_lumped_mass, _ = self.lumped_mass_position.shape
        # lumped masses to element mass
        if self.lumped_mass is not None:
            self.lump_masses()

        self.generate_dof_arrays()
        self.generate_fortran()