Example #1
0
 def __init__(
         self,
         id: int,
         Fx: float = 0.0,
         Fz: float = 0.0,
         Ty: float = 0.0,
         ux: float = 0.0,
         uz: float = 0.0,
         phi_y: float = 0,
         vertex: Vertex = Vertex(0, 0),
         hinge: bool = False,
 ):
     """
     :param id: ID of the node, integer
     :param Fx: Value of Fx
     :param Fz: Value of Fz
     :param Ty: Value of Ty
     :param ux: Value of ux
     :param uz: Value of uz
     :param phi_y: Value of phi
     :param vertex: Point object
     :param hinge: Boolean
     """
     self.id = id
     # forces
     self.Fx = Fx
     self.Fz = Fz
     self.Ty = Ty
     # displacements
     self.ux = ux
     self.uz = uz
     self.phi_y = phi_y
     self.vertex = vertex
     self.hinge = hinge
     self.elements: Dict[int, Element] = {}
Example #2
0
def det_vertices(system, location_list):
    if isinstance(location_list, Vertex):
        point_1 = system._previous_point
        point_2 = Vertex(location_list)
    elif len(location_list) == 1:
        point_1 = system._previous_point
        point_2 = Vertex(location_list[0][0], location_list[0][1])
    elif isinstance(location_list[0], (int, float)):
        point_1 = system._previous_point
        point_2 = Vertex(location_list[0], location_list[1])
    elif isinstance(location_list[0], Vertex):
        point_1 = location_list[0]
        point_2 = location_list[1]
    else:
        point_1 = Vertex(location_list[0][0], location_list[0][1])
        point_2 = Vertex(location_list[1][0], location_list[1][1])
    system._previous_point = point_2

    return point_1, point_2
Example #3
0
    def insert_node(self, element_id, location=None, factor=None):
        """
        Insert a node into an existing structure.
        This can be done by adding a new Vertex at any given location, or by setting a factor of the elements
        length. E.g. if you want a node at 40% of the elements length, you pass factor = 0.4.

        Note: this method completely rebuilds the SystemElements object and is therefore slower then building
        a model with `add_element` methods.

        :param element_id: (int) Id number of the element you want to insert the node.
        :param location: (list/ Vertex) The nodes of the element or the next node of the element.

            :Example:

            .. code-block:: python

                   location=[x, y]
                   location=Vertex

        :param: factor: (flt) Value between 0 and 1 to determine the new node location.
        """
        ss = SystemElements(EA=self.EA, EI=self.EI, load_factor=self.load_factor,
                            mesh=self.plotter.mesh)

        for element in self.element_map.values():
            g = self.element_map[element.id].dead_load
            mp = self.non_linear_elements[element.id] if element.id in self.non_linear_elements else None
            if element_id == element.id:
                if factor is not None:
                    location = factor * (element.vertex_2 - element.vertex_1) + element.vertex_1
                else:
                    location = Vertex(location)

                mp1 = mp2 = spring1 = spring2 = None
                if mp is not None:
                    if 1 in mp:
                        mp1 = {1: mp[1]}
                    if 2 in mp:
                        mp2 = {2: mp[2]}
                if element.springs is not None:
                    if 1 in element.springs:
                        spring1 = {1: element.springs[1]}
                    if 2 in element.springs:
                        spring2 = {2: element.springs[2]}

                ss.add_element([element.vertex_1, location], EA=element.EA, EI=element.EI, g=g, mp=mp1, spring=spring1)
                ss.add_element([location, element.vertex_2], EA=element.EA, EI=element.EI, g=g, mp=mp2, spring=spring2)

            else:
                ss.add_element([element.vertex_1, element.vertex_2], EA=element.EA,
                               EI=element.EI, g=g, mp=mp, spring=element.springs)
        self.__dict__ = ss.__dict__.copy()
Example #4
0
    def find_node_id(self, vertex):
        """
        Retrieve the ID of a certain location.

        :param vertex: (Vertex/ list/ tpl) Vertex_xz, [x, y], (x, y)
        :return: (int/ None) id of the node at the location of the vertex
        """
        if isinstance(vertex, (list, tuple)):
            vertex = Vertex(vertex)
        try:
            tol = 1e-9
            return next(filter(lambda x: math.isclose(x.vertex.x, vertex.x, abs_tol=tol)
                                         and math.isclose(x.vertex.y, vertex.y, abs_tol=tol),
                               self.node_map.values())).id
        except StopIteration:
            return None
Example #5
0
    def __init__(self, figsize=(12, 8), EA=15e3, EI=5e3, load_factor=1, mesh=50):
        """
        * E = Young's modulus
        * A = Area
        * I = Moment of Inertia

        :param figsize: (tpl) Set the standard plotting size.
        :param EA: (flt) Standard E * A. Set the standard values of EA if none provided when generating an element.
        :param EI: (flt) Standard E * I. Set the standard values of EA if none provided when generating an element.
        :param load_factor: (flt) Multiply all loads with this factor.
        :param mesh: (int) Plotting mesh. Has no influence on the calculation.
        """
        # init object
        self.post_processor = post_sl(self)
        self.plotter = plotter.Plotter(self, mesh)
        self.plot_values = plotter.PlottingValues(self, mesh)

        # standard values if none provided
        self.EA = EA
        self.EI = EI
        self.figsize = figsize
        self.orientation_cs = -1  # needed for the loads directions

        # structure system
        self.element_map = {}  # maps element ids to the Element objects.
        self.node_map = {}  # maps node ids to the Node objects.
        self.node_element_map = {}  # maps node ids to Element objects
        # keys matrix index (for both row and columns), values K, are processed assemble_system_matrix
        self.system_spring_map = {}

        # list of indexes that remain after conditions are applied
        self._remainder_indexes = []

        # keep track of the node_id of the supports
        self.supports_fixed = []
        self.supports_hinged = []
        self.supports_roll = []
        self.supports_spring_x = []
        self.supports_spring_z = []
        self.supports_spring_y = []
        self.supports_roll_direction = []
        self.inclined_roll = (
            {}
        )  # map node ids to inclination angle relative to global x-axis.

        # save tuples of the arguments for copying purposes.
        self.supports_spring_args = []

        # keep track of the loads
        self.loads_point = {}  # node ids with a point loads
        self.loads_q = {}  # element ids with a q-load
        self.loads_moment = {}
        self.loads_dead_load = set()  # element ids with q-load due to dead load

        # results
        self.reaction_forces = {}  # node objects
        self.non_linear = False
        self.non_linear_elements = (
            {}
        )  # keys are element ids, values are dicts: {node_index: max moment capacity}
        self.buckling_factor = None

        # previous point of element
        self._previous_point = Vertex(0, 0)
        self.load_factor = load_factor

        # Objects state
        self.count = 0
        self.system_matrix_locations = []
        self.system_matrix = None
        self.system_force_vector = None
        self.system_displacement_vector = None
        self.shape_system_matrix = None
        self.reduced_force_vector = None
        self.reduced_system_matrix = None
        self._vertices = {}  # maps vertices to node ids
Example #6
0
    def __init__(self,
                 figsize=(12, 8),
                 EA=15e3,
                 EI=5e3,
                 load_factor=1,
                 mesh=50,
                 plot_backend='mpl'):
        """
        E = Young's modulus
        A = Area
        I = Moment of Inertia

        :param figsize: (tpl) Set the standard plotting size.
        :param EA: (flt) Standard E * A. Set the standard values of EA if none provided when generating an element.
        :param EI: (flt) Standard E * I. Set the standard values of EA if none provided when generating an element.
        :param load_factor: (flt) Multiply all loads with this factor.
        :param mesh: (int) Plotting mesh. Has no influence on the calculation.
        :param plot_backend: (str)  matplotlib  -> "mpl"  (Currently only the matplotlib one is stable)
                                    plotly      -> "plt"
                                    plotly nb   -> "ipt"
        """
        # init object
        self.post_processor = post_sl(self)
        self.plotter = Plotter(self, mesh, plot_backend)

        # standard values if none provided
        self.EA = EA
        self.EI = EI
        self.figsize = figsize
        self.orientation_cs = -1  # needed for the loads directions

        # structure system
        self.element_map = {}  # maps element ids to the Element objects.
        self.node_map = {}  # maps node ids to the Node objects.
        self.node_element_map = {}  # maps node ids to Element objects
        self.system_spring_map = {
        }  # keys matrix index (for both row and columns), values K

        # list of indexes that remain after conditions are applied
        self._remainder_indexes = []

        # keep track of the node_id of the supports
        self.supports_fixed = []
        self.supports_hinged = []
        self.supports_roll = []
        self.supports_spring_x = []
        self.supports_spring_z = []
        self.supports_spring_y = []
        self.supports_roll_direction = []

        # keep track of the loads
        self.loads_point = {}  # node ids with a point loads
        self.loads_q = {}  # element ids with a q-load
        self.loads_moment = {}
        self.loads_dead_load = []  # element ids with q-load due to dead load

        # results
        self.reaction_forces = {}  # node objects
        self.non_linear = False
        self.non_linear_elements = {
        }  # keys are element ids, values are dicts: {node_index: max moment capacity}

        # previous point of element
        self._previous_point = Vertex(0, 0)
        self.load_factor = load_factor

        # Objects state
        self.count = 0
        self.system_matrix_locations = []
        self.system_matrix = None
        self.system_force_vector = None
        self.system_displacement_vector = None
        self.shape_system_matrix = None
        self.reduced_force_vector = None
        self.reduced_system_matrix = None
        self._vertices = {}  # maps vertices to node ids