def test_read_orientation_str(ori_w_nodes_text): fem = FEM("DummyFEM") fem.nodes.add(Node((0, 0, 0), 5)) fem.nodes.add(Node((1, 0, 0), 95)) fem.nodes.add(Node((1, 1, 0), 126)) res = get_lcsys_from_bulk(ori_w_nodes_text, fem) assert len(res) == 1 csys = res["dummy_csys"] assert csys.definition == "NODES" assert len(csys.nodes) == 3
def elems(): n1 = Node([1.0, 2.0, 3.0], 1) n2 = Node([1.0, 1.0, 1.0], 2) n3 = Node([2.0, 1.0, 8.0], 3) n4 = Node([1.0, 2.0, 3.0], 4) el1 = Elem(1, [n1, n2], "LINE") el2 = Elem(2, [n2, n3], "LINE") el3 = Elem(3, [n3, n1], "LINE") el4 = Elem(4, [n1, n2, n3, n4], "QUAD") return el1, el2, el3, el4
def test_in_between(self): p1 = 284.651885, 130.233454, 553.35 p2 = 284.651885, 130.233454, 553.425 p3 = 284.651885, 130.233454, 553.5 p4 = 284.651885, 130.233454, 554.5 n1 = Node(p1, 1) n2 = Node(p2, 2) n3 = Node(p3, 3) n4 = Node(p4, 4) nodes = Nodes([n1, n2, n3, n4]) res = Nodes(nodes.get_by_volume(p=p1)) self.assertEqual(len(res), 1)
def test_add_to_list(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes([n1, n2, n3]) n20 = Node((1, 1, 8), 20) n21 = Node((1, 2, 4), 21) n22 = Node((2, 1, 6), 22) s.add(n20) s.add(n21) s.add(n22) assert s == Nodes([n2, n20, n1, n21, n22, n3])
def get_nodes(): n1 = Node([1.0, 2.0, 3.0], 1) n2 = Node([1.0, 1.0, 1.0], 2) n3 = Node([2.0, 1.0, 8.0], 3) n4 = Node([1.0, 2.0, 3.0], 4) n5 = Node([1.0, 3.0, 2.0], 5) n6 = Node([1.0, 1.0, 3.0], 6) n7 = Node([4.0, 5.0, 1.0], 7) n8 = Node([2.0, 4.0, 3.0], 8) n9 = Node([1.0, 1.0, 4.0], 9) n10 = Node([5.0, 2.0, 3.0], 10) return n1, n2, n3, n4, n5, n6, n7, n8, n9, n10
def test_add_to_list(self): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = get_nodes() s = Nodes([n1, n2, n3]) n20 = Node((1, 1, 8), 20) n21 = Node((1, 2, 4), 21) n22 = Node((2, 1, 6), 22) s.add(n20) s.add(n21) s.add(n22) self.assertEqual(s, Nodes([n2, n20, n1, n21, n22, n3]))
def get_nodes(): n1 = Node((1.0, 2.0, 3.0), 1) n2 = Node((1.0, 1.0, 1.0), 2) n3 = Node((2.0, 1.0, 8.0), 3) n4 = Node((1.0, 2.0, 3.0), 4) n5 = Node((1.0, 3.0, 2.0), 5) n6 = Node((1.0, 1.0, 3.0), 6) n7 = Node((4.0, 5.0, 1.0), 7) n8 = Node((2.0, 4.0, 3.0), 8) n9 = Node((1.0, 1.0, 4.0), 9) n10 = Node((5.0, 2.0, 3.0), 10) return n1, n2, n3, n4, n5, n6, n7, n8, n9, n10
def test_negative_contained_shell_(part_with_shell): # Testing equal operator for change in element type mat = Material("my_mat") elem = Elem( 1, [Node((0, 0, 0)), Node((1, 0, 0)), Node((1, 1, 0)), Node((0, 1, 0))], "quad") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "shell", fem_set, mat, thickness=0.01) assert fem_sec not in part_with_shell.fem.sections
def test_negative_contained_shell_(self): # Testing equal operator for change in element type mat = Material("my_mat") elem = Elem(1, [ Node((0, 0, 0)), Node((1, 0, 0)), Node((1, 1, 0)), Node((0, 1, 0)) ], "S4") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "shell", fem_set, mat, thickness=0.01) p = get_fsec_sh_collection() self.assertFalse(fem_sec in p.fem.sections)
def test_negative_contained_shell(self): # Testing equal operator for different shell thickness mat = Material('my_mat') elem = Elem(1, [ Node((0, 0, 0)), Node((1, 0, 0)), Node((1, 1, 0)), Node((0, 1, 0)) ], 'S4R') fem_set = FemSet('my_set', [elem], 'elset') fem_sec = FemSection('my_sec', 'shell', fem_set, mat, thickness=0.02) p = get_fsec_sh_collection() self.assertFalse(fem_sec in p.fem.sections)
def get_node(m): d = m.groupdict() return Node( [float(d["x"]), float(d["y"]), float(d["z"])], int(float(d["id"])), parent=parent, )
def add(self, joint, point_tol=_Settings.point_tol): """ Add a joint :param joint: :param point_tol: Point Tolerance :type joint: ada.JointBase """ from ada import Node if joint.name is None: raise Exception("Name is not allowed to be None.") if joint.name in self._dmap.keys(): raise ValueError("Joint Exists with same name") new_node = Node(joint.centre) node = self._joint_centre_nodes.add(new_node, point_tol=point_tol) if node != new_node: return self._nmap[node] else: self._nmap[node] = joint self._dmap[joint.name] = joint self._connections.append(joint)
def are_beams_connected(beams): """ :param beams: Tuple containing beam and list of beams found using clash check :return: """ bm1 = beams[0] assert isinstance(bm1, Beam) for bm2 in beams[1]: if bm1 == bm2: continue assert isinstance(bm2, Beam) res = beam_cross_check(bm1, bm2, out_of_plane_tol) if res is None: continue point, s, t = res t_len = (abs(t) - 1) * bm2.length s_len = (abs(s) - 1) * bm1.length if t_len > bm2.length / 2 or s_len > bm1.length / 2: continue if point is not None: new_node = Node(point) n = nodes.add(new_node, point_tol=point_tol) if n not in nmap.keys(): nmap[n] = [bm1] if bm1 not in nmap[n]: nmap[n].append(bm1) if bm2 not in nmap[n]: nmap[n].append(bm2)
def convert_springs_to_connectors(assembly): """ Converts all single noded springs to connector elements :param assembly: :type assembly: ada.Assembly """ import numpy as np from ada import Node from ada.fem import Bc, Connector, ConnectorSection, FemSet for p in assembly.get_all_subparts(): for spring in p.fem.springs.values(): n1 = spring.nodes[0] n2 = Node(n1.p - np.array([0, 0, 10e-3])) assembly.fem.add_rp(spring.name + "_rp", n2) fs = FemSet(spring.name + "_bc", [n2], "nset") assembly.fem.add_set(fs) assembly.fem.add_bc(Bc(spring.name + "_bc", fs, [1, 2, 3, 4, 5, 6])) diag = [] for dof, row in enumerate(spring.stiff): for j, stiffness in enumerate(row): if dof == j: diag.append(stiffness) con_sec = ConnectorSection(spring.name + "_consec", diag, []) assembly.fem.add_connector_section(con_sec) con = Connector(spring.name + "_con", spring.id, n1, n2, "bushing", con_sec) assembly.fem.add_connector(con) p.fem._springs = dict() p.fem.elements.filter_elements(delete_elem=["SPRING1"])
def get_nodes_and_elements(gmsh_session, fem, fem_set_name="all_elements"): nodes = list(gmsh_session.model.mesh.getNodes(-1, -1)) # Get nodes fem._nodes = Nodes( [ Node( [roundoff(x) for x in gmsh_session.model.mesh.getNode(n)[0]], n, parent=fem, ) for n in nodes[0] ], parent=fem, ) # Get elements elemTypes, elemTags, elemNodeTags = gmsh_session.model.mesh.getElements( 2, -1) elements = [] for k, element_list in enumerate(elemTags): face, dim, morder, numv, parv, _ = gmsh_session.model.mesh.getElementProperties( elemTypes[k]) elem_type = gmsh_map[face] for j, eltag in enumerate(element_list): nodes = [] for i in range(numv): idtag = numv * j + i p1 = elemNodeTags[k][idtag] nodes.append(fem.nodes.from_id(p1)) el = Elem(eltag, nodes, elem_type, parent=fem) elements.append(el) fem._elements = FemElements(elements, fem_obj=fem) femset = FemSet(fem_set_name, elements, "elset") fem.sets.add(femset)
def getnodes(m): d = m.groupdict() res = np.fromstring(list_cleanup(d["members"]), sep=",", dtype=np.float64) res_ = res.reshape(int(res.size / 4), 4) members = [Node(n[1:4], int(n[0]), parent=parent) for n in res_] if d["nset"] is not None: parent.sets.add(FemSet(d["nset"], members, "nset", parent=parent)) return members
def part_with_shell(): p = Part("my_part") mat = Material("my_mat") elem = Elem( 1, [Node((0, 0, 0)), Node((1, 0, 0)), Node((1, 1, 0)), Node((0, 1, 0))], "quad") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "shell", fem_set, mat, thickness=0.01) for n in elem.nodes: p.fem.nodes.add(n) p.fem.elements.add(elem) p.fem.sets.add(fem_set) p.fem.sections.add(fem_sec) return p
def get_fsec_sh_collection(): p = Part('my_part') mat = Material('my_mat') elem = Elem( 1, [Node((0, 0, 0)), Node((1, 0, 0)), Node((1, 1, 0)), Node((0, 1, 0))], 'S4R') fem_set = FemSet('my_set', [elem], 'elset') fem_sec = FemSection('my_sec', 'shell', fem_set, mat, thickness=0.01) for n in elem.nodes: p.fem.nodes.add(n) p.fem.elements.add(elem) p.fem.sets.add(fem_set) p.fem.sections.add(fem_sec) return p
def get_nodes_from_gmsh(model: gmsh.model, fem: FEM) -> List[Node]: nodes = list(model.mesh.getNodes(-1, -1)) node_ids = nodes[0] node_coords = nodes[1].reshape(len(node_ids), 3) return [ Node(coord, nid, parent=fem) for nid, coord in zip(node_ids, node_coords) ]
def get_mesh_nodes(self, e): """ :param e: :return: """ nco = gmsh.model.mesh.getNode(e) return Node([roundoff(x) for x in nco[0]], e, parent=self._part.fem)
def test_not_in(self): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = get_nodes() s = Nodes([n1, n2, n3, n4, n5, n6, n7, n8, n9, n10]) n11 = Node((0, 0, 0), 10000) assert n11 not in s assert n10 in s
def find_beams_connected_to_plate(pl: Plate, beams: List[Beam]) -> List[Beam]: """Return all beams with their midpoints inside a specified plate for a given list of beams""" from ada.concepts.containers import Nodes nid = Counter(1) nodes = Nodes( [Node((bm.n2.p + bm.n1.p) / 2, next(nid), refs=[bm]) for bm in beams]) res = nodes.get_by_volume(pl.bbox.p1, pl.bbox.p2) all_beams_within = list(chain.from_iterable([r.refs for r in res])) return all_beams_within
def make_elem(j): el_id = segments[j] nonlocal elem_type nonlocal numv nonlocal fem_nodes no = [] for i in range(numv): p1 = fem_nodes[numv * j + i] p1_co = gmsh.model.mesh.getNode(p1)[0] no.append(Node(p1_co, p1)) return Elem(el_id, no, elem_type, parent=self._part.fem)
def make_elem(j): no = [] for i in range(numv): p1 = fem_nodes[numv * j + i] p1_co = gmsh.model.mesh.getNode(p1)[0] no.append(Node(p1_co, p1)) if len(no) == 3: myorder = [0, 2, 1] no = [no[i] for i in myorder] bm_el_type = "B31" if order == 1 else "B32" return Elem(segments[j], no, bm_el_type, parent=self._part.fem)
def eval_node(ab, n1=True): n = Node(ab) n_old = self._parent.nodes.add(n) # TODO: Evaluate if the following is necessary! if n_old is not None: n = n_old if n.id not in [bm2.n1.id, bm2.n2.id]: if n1 is True: bm2.n1 = n bm2.n1.Free = False else: bm2.n2 = n bm2.n2.Free = False else: logging.debug("Midnode on n1")
def get_nodes_and_elements(gmsh, fem=None, fem_set_name="all_elements"): """ :param gmsh: :type gmsh: gmsh :param fem: :type fem: ada.fem.FEM :param fem_set_name: :type fem_set_name: str """ from ada.fem import FEM fem = FEM("AdaFEM") if fem is None else fem nodes = list(gmsh.model.mesh.getNodes(-1, -1)) # Get nodes fem._nodes = Nodes( [ Node( [roundoff(x) for x in gmsh.model.mesh.getNode(n)[0]], n, parent=fem, ) for n in nodes[0] ], parent=fem, ) # Get elements elemTypes, elemTags, elemNodeTags = gmsh.model.mesh.getElements(2, -1) elements = [] for k, element_list in enumerate(elemTags): face, dim, morder, numv, parv, _ = gmsh.model.mesh.getElementProperties( elemTypes[k]) elem_type = gmsh_map[face] for j, eltag in enumerate(element_list): nodes = [] for i in range(numv): idtag = numv * j + i p1 = elemNodeTags[k][idtag] nodes.append(fem.nodes.from_id(p1)) el = Elem(eltag, nodes, elem_type, parent=fem) elements.append(el) fem._elements = FemElements(elements, fem_obj=fem) femset = FemSet(fem_set_name, elements, "elset") fem.sets.add(femset)
def convert_hinge(elem: Elem, hinge: Hinge): if hinge.constraint_ref is not None: return n = hinge.fem_node csys = hinge.csys d = hinge.retained_dofs n2 = Node(n.p, next(new_node_id), parent=elem.parent) elem.parent.nodes.add(n2, allow_coincident=True) i = elem.nodes.index(n) elem.nodes[i] = n2 if elem.eccentricity is not None: if elem.eccentricity.end1 is not None: if n == elem.eccentricity.end1.node: elem.eccentricity.end1.node = n2 if elem.eccentricity.end2 is not None: if n == elem.eccentricity.end2.node: elem.eccentricity.end2.node = n2 if n2.id not in constrain_ids: constrain_ids.append(n2.id) else: logging.error(f"Hinged node {n2} cannot be added twice to different couplings") return None m_set = FemSet(f"el{elem.id}_hinge{i + 1}_m", [n], "nset") s_set = FemSet(f"el{elem.id}_hinge{i + 1}_s", [n2], "nset") elem.parent.add_set(m_set) elem.parent.add_set(s_set) c = Constraint( f"el{elem.id}_hinge{i + 1}_co", Constraint.TYPES.COUPLING, m_set, s_set, d, csys=csys, ) elem.parent.add_constraint(c) hinge.constraint_ref = c logging.info(f"added constraint {c}")
def build_mpc_for_end(elem, n_old, ecc, i): if n_old.id in edited_nodes.keys(): build_constraint(n_old, elem, ecc, i) else: mat = np.eye(3) new_p = np.dot(mat, ecc) + n_old.p n_new = Node(new_p, parent=elem.parent) elem.parent.nodes.add(n_new, allow_coincident=True) m_set = FemSet(f"el{elem.id}_mpc{i + 1}_m", [n_new], "nset") s_set = FemSet(f"el{elem.id}_mpc{i + 1}_s", [n_old], "nset") c = Constraint( f"el{elem.id}_mpc{i + 1}_co", Constraint.TYPES.MPC, m_set, s_set, mpc_type="Beam", parent=elem.parent, ) elem.parent.add_constraint(c) elem.nodes[i] = n_new edited_nodes[n_old.id] = n_new
def test_shell_elem_to_plate(): p = ada.Part("MyPart") nodes1 = [ Node([-15.0001154, -6.0, 24.5], 799), Node([-16.0, -6.0, 24.5], 571), Node([-16.0, -7.0, 24.5], 570), Node([-15.0015383, -7.0, 24.5], 802), ] nodes2 = [ Node([-15.0015383, -7.0, 24.5], 802), Node([-16.0, -7.0, 24.5], 570), Node([-16.0, -8.0, 24.5], 529), Node([-15.0, -8.0, 24.5], 651), ] create_shell_elem(999, nodes1, p.fem) create_shell_elem(1003, nodes2, p.fem) a = ada.Assembly() / p p.fem.sections.merge_by_properties() a.create_objects_from_fem() pl: ada.Plate = a.get_by_name("sh999") nodes_eval = nodes1 assert tuple(pl.nodes[0].p) == tuple(nodes_eval[0].p) assert tuple(pl.poly.seg_global_points[0]) == tuple(nodes_eval[-1].p) assert tuple(pl.poly.seg_global_points[1]) == tuple(nodes_eval[0].p) assert tuple(pl.poly.seg_global_points[2]) == tuple(nodes_eval[1].p) assert tuple(pl.poly.seg_global_points[3]) == tuple(nodes_eval[2].p) pl: ada.Plate = a.get_by_name("sh1003") nodes_eval = nodes2 assert tuple(pl.nodes[0].p) == tuple(nodes_eval[0].p) assert tuple(pl.poly.seg_global_points[0]) == tuple(nodes_eval[-1].p) assert tuple(pl.poly.seg_global_points[1]) == tuple(nodes_eval[0].p) assert tuple(pl.poly.seg_global_points[2]) == tuple(nodes_eval[1].p) assert tuple(pl.poly.seg_global_points[3]) == tuple(nodes_eval[2].p)
def are_beams_connected(bm1: Beam, beams: List[Beam], out_of_plane_tol, point_tol, nodes, nmap) -> None: # TODO: Function should be renamed, or return boolean. Unclear what the function does at the moment for bm2 in beams: if bm1 == bm2: continue res = beam_cross_check(bm1, bm2, out_of_plane_tol) if res is None: continue point, s, t = res t_len = (abs(t) - 1) * bm2.length s_len = (abs(s) - 1) * bm1.length if t_len > bm2.length / 2 or s_len > bm1.length / 2: continue if point is not None: new_node = Node(point) n = nodes.add(new_node, point_tol=point_tol) if n not in nmap.keys(): nmap[n] = [bm1] if bm1 not in nmap[n]: nmap[n].append(bm1) if bm2 not in nmap[n]: nmap[n].append(bm2)