def test_beam_offset(self): bm1 = Beam( "bm1", n1=[0, 0, 0], n2=[2, 0, 0], sec="IPE300", mat=Material("SteelMat", CarbonSteel("S420")), colour="red", up=(0, 0, 1), e1=(0, 0, -0.1), e2=(0, 0, -0.1), ) bm2 = Beam( "bm2", n1=[0, 0, 0], n2=[2, 0, 0], sec="IPE300", mat=Material("SteelMat", CarbonSteel("S420")), colour="blue", up=(0, 0, -1), e1=(0, 0, -0.1), e2=(0, 0, -0.1), ) a = Assembly("Toplevel") / [Part("MyPart") / [bm1, bm2]] a.to_ifc(test_folder / "beams_offset.ifc")
def read_material(ifc_mat, ifc_ref: "IfcRef", assembly: "Assembly") -> Material: from ada.materials.metals import CarbonSteel, Metal mat_psets = ifc_mat.HasProperties if hasattr(ifc_mat, "HasProperties") else None if mat_psets is None or len(mat_psets) == 0: logging.info(f'No material properties found for "{ifc_mat}"') return Material(ifc_mat.Name) props = {} for entity in mat_psets[0].Properties: if entity.is_a("IfcPropertySingleValue"): props[entity.Name] = entity.NominalValue[0] mat_props = dict( E=props.get("YoungModulus", 210000e6), sig_y=props.get("YieldStress", 355e6), rho=props.get("MassDensity", 7850), v=props.get("PoissonRatio", 0.3), alpha=props.get("ThermalExpansionCoefficient", 1.2e-5), zeta=props.get("SpecificHeatCapacity", 1.15), units=assembly.units, ) if "StrengthGrade" in props: mat_model = CarbonSteel(grade=props["StrengthGrade"], **mat_props) else: mat_model = Metal(sig_u=None, **mat_props) return Material(name=ifc_mat.Name, mat_model=mat_model, ifc_ref=ifc_ref, units=assembly.units)
def test_main_properties(): matS355 = Material("MatS355", mat_model=CarbonSteel("S355")) matS420 = Material("MatS420", mat_model=CarbonSteel("S420")) for model in [matS355.model, matS420.model]: assert model.E == 2.1e11 assert model.rho == 7850 assert model.v == 0.3 assert matS355.model.sig_y == 355e6 assert matS420.model.sig_y == 420e6
def test_bm(): bm = Beam("MyBeam", (0, 0.5, 0.5), (5, 0.5, 0.5), "IPE400", Material("S420", CarbonSteel("S420"))) f1 = fundamental_eigenfrequency(bm) f2 = 6.268 * f1 f3 = 17.456 * f1 print(f"Fundamental Eigenfrequencies\n\n1: {f1}\n2: {f2}\n3: {f3}") return bm
def get_morsmel(m): """ MORSMEL Anisotropy, Linear Elastic Structural Analysis, 2-D Membrane Elements and 2-D Thin Shell Elements :param m: :return: """ d = m.groupdict() matno = str_to_int(d["matno"]) return Material( name=mat_names[matno], mat_id=matno, mat_model=CarbonSteel( rho=roundoff(d["rho"]), E=roundoff(d["d11"]), v=roundoff(d["ps1"]), alpha=roundoff(d["alpha1"]), zeta=roundoff(d["damp1"]), sig_p=[], eps_p=[], sig_y=5e6, ), metadata=d, parent=part, )
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 mat_from_list(mat_int, mat_str): guid, name, units = str_fix(mat_str) E, rho, sigy = mat_int return Material(name=name, guid=guid, units=units, mat_model=CarbonSteel(E=E, rho=rho, sig_y=sigy), parent=parent)
def mat_str_to_mat_obj(mat_str): """ Converts a Abaqus materials str into a ADA Materials object :param mat_str: :return: """ from ada import Material rd = roundoff # Name name = re.search(r"name=(.*?)\n", mat_str, _re_in).group(1).split("=")[-1].strip() # Density density_ = re.search(r"\*Density\n(.*?)(?:,|$)", mat_str, _re_in) if density_ is not None: density = rd(density_.group(1).strip().split(",")[0].strip(), 10) else: print('No density flag found for material "{}"'.format(name)) density = None # Elastic re_elastic_ = re.search(r"\*Elastic(?:,\s*type=(.*?)|)\n(.*?)(?:\*|$)", mat_str, _re_in) if re_elastic_ is not None: re_elastic = re_elastic_.group(2).strip().split(",") young, poisson = rd(re_elastic[0]), rd(re_elastic[1]) else: print('No Elastic properties found for material "{name}"'.format(name=name)) young, poisson = None, None # Plastic re_plastic_ = re.search(r"\*Plastic\n(.*?)(?:\*|\Z)", mat_str, _re_in) if re_plastic_ is not None: re_plastic = [tuple(x.split(",")) for x in re_plastic_.group(1).strip().splitlines()] sig_p = [rd(x[0]) for x in re_plastic] eps_p = [rd(x[1]) for x in re_plastic] else: eps_p, sig_p = None, None # Expansion re_zeta = re.search(r"\*Expansion(?:,\s*type=(.*?)|)\n(.*?)(?:\*|$)", mat_str, _re_in) if re_zeta is not None: zeta = float(re_zeta.group(2).split(",")[0].strip()) else: zeta = 0.0 # Return material object model = CarbonSteel( rho=density, E=young, v=poisson, eps_p=eps_p, zeta=zeta, sig_p=sig_p, plasticity_model=None, ) return Material(name=name, mat_model=model)
def test_material_ifc_roundtrip(materials_test_dir): ifc_path = materials_test_dir / "my_material.ifc" p = Part("MyPart") p.add_material(Material("my_mat")) a = Assembly("MyAssembly") / p fp = a.to_ifc(ifc_path, return_file_obj=True) b = ada.from_ifc(fp) assert len(b.materials) == 1
def test_material_equal(self): matvar = dict( sec_type="IG", h=0.8, w_top=0.2, w_btn=0.2, t_fbtn=0.01, t_ftop=0.01, t_w=0.01, ) Material("MyMat")
def test_material_ifc_roundtrip(self): ifc_name = "my_material.ifc" a = Assembly("MyAssembly") p = Part("MyPart") p.add_material(Material("my_mat")) a.add_part(p) a.to_ifc(test_folder / ifc_name) b = Assembly("MyImport") b.read_ifc(test_folder / ifc_name)
def test_negative_sec_contained(self): # A minor change in section box thickness sec = Section("myBG", from_str="BG800x400x20x40") mat = Material("my_mat") bm = Beam("my_beam", (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], "B31") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "beam", fem_set, mat, sec) p = get_fsec_bm_collection() self.assertFalse(fem_sec in p.fem.sections)
def test_material_ifc_roundtrip(self): ifc_name = 'my_material.ifc' a = Assembly('MyAssembly') p = Part('MyPart') p.add_material(Material('my_mat')) a.add_part(p) a.to_ifc(test_folder / ifc_name) b = Assembly('MyImport') b.read_ifc(test_folder / ifc_name)
def test_negative_sec_contained(self): # A minor change in section box thickness sec = Section('myBG', from_str='BG800x400x20x40') mat = Material('my_mat') bm = Beam('my_beam', (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], 'B31') fem_set = FemSet('my_set', [elem], 'elset') fem_sec = FemSection('my_sec', 'beam', fem_set, mat, sec) p = get_fsec_bm_collection() self.assertFalse(fem_sec in p.fem.sections)
def test_negative_mat_contained(self): # A minor change in material property (S420 instead of S355) sec = Section('myBG', from_str='BG800x400x30x40') mat = Material('my_mat', CarbonSteel('S420')) bm = Beam('my_beam', (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], 'B31') fem_set = FemSet('my_set', [elem], 'elset') fem_sec = FemSection('my_sec', 'beam', fem_set, mat, sec) p = get_fsec_bm_collection() self.assertFalse(fem_sec in p.fem.sections)
def part_with_beam(): sec = Section("myIPE", from_str="BG800x400x30x40") mat = Material("my_mat") bm = Beam("my_beam", (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], "line") p = Part("my_part") / bm fem_set = p.fem.sets.add(FemSet("my_set", [elem])) p.fem.sections.add( FemSection("my_sec", "line", fem_set, mat, sec, local_z=(0, 0, 1))) p.fem.elements.add(elem) return p
def test_negative_mat_contained(self): # A minor change in material property (S420 instead of S355) sec = Section("myBG", from_str="BG800x400x30x40") mat = Material("my_mat", CarbonSteel("S420")) bm = Beam("my_beam", (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], "B31") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "beam", fem_set, mat, sec) p = get_fsec_bm_collection() self.assertFalse(fem_sec in p.fem.sections)
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_merge_materials(): plates = [] for i in range(1, 10): mat = Material(f"mat{i}", CarbonSteel("S355")) plates.append( Plate(f"pl{i}", [(0, 0, 0), (0, 1, 0), (1, 1, 0)], 20e-3, mat=mat)) a = Assembly() / (Part("MyPart") / plates) p = a.get_part("MyPart") mats = p.materials assert len(mats) == 9 mats.merge_materials_by_properties() assert len(mats) == 1
def create_ifc(name, up=(0, 0, 1)): a = Assembly("MyAssembly") p = Part(name) p.add_beam( Beam( "bm_up", n1=[0, 0, 0], n2=[2, 0, 0], sec="HP200x10", mat=Material("SteelMat", CarbonSteel("S420")), colour="red", up=up, )) a.add_part(p) a.to_ifc(test_folder / name)
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 test_negative_sec_contained(part_with_beam): # A minor change in section box thickness sec = Section("myBG", from_str="BG800x400x20x40") mat = Material("my_mat") bm = Beam("my_beam", (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], "line") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "line", fem_set, mat, sec, local_z=(0, 0, 1)) assert fem_sec not in part_with_beam.fem.sections
def test_negative_mat_contained(part_with_beam): # A minor change in material property (S420 instead of S355) sec = Section("myBG", from_str="BG800x400x30x40") mat = Material("my_mat", CarbonSteel("S420")) bm = Beam("my_beam", (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], "line") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "line", fem_set, mat, sec, local_z=(0, 0, 1)) assert fem_sec not in part_with_beam.fem.sections
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_mat(match): d = match.groupdict() matno = str_to_int(d["matno"]) return Material( name=mat_names[matno], mat_id=matno, mat_model=CarbonSteel( rho=roundoff(d["rho"]), E=roundoff(d["young"]), v=roundoff(d["poiss"]), alpha=roundoff(d["damp"]), zeta=roundoff(d["alpha"]), sig_p=[], eps_p=[], sig_y=roundoff(d["yield"]), ), parent=part, )
def get_fsec_bm_collection(): sec = Section("myIPE", from_str="BG800x400x30x40") mat = Material("my_mat") p = Part("my_part") bm = Beam("my_beam", (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], "B31") fem_set = FemSet("my_set", [elem], "elset") fem_sec = FemSection("my_sec", "beam", fem_set, mat, sec, local_z=(0, 0, 1)) p.add_beam(bm) p.fem.elements.add(elem) p.fem.sets.add(fem_set) p.fem.sections.add(fem_sec) return p
def get_fsec_bm_collection(): sec = Section('myIPE', from_str='BG800x400x30x40') mat = Material('my_mat') p = Part('my_part') bm = Beam('my_beam', (0, 0, 0), (1, 0, 0), sec, mat) elem = Elem(1, [bm.n1, bm.n2], 'B31') fem_set = FemSet('my_set', [elem], 'elset') fem_sec = FemSection('my_sec', 'beam', fem_set, mat, sec, local_z=(0, 0, 1)) p.add_beam(bm) p.fem.elements.add(elem) p.fem.sets.add(fem_set) p.fem.sections.add(fem_sec) return p
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