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 test_bm_eigenfrequency_shell(self): bm = test_bm() p = Part("MyPart") a = Assembly("MyAssembly") / [p / bm] create_beam_mesh(bm, p.fem, "shell") fix_set = p.fem.add_set(FemSet("bc_nodes", get_beam_end_nodes(bm), "nset")) a.fem.add_bc(Bc("Fixed", fix_set, [1, 2, 3, 4, 5, 6])) a.fem.add_step(Step("Eigen", "eigenfrequency")) a.to_fem("Cantilever_CA_EIG_sh", "abaqus", overwrite=True) a.to_fem("Cantilever_CA_EIG_sh", "sesam", overwrite=True) res = a.to_fem("Cantilever_CA_EIG_sh", "code_aster", overwrite=True, execute=True) f = h5py.File(res.results_file_path) modes = f.get("CHA/modes___DEPL") for mname, m in modes.items(): mode = m.attrs["NDT"] freq = m.attrs["PDT"] print(mode, freq)
def add_bcs(self): from ada.fem import Bc, FemSet for i, bc_loc in enumerate([self.c1, self.c2, self.c3, self.c4]): fem_set_btn = FemSet(f"fix{i}", [], "nset") self.fem.add_set(fem_set_btn, p=bc_loc(self._origin[2])) self.fem.add_bc(Bc(f"bc_fix{i}", fem_set_btn, [1, 2, 3]))
def get_bc(match): d = match.groupdict() bc_name = d["name"] if d["name"] is not None else next(bc_counter) bc_type = d["type"] set_name, dofs, magn = get_dofs(d["content"]) if "." in set_name: part_instance_name, set_name = set_name.split(".") fem_set = get_nset(part_instance_name, set_name) else: if set_name in fem.nsets.keys(): fem_set = fem.sets.get_nset_from_name(set_name) else: val = str_to_int(set_name) if val in fem.nodes.dmap.keys(): node = fem.nodes.from_id(val) fem_set = FemSet(bc_name + "_set", [node], "nset", parent=fem) else: raise ValueError( f'Unable to find set "{set_name}" in part {fem}') if fem_set is None: raise Exception("Unable to Find node set") props = dict() if bc_type is not None: props["bc_type"] = bc_type if magn is not None: props["magnitudes"] = magn return Bc(bc_name, fem_set, dofs, parent=fem, **props)
def test_beam_with_isotropic_mass(beam_model_line, isotropic_mass: Mass, fem_format, test_fem_mass_dir): bm = beam_model_line.get_by_name("Bm") fix_nodes = get_beam_end_nodes(bm) fs_fix = bm.parent.fem.add_set( FemSet("FixSet", fix_nodes, FemSet.TYPES.NSET)) bm.parent.fem.add_bc(Bc("FixBc", fs_fix, [1, 2, 3, 4, 5, 6])) end_nodes = get_beam_end_nodes(bm, 2) fs_mass = bm.parent.fem.add_set( FemSet("MassSet", end_nodes, FemSet.TYPES.NSET)) isotropic_mass.fem_set = fs_mass bm.parent.fem.add_mass(isotropic_mass) a = bm.parent.get_assembly() a.fem.add_step(StepEigen("StepEig", num_eigen_modes=10)) name = f"bm_wIsoMass_{fem_format}" try: res = beam_model_line.to_fem(name, fem_format, scratch_dir=test_fem_mass_dir, overwrite=True) except IncompatibleElements as e: logging.error(e) return if res is not None and res.eigen_mode_data is not None: for mode in res.eigen_mode_data.modes: print(mode)
def beam_ex1(p1=(0, 0, 0), p2=(1.5, 0, 0), profile="IPE400"): """ :return: :rtype: ada.Assembly """ bm = Beam("MyBeam", p1, p2, profile, Material("S355")) a = Assembly("Test", user=User("krande")) / [Part("MyPart") / bm] h = 0.2 r = 0.02 normal = [0, 1, 0] xdir = [-1, 0, 0] # Polygon Extrusions origin = np.array([0.2, -0.1, -0.1]) points = [(0, 0), (0.1, 0), (0.05, 0.1)] bm.add_penetration(PrimExtrude("Poly1", points, h, normal, origin, xdir)) origin += np.array([0.2, 0, 0]) points = [(0, 0, r), (0.1, 0, r), (0.05, 0.1, r)] bm.add_penetration(PrimExtrude("Poly2", points, h, normal, origin, xdir)) origin += np.array([0.2, 0, 0]) points = [(0, 0, r), (0.1, 0, r), (0.1, 0.2, r), (0.0, 0.2, r)] bm.add_penetration(PrimExtrude("Poly3", points, h, normal, origin, xdir)) # Cylinder Extrude x = origin[0] + 0.2 bm.add_penetration(PrimCyl("cylinder", (x, -0.1, 0), (x, 0.1, 0), 0.1)) # Box Extrude x += 0.2 bm.add_penetration(PrimBox("box", (x, -0.1, -0.1), (x + 0.2, 0.1, 0.1))) # Create a FEM analysis of the beam as a cantilever subjected to gravity loads p = a.get_part("MyPart") create_beam_mesh(bm, p.fem, "shell") # Add a set containing ALL elements (necessary for Calculix loads). fs = p.fem.add_set(FemSet("Eall", [el for el in p.fem.elements], "elset")) step = a.fem.add_step( Step("gravity", "static", nl_geom=True, init_incr=100.0, total_time=100.0)) step.add_load(Load("grav", "gravity", -9.81 * 800, fem_set=fs)) fix_set = p.fem.add_set(FemSet("bc_nodes", get_beam_end_nodes(bm), "nset")) a.fem.add_bc(Bc("Fixed", fix_set, [1, 2, 3])) return a
def add_bcs(self): funcs: List[Callable] = [self.c1, self.c2, self.c3, self.c4] fem_set_btn = self.fem.add_set(FemSet("fix", [], FemSet.TYPES.NSET)) nodes: List[Node] = [] for bc_loc in funcs: location = self.placement.origin + bc_loc(self._elevations[0]) nodes += self.fem.nodes.get_by_volume(location) fem_set_btn.add_members(nodes) self.fem.add_bc(Bc("bc_fix", fem_set_btn, [1, 2, 3]))
def add_bc(self, bc: Bc) -> Bc: if bc.name in [b.name for b in self.bcs]: raise ValueError(f'BC with name "{bc.name}" already exists') bc.parent = self if bc.fem_set.parent is None: logging.debug("Bc FemSet has no parent. Adding to self") self.sets.add(bc.fem_set) self.bcs.append(bc) return bc
def grab_bc(match): d = match.groupdict() node = fem.nodes.from_id(str_to_int(d["nodeno"])) assert isinstance(node, Node) fem_set = FemSet(f"bc{node.id}_set", [node], "nset") fem.sets.add(fem_set) dofs = [] for i, c in enumerate(d["content"].replace("\n", "").split()): bc_sestype = str_to_int(c.strip()) if bc_sestype in [0, 4]: continue dofs.append(i + 1) bc = Bc(f"bc{node.id}", fem_set, dofs, parent=fem) node.bc = bc return bc
def grab_bc(match, fem: FEM) -> Union[Bc, None]: d = match.groupdict() node = fem.nodes.from_id(str_to_int(d["nodeno"])) for constraint in fem.constraints.values(): if node in constraint.m_set.members: return None if node in constraint.s_set.members: return None fem_set = fem.sets.add(FemSet(f"bc{node.id}_set", [node], "nset")) dofs = [] for i, c in enumerate(d["content"].replace("\n", "").split()): bc_sestype = str_to_int(c.strip()) if bc_sestype in [0, 4]: continue dofs.append(i + 1) bc = Bc(f"bc{node.id}", fem_set, dofs, parent=fem) node.bc = bc return bc
def beam_ex1(p1=(0, 0, 0), p2=(1.5, 0, 0), profile="IPE400", geom_repr=ElemType.SHELL) -> Assembly: mat_grade = CarbonSteel.TYPES.S355 bm = Beam("MyBeam", p1, p2, profile, Material("S355", mat_model=CarbonSteel(mat_grade))) bm.material.model.plasticity_model = DnvGl16Mat(bm.section.t_w, mat_grade) a = Assembly("Test", user=User("krande")) / [Part("MyPart") / bm] add_random_cutouts(bm) # Create a FEM analysis of the beam as a cantilever subjected to gravity loads p = a.get_part("MyPart") p.fem = bm.to_fem_obj(0.1, geom_repr) # Add a set containing ALL elements (necessary for Calculix loads). fs = p.fem.add_set(FemSet("Eall", [el for el in p.fem.elements], FemSet.TYPES.ELSET)) step = a.fem.add_step(StepImplicit("gravity", nl_geom=True, init_incr=100.0, total_time=100.0)) step.add_load(Load("grav", Load.TYPES.GRAVITY, -9.81 * 800, fem_set=fs)) fix_set = p.fem.add_set(FemSet("bc_nodes", get_beam_end_nodes(bm), FemSet.TYPES.NSET)) a.fem.add_bc(Bc("Fixed", fix_set, [1, 2, 3])) return a