def test_remove_from_list(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes([n1, n2, n3]) s.remove(n3) s.remove(n7) assert s == Nodes([n1, n2])
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 test_in_between(): 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)) assert len(res) == 1
def meshio_read_fem(fem_file, fem_name=None): """Import a FEM file using the meshio package""" mesh = meshio.read(fem_file) name = fem_name if fem_name is not None else "Part-1" fem = FEM(name) def to_node(data): return Node(data[1], data[0]) point_ids = mesh.points_id if "points_id" in mesh.__dict__.keys() else [ i + 1 for i, x in enumerate(mesh.points) ] elem_counter = Counter(1) cell_ids = (mesh.cells_id if "cells_id" in mesh.__dict__.keys() else [[next(elem_counter) for cell in cellblock.data] for cellblock in mesh.cells]) fem.nodes = Nodes([to_node(p) for p in zip(point_ids, mesh.points)]) cell_block_counter = Counter(0) def to_elem(cellblock): block_id = next(cell_block_counter) return [ Elem( cell_ids[block_id][i], [fem.nodes.from_id(point_ids[c]) for c in cell], cellblock.type, ) for i, cell in enumerate(cellblock.data) ] fem.elements = FemElements(chain.from_iterable(map(to_elem, mesh.cells))) return Assembly("TempAssembly") / Part(name, fem=fem)
def get_fem(self, name="AdaFEM") -> FEM: from .utils import ( add_fem_sections, get_elements_from_entities, get_nodes_from_gmsh, ) fem = FEM(name) gmsh_nodes = get_nodes_from_gmsh(self.model, fem) fem.nodes = Nodes(gmsh_nodes, parent=fem) def add_obj_to_elem_ref(el: Elem, obj: Union[Shape, Beam, Plate, Pipe]): el.refs.append(obj) # Get Elements elements = [] for gmsh_data in self.model_map.values(): entity_elements = get_elements_from_entities( self.model, gmsh_data.entities, fem) gmsh_data.obj.elem_refs = entity_elements [add_obj_to_elem_ref(el, gmsh_data.obj) for el in entity_elements] elements += entity_elements fem.elements = FemElements(elements, fem_obj=fem) # Add FEM sections for model_obj, gmsh_data in self.model_map.items(): add_fem_sections(self.model, fem, model_obj, gmsh_data) fem.nodes.renumber() fem.elements.renumber() return fem
def test_not_in(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = 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 test_from_iterables(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes def geniter(): yield n1 yield n2 yield n3 g = geniter() n = Nodes(g) assert len(n) == 3
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_singular_node_by_volume(nodes: Nodes, p: np.ndarray, tol=Settings.point_tol) -> Node: """Returns existing node within the volume, or creates and returns a new Node at the point""" nds = nodes.get_by_volume(p, tol=tol) if len(nds) > 0: node, *other_nodes = nds if len(other_nodes) > 0: logging.warning( f"More than 1 node within point {p}, other nodes: {other_nodes}. Returns node {node}" ) return node else: return Node(p)
def __init__( self, name, colour=None, placement=Placement(), fem: FEM = None, settings: Settings = Settings(), metadata=None, parent=None, units="m", ifc_elem=None, guid=None, ifc_ref: IfcRef = None, ): super().__init__(name, guid=guid, metadata=metadata, units=units, parent=parent, ifc_elem=ifc_elem, ifc_ref=ifc_ref) self._nodes = Nodes(parent=self) self._beams = Beams(parent=self) self._plates = Plates(parent=self) self._pipes = list() self._walls = list() self._connections = Connections(parent=self) self._materials = Materials(parent=self) self._sections = Sections(parent=self) self._colour = colour self._placement = placement self._instances: Dict[Any, Instance] = dict() self._shapes = [] self._parts = dict() self._groups: Dict[str, Group] = dict() if ifc_elem is not None: self.metadata["ifctype"] = self._import_part_from_ifc(ifc_elem) else: if self.metadata.get("ifctype") is None: self.metadata["ifctype"] = "site" if type( self) is Assembly else "storey" self._props = settings if fem is not None: fem.parent = self self.fem = FEM(name + "-1", parent=self) if fem is None else fem
def get_nodes_from_inp(bulk_str, parent: FEM) -> Nodes: """Extract node information from abaqus input file string""" re_no = re.compile( r"^\*Node\s*(?:,\s*nset=(?P<nset>.*?)\n|\n)(?P<members>(?:.*?)(?=\*|\Z))", _re_in, ) 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 nodes = list(chain.from_iterable(map(getnodes, re_no.finditer(bulk_str)))) return Nodes(nodes, parent=parent)
def test_identical(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes([n1, n2, n3]) assert s == s
def test_type_mismatch(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes assert Nodes([n1, n2, n3]) != [n1, n2, n3]
def test_repr_some(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes([n1, n2, n3]) assert repr(s) == "Nodes(3, min_id: 1, max_id: 3)"
def test_repr_empty(): s = Nodes() assert repr(s) == "Nodes(0, min_id: 0, max_id: 0)"
def test_get_by_id_positive(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes([n1, n2, n3]) assert s.from_id(1) == n1 assert s.from_id(2) == n2 assert s.from_id(3) == n3
def test_negative_not_contained(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes n = Nodes([n1, n2, n3, n4, n5, n6, n7, n8, n9, n10]) assert n1 in n
def get_nodes_from_cache(node_group, parent): points_in = node_group[()] points = [Node(n[1:], n[0]) for n in points_in] return Nodes(points, parent=parent)
def med_to_fem(fem_file, fem_name) -> "FEM": from ada import FEM, Node f = h5py.File(fem_file, "r") # Mesh ensemble mesh_ensemble = f["ENS_MAA"] meshes = mesh_ensemble.keys() if len(meshes) != 1: raise ValueError("Must only contain exactly 1 mesh, found {}.".format( len(meshes))) mesh_name = list(meshes)[0] mesh = mesh_ensemble[mesh_name] dim = mesh.attrs["ESP"] fem_name = fem_name if fem_name is not None else mesh_name # Initialize FEM object fem = FEM(fem_name) # Possible time-stepping if "NOE" not in mesh: # One needs NOE (node) and MAI (French maillage, meshing) data. If they # are not available in the mesh, check for time-steppings. time_step = mesh.keys() if len(time_step) != 1: raise ValueError( f"Must only contain exactly 1 time-step, found {len(time_step)}." ) mesh = mesh[list(time_step)[0]] # Points pts_dataset = mesh["NOE"]["COO"] n_points = pts_dataset.attrs["NBR"] points = pts_dataset[()].reshape((n_points, dim), order="F") if "NUM" in mesh["NOE"]: point_num = list(mesh["NOE"]["NUM"]) else: logging.warning("No node information is found on MED file") point_num = np.arange(1, len(points) + 1) fem.nodes = Nodes( [Node(p, point_num[i], parent=fem) for i, p in enumerate(points)], parent=fem) # Point tags tags = None if "FAM" in mesh["NOE"]: tags = mesh["NOE"]["FAM"][()] # Information for point tags point_tags = {} fas = mesh["FAS"] if "FAS" in mesh else f["FAS"][mesh_name] if "NOEUD" in fas: point_tags = _read_families(fas["NOEUD"]) point_sets = _point_tags_to_sets(tags, point_tags, fem) if tags is not None else [] # Information for cell tags cell_tags = {} if "ELEME" in fas: cell_tags = _read_families(fas["ELEME"]) # CellBlock cell_types = [] med_cells = mesh["MAI"] elements = [] element_sets = dict() for med_cell_type, med_cell_type_group in med_cells.items(): if med_cell_type == "PO1": logging.warning("Point elements are still not supported") continue cell_type = med_to_ada_type(med_cell_type) cell_types.append(cell_type) nod = med_cell_type_group["NOD"] n_cells = nod.attrs["NBR"] nodes_in = nod[()].reshape(n_cells, -1, order="F") if "NUM" in med_cell_type_group.keys(): num = list(med_cell_type_group["NUM"]) else: num = np.arange(0, len(nodes_in)) element_block = [ Elem(num[i], [fem.nodes.from_id(e) for e in c], cell_type, parent=fem) for i, c in enumerate(nodes_in) ] elements += element_block # Cell tags if "FAM" in med_cell_type_group: cell_data = med_cell_type_group["FAM"][()] cell_type_sets = _cell_tag_to_set(cell_data, cell_tags) for key, val in cell_type_sets.items(): if key not in element_sets.keys(): element_sets[key] = [] element_sets[key] += [element_block[i] for i in set(val)] fem.elements = FemElements(elements, fem_obj=fem) elsets = _element_set_dict_to_list_of_femset(element_sets, fem) fem.sets = FemSets(elsets + point_sets, parent=fem) return fem
def test_get_by_id_negative(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes([n1, n2, n3]) with pytest.raises(ValueError): s.from_id(4)
def test_one(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes n = Nodes([n1]) assert len(n) == 1
def contained3nodes(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes return Nodes([n1, n2, n3])
def test_positive_equal(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes assert Nodes([n1, n2, n3]) == Nodes([n1, n2, n3])
def test_get_by_volume_point(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes(nodes) c = Nodes(s.get_by_volume(p=(4.0, 5.0, 1.0))) assert c == Nodes([n7])
def test_get_by_volume_box(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes(nodes) c = Nodes(s.get_by_volume(p=(1.5, 0.5, 0.5), vol_box=(4.5, 5.5, 8.5))) assert c == Nodes([n3, n7, n8])
def test_get_by_volume_cylinder(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes s = Nodes(nodes) c = Nodes(s.get_by_volume(p=(1.0, 1.0, 0.5), vol_cyl=(0.2, 4, 0.2))) assert c == Nodes([n2, n6, n9])
def test_negative_equal(nodes): n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 = nodes assert Nodes([n1, n2, n3]) != Nodes([n4, n5, n6])
def test_ten(nodes): n = Nodes(nodes) assert len(n) == 10
def get_nodes(bulk_str: str, parent: "FEM") -> Nodes: nodes = [get_node(m, parent) for m in cards.re_gcoord_in.finditer(bulk_str)] return Nodes(nodes, parent=parent)
def test_empty(): n = Nodes() assert len(n) == 0