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] = {}
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
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()
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
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
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