def get_dofs(content: str): set_name = None dofs = [] magn = [] if content.count("\n") == 1: temp = content.split(",") set_name = temp[0].strip() dof_in = temp[1].strip().replace("\n", "") if dof_in.lower() == "encastre": dofs = dof_in else: dof = str_to_int(temp[1]) if len(temp) == 2: dofs = [x if dof == x else None for x in range(1, 7)] else: dof_end = str_to_int(temp[2]) dofs = [ x if dof <= x <= dof_end else None for x in range(1, 7) ] else: for line in content.splitlines(): ev = [x.strip() for x in line.split(",")] set_name = ev[0] try: dofs.append(int(ev[1])) except BaseException as e: logging.debug(e) dofs.append(ev[1]) if len(ev) > 3: magn.append(ev[2]) magn = None if len(magn) == 0 else magn return set_name, dofs, magn
def grab_elements(match): d = match.groupdict() el_no = str_to_int(d["elno"]) el_nox = str_to_int(d["elnox"]) internal_external_element_map[el_no] = el_nox nodes = [ fem.nodes.from_id(x) for x in filter( lambda x: x != 0, map(str_to_int, d["nids"].replace("\n", "").split()), ) ] eltyp = d["eltyp"] el_type = sesam_eltype_2_general(str_to_int(eltyp)) if el_type in ("SPRING1", "SPRING2"): spring_elem[el_no] = dict(gelmnt=d) return None metadata = dict(eltyad=str_to_int(d["eltyad"]), eltyp=eltyp) elem = Elem(el_no, nodes, el_type, None, parent=fem, metadata=metadata) if el_type == Elem.EL_TYPES.MASS_SHAPES.MASS: logging.warning( "Mass element interpretation in sesam is undergoing changes. Results should be checked" ) mass_elem[el_no] = dict(gelmnt=d) fem.sets.add( FemSet(f"m{el_no}", [elem], FemSet.TYPES.ELSET, parent=fem)) return elem
def get_femsecs(match, total_geo, curr_geom_num, lcsysd, hinges_global, ecc, thicknesses, fem, mass_elem, spring_elem): next(total_geo) d = match.groupdict() geono = str_to_int(d["geono"]) elno = str_to_int(d["elno"]) matno = str_to_int(d["matno"]) # Go no further if element has no fem section if elno in spring_elem.keys(): next(curr_geom_num) spring_elem[elno]["section_data"] = d return None if elno in mass_elem.keys(): next(curr_geom_num) mass_elem[elno]["section_data"] = d return None elem = fem.elements.from_id(elno) mat = fem.parent.materials.get_by_id(matno) if elem.type in ElemShape.TYPES.lines.all: next(curr_geom_num) return read_line_section(elem, fem, mat, geono, d, lcsysd, hinges_global, ecc) elif elem.type in ElemShape.TYPES.shell.all: next(curr_geom_num) return read_shell_section(elem, fem, mat, elno, thicknesses, geono) else: raise ValueError("Section not added to conversion")
def get_elem_nodes(elem_nodes_str, fem: "FEM"): elem_nodes = [] for d in elem_nodes_str[1:]: temp2 = [x.strip() for x in d.split(".")] par_ = None if len(temp2) == 2: par, setr = temp2 pfems = [] parents = fem.parent.get_all_parts_in_assembly() for p in parents: pfems.append(p.fem.name) if p.fem.name == par: par_ = p break if par_ is None: raise ValueError(f'Unable to find parent for "{par}"') r = par_.fem.nodes.from_id(str_to_int(setr)) if type(r) != Node: raise ValueError("Node ID not found") elem_nodes.append(r) else: r = fem.nodes.from_id(str_to_int(d)) if type(r) != Node: raise ValueError("Node ID not found") elem_nodes.append(r) return elem_nodes
def get_setmap(m, parent): d = m.groupdict() set_type = "nset" if str_to_int(d["istype"]) == 1 else "elset" mem_list = d["members"].split() if set_type == "nset": members = [parent.nodes.from_id(str_to_int(x)) for x in mem_list] else: members = [parent.elements.from_id(str_to_int(x)) for x in mem_list] return str_to_int(d["isref"]), set_type, members
def grab_constraint(master, data, fem: FEM) -> Constraint: m = str_to_int(master) m_set = FemSet(f"co{m}_m", [fem.nodes.from_id(m)], "nset") slaves = [] for d in data: s = str_to_int(d["slave"]) slaves.append(fem.nodes.from_id(s)) s_set = FemSet(f"co{m}_s", slaves, "nset") fem.add_set(m_set) fem.add_set(s_set) return Constraint(f"co{m}", Constraint.TYPES.COUPLING, m_set, s_set, parent=fem)
def add_general_sections(match, fem) -> None: d = match.groupdict() sec_id = str_to_int(d["geono"]) gen_props = GeneralProperties( Ax=roundoff(d["area"], 10), Ix=roundoff(d["ix"], 10), Iy=roundoff(d["iy"], 10), Iz=roundoff(d["iz"], 10), Iyz=roundoff(d["iyz"], 10), Wxmin=roundoff(d["wxmin"]), Wymin=roundoff(d["wymin"]), Wzmin=roundoff(d["wzmin"]), Shary=roundoff(d["shary"]), Sharz=roundoff(d["sharz"]), Shceny=roundoff(d["shceny"]), Shcenz=roundoff(d["shcenz"]), Sy=float(d["sy"]), Sz=float(d["sz"]), ) if sec_id in fem.parent.sections.id_map.keys(): sec = fem.parent.sections.get_by_id(sec_id) sec._genprops = gen_props gen_props.parent = sec else: stype = Section.TYPES.GENERAL sec = Section(name=f"GB{sec_id}", sec_id=sec_id, sec_type=stype, genprops=gen_props, parent=fem.parent) gen_props.parent = sec fem.parent.sections.add(sec)
def get_morsmel(m, mat_names, part) -> Material: """ 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"]) mat_model = CarbonSteel( rho=roundoff(d["rho"]), E=roundoff(d["d11"]), v=roundoff(d["ps1"]), alpha=roundoff(d["alpha1"]), zeta=roundoff(d["damp1"]), sig_y=5e6, ) return Material(name=mat_names[matno], mat_id=matno, mat_model=mat_model, metadata=d, parent=part)
def get_lcsys(m): d = m.groupdict() return str_to_int(d["transno"]), ( roundoff(d["unix"]), roundoff(d["uniy"]), roundoff(d["uniz"]), )
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 get_mass(match, parent: "FEM", mass_id_gen): d = match.groupdict() elset = get_set_from_assembly(d["elset"], parent, "elset") mass_type = d["mass_type"] mass_type_general = aba_to_ada_mass_map.get(mass_type.upper(), None) if mass_type_general is None: raise NotImplementedError( f'Mass type "{mass_type}" is not yet supported by general ADA') p_type = d["ptype"] mass_ints = [ str_to_int(x.strip()) for x in d["mass"].split(",") if x.strip() != "" ] if len(mass_ints) == 1: mass_ints = mass_ints[0] units = d["units"] elem = elset.members[0] mass = Mass(d["elset"], elset, mass_ints, mass_type_general, p_type, mass_id=next(mass_id_gen), units=units, parent=parent) elem.mass_prop = mass return mass
def get_eccentricities(match): d = match.groupdict() eccno = str_to_int(d["eccno"]) ex = float(d["ex"]) ey = float(d["ey"]) ez = float(d["ez"]) return eccno, (ex, ey, ez)
def read_line_section(elem: Elem, fem: FEM, mat: Material, geono, d, lcsysd, hinges_global, eccentricities): transno = str_to_int(d["transno"]) sec = fem.parent.sections.get_by_id(geono) n1, n2 = elem.nodes v = n2.p - n1.p if vector_length(v) == 0.0: xvec = [1, 0, 0] else: xvec = unit_vector(v) zvec = lcsysd[transno] crossed = np.cross(zvec, xvec) ma = max(abs(crossed)) yvec = tuple([roundoff(x / ma, 3) for x in crossed]) fix_data = str_to_int(d["fixno"]) ecc_data = str_to_int(d["eccno"]) members = None if d["members"] is not None: members = [ str_to_int(x) for x in d["members"].replace("\n", " ").split() ] if fix_data == -1: add_hinge_prop_to_elem(elem, members, hinges_global, xvec, yvec) if ecc_data == -1: add_ecc_to_elem(elem, members, eccentricities, fix_data) fem_set = FemSet(sec.name, [elem], "elset", metadata=dict(internal=True), parent=fem) fem.sets.add(fem_set, append_suffix_on_exist=True) fem_sec = FemSection( sec_id=geono, name=sec.name, sec_type=ElemType.LINE, elset=fem_set, section=sec, local_z=zvec, local_y=yvec, material=mat, parent=fem, ) return fem_sec
def interpret_member(mem): msplit = mem.split(",") try: ref = str_to_int(msplit[0]) except BaseException as e: logging.debug(e) ref = msplit[0].strip() return tuple([ref, msplit[1].strip()])
def find_mgspring(m): nonlocal matno_map d = m.groupdict() matno = str_to_int(d["matno"]) ndof = str_to_int(d["ndof"]) res: dict = matno_map.get(matno, None) if res is None: raise ValueError() elid = str_to_int(res["section_data"]["elno"]) bulk = d["bulk"].replace("\n", "").split() spr_name = f"spr{elid}" nid = res["gelmnt"].get("nids", None) n1 = fem.nodes.from_id(str_to_int(nid)) a = 1 row = 0 spring = [] subspring = [] for dof in bulk: subspring.append(float(dof.strip())) a += 1 if a > ndof - row: spring.append(subspring) subspring = [] a = 1 row += 1 new_s = [] for row in spring: l = abs(len(row) - 6) if l > 0: new_s.append([0.0 for i in range(0, l)] + row) else: new_s.append(row) spring_matrix = np.array(new_s) spring_matrix = spring_matrix + spring_matrix.T - np.diag( np.diag(spring_matrix)) fs = FemSet(f"{spr_name}_set", [n1], FemSet.TYPES.NSET, parent=fem) return Spring(spr_name, elid, "SPRING1", fem_set=fs, stiff=spring_matrix, parent=fem)
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 find_mgmass(match) -> Mass: d = match.groupdict() matno = str_to_int(d["matno"]) mat_mass_map = { str_to_int(val["section_data"]["matno"]): val for key, val in mass_elem.items() } mass_el: dict = mat_mass_map.get(matno, None) if mass_el is None: raise ValueError() ndof = str_to_int(d["ndof"]) if ndof != 6: raise NotImplementedError( "Only mass matrices with 6 DOF are currently supported for reading" ) r = [float(x) for x in d["bulk"].split()] A = np.matrix([ [r[0], 0.0, 0.0, 0.0, 0.0, 0.0], [r[1], r[6], 0.0, 0.0, 0.0, 0.0], [r[2], r[7], r[11], 0.0, 0.0, 0.0], [r[3], r[8], r[12], r[15], 0.0, 0.0], [r[4], r[9], r[13], r[16], r[18], 0.0], [r[5], r[10], r[14], r[17], r[19], r[20]], ]) # use symmetry to complete the 6x6 matrix mass_matrix_6x6 = np.tril(A) + np.triu(A.T, 1) nodeno = str_to_int(mass_el["gelmnt"].get("nids")) elno = str_to_int(mass_el["gelmnt"].get("elno")) no = fem.nodes.from_id(nodeno) fem_set = fem.sets.add( FemSet(f"m{nodeno}", [no], FemSet.TYPES.NSET, parent=fem)) mass_type = Mass.PTYPES.ANISOTROPIC mass = Mass(f"m{nodeno}", fem_set, mass_matrix_6x6, Mass.TYPES.MASS, ptype=mass_type, parent=fem, mass_id=elno) mass_el["el"] = mass return mass
def get_femsets(m, set_map, parent) -> FemSet: d = m.groupdict() isref = str_to_int(d["isref"]) fem_set = FemSet( d["set_name"].strip(), set_map[isref][0], set_map[isref][1], parent=parent, ) return fem_set
def get_hinges(match): d = match.groupdict() fixno = str_to_int(d["fixno"]) opt = str_to_int(d["opt"]) trano = str_to_int(d["trano"]) a1 = str_to_int(d["a1"]) a2 = str_to_int(d["a2"]) a3 = str_to_int(d["a3"]) a4 = str_to_int(d["a4"]) a5 = str_to_int(d["a5"]) try: a6 = str_to_int(d["a6"]) except BaseException as e: logging.debug(e) a6 = 0 pass return fixno, (opt, trano, a1, a2, a3, a4, a5, a6)
def get_flatbar(match, sect_names, fem) -> Section: d = match.groupdict() sec_id = str_to_int(d["geono"]) return Section( name=sect_names[sec_id], sec_id=sec_id, sec_type=Section.TYPES.FLATBAR, h=roundoff(d["hz"]), w_top=roundoff(d["bt"]), w_btn=roundoff(d["bb"]), genprops=GeneralProperties(Sfy=float(d["sfy"]), Sfz=float(d["sfz"])), parent=fem.parent, )
def get_mat(match, mat_names, part) -> Material: d = match.groupdict() matno = str_to_int(d["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_y=roundoff(d["yield"]), ) return Material(name=mat_names[matno], mat_id=matno, mat_model=mat_model, parent=part)
def get_tubular_section(match, sect_names, fem) -> Section: d = match.groupdict() sec_id = str_to_int(d["geono"]) if sec_id not in sect_names: sec_name = f"TUB{sec_id}" else: sec_name = sect_names[sec_id] t = d["t"] if d["t"] is not None else (d["dy"] - d["di"]) / 2 return Section( name=sec_name, sec_id=sec_id, sec_type=Section.TYPES.TUBULAR, r=roundoff(float(d["dy"]) / 2), wt=roundoff(t), genprops=GeneralProperties(Sfy=float(d["sfy"]), Sfz=float(d["sfz"])), parent=fem.parent, )
def get_isection(match, sect_names, fem) -> Section: d = match.groupdict() sec_id = str_to_int(d["geono"]) name = sect_names[sec_id] return Section( name=name, sec_id=sec_id, sec_type=Section.TYPES.IPROFILE, h=roundoff(d["hz"]), t_w=roundoff(d["ty"]), w_top=roundoff(d["bt"]), w_btn=roundoff(d["bb"]), t_ftop=roundoff(d["tt"]), t_fbtn=roundoff(d["tb"]), genprops=GeneralProperties(Sfy=float(d["sfy"]), Sfz=float(d["sfz"])), parent=fem.parent, )
def grab_elements(match, fem: "FEM"): d = match.groupdict() eltype = d["eltype"] if eltype in ("CONN3D2", ): logging.info(f'Importing Connector type "{eltype}"') if eltype in ("MASS", "ROTARYI"): logging.info(f'Importing Mass type "{eltype}"') ada_el_type = abaqus_el_type_to_ada(eltype) elset = d["elset"] el_type_members_str = d["members"] res = re.search("[a-zA-Z]", el_type_members_str) is_cubic = ada_el_type in [so.HEX20, so.HEX27] if is_cubic or res is None: if is_cubic is True: elem_nodes_str = el_type_members_str.splitlines() ntext = "".join([ l1.strip() + " " + l2.strip() + "\n" for l1, l2 in zip(elem_nodes_str[:-1:2], elem_nodes_str[1::2]) ]) else: ntext = d["members"] res = np.fromstring(ntext.replace("\n", ","), sep=",", dtype=int) n = ElemShape.num_nodes(ada_el_type) + 1 return numpy_array_to_list_of_elements( res.reshape(int(res.size / n), n), eltype, elset, ada_el_type, fem) else: elems = [] for li in el_type_members_str.splitlines(): elem_nodes_str = li.split(",") elid = str_to_int(elem_nodes_str[0]) elem_nodes = get_elem_nodes(elem_nodes_str, fem) elem = Elem(elid, elem_nodes, ada_el_type, elset, el_formulation_override=eltype, parent=fem) elems.append(elem) return elems
def find_bnmass(match) -> Mass: d = match.groupdict() nodeno = str_to_int(d["nodeno"]) mass_in = [ roundoff(d["m1"]), roundoff(d["m2"]), roundoff(d["m3"]), roundoff(d["m4"]), roundoff(d["m5"]), roundoff(d["m6"]), ] masses = [m for m in mass_in if m != 0.0] if checkEqual2(masses): mass_type = Mass.PTYPES.ISOTROPIC masses = [masses[0]] if len(masses) > 0 else [0.0] else: mass_type = Mass.PTYPES.ANISOTROPIC no = fem.nodes.from_id(nodeno) fem_set = fem.sets.add( FemSet(f"m{nodeno}", [no], FemSet.TYPES.NSET, parent=fem)) el_id = fem.elements.max_el_id + 1 elem = fem.elements.add( Elem(el_id, [no], Elem.EL_TYPES.MASS_SHAPES.MASS, None, parent=fem)) mass = Mass(f"m{nodeno}", fem_set, masses, Mass.TYPES.MASS, ptype=mass_type, parent=fem, mass_id=el_id) elset = fem.sets.add( FemSet(f"m{nodeno}", [elem], FemSet.TYPES.ELSET, parent=fem)) elem.mass_props = mass elem.elset = elset return mass
def get_node(m, parent): d = m.groupdict() return Node([float(d["x"]), float(d["y"]), float(d["z"])], str_to_int(d["id"]), parent=parent)
def get_nodeno(m_gnod): d = m_gnod.groupdict() return str_to_int(d["nodex"]), str_to_int(d["nodeno"])
def get_section_names(m): d = m.groupdict() return str_to_int(d["geono"]), d["set_name"].strip()
def get_constraints_from_inp(bulk_str: str, fem: FEM) -> Dict[str, Constraint]: """ ** Constraint: Container_RigidBody *Rigid Body, ref node=container_rp, elset=container *MPC BEAM, 2007, 161 BEAM, 2008, 162 """ # Rigid Bodies constraints = [] rbnames = Counter(1, "rgb") conames = Counter(1, "co") for m in cards.tie.regex.finditer(bulk_str): d = m.groupdict() name = d["name"] msurf = get_set_from_assembly(d["surf1"], fem, "surface") ssurf = get_set_from_assembly(d["surf2"], fem, "surface") constraints.append( Constraint(name, Constraint.TYPES.TIE, msurf, ssurf, metadata=dict(adjust=d["adjust"]))) for m in cards.rigid_bodies.regex.finditer(bulk_str): d = m.groupdict() name = next(rbnames) ref_node = get_set_from_assembly(d["ref_node"], fem, FemSet.TYPES.NSET) elset = get_set_from_assembly(d["elset"], fem, FemSet.TYPES.ELSET) constraints.append( Constraint(name, Constraint.TYPES.RIGID_BODY, ref_node, elset, parent=fem)) couplings = [] for m in cards.coupling.regex.finditer(bulk_str): d = m.groupdict() name = d["constraint_name"] rn = d["ref_node"].strip() sf = d["surface"].strip() if rn.isnumeric(): ref_set = FemSet(next(conames), [fem.nodes.from_id(int(rn))], FemSet.TYPES.NSET, parent=fem) fem.sets.add(ref_set) else: ref_set = fem.nsets[rn] surf = fem.surfaces[sf] res = np.fromstring(list_cleanup(d["bulk"]), sep=",", dtype=int) size = res.size cols = 2 rows = int(size / cols) dofs = res.reshape(rows, cols) csys_name = d.get("orientation", None) if csys_name is not None: if csys_name not in fem.lcsys.keys(): raise ValueError( f'Csys "{csys_name}" was not found on part {fem}') csys = fem.lcsys[csys_name] else: csys = None couplings.append( Constraint(name, Constraint.TYPES.COUPLING, ref_set, surf, csys=csys, dofs=dofs, parent=fem)) # Shell to Solid Couplings sh2solids = [] for m in cards.sh2so_re.regex.finditer(bulk_str): d = m.groupdict() name = d["constraint_name"] influence = d["influence_distance"] surf1 = get_set_from_assembly(d["surf1"], fem, "surface") surf2 = get_set_from_assembly(d["surf2"], fem, "surface") sh2solids.append( Constraint(name, Constraint.TYPES.SHELL2SOLID, surf1, surf2, influence_distance=influence)) # MPC's mpc_dict = dict() mpc_re = re.compile(r"\*mpc\n(?P<bulk>.*?)^\*", _re_in) mpc_content = re.compile( r"\s*(?P<mpc_type>.*?),\s*(?P<master>.*?),\s*(?P<slave>.*?)$", _re_in) for match in mpc_re.finditer(bulk_str): d1 = match.groupdict() for subm in mpc_content.finditer(d1["bulk"]): d = subm.groupdict() mpc_type = d["mpc_type"] m = d["master"] s = d["slave"] if mpc_type not in mpc_dict.keys(): mpc_dict[mpc_type] = [] try: n1_ = str_to_int(m) except BaseException as e: logging.debug(e) n1_ = get_set_from_assembly(m, fem, FemSet.TYPES.NSET) try: n2_ = str_to_int(s) except BaseException as e: logging.debug(e) n2_ = get_set_from_assembly(s, fem, FemSet.TYPES.NSET) mpc_dict[mpc_type].append((n1_, n2_)) def get_mpc(mpc_values): m_set, s_set = zip(*mpc_values) mpc_name = mpc_type + "_mpc" mset = FemSet("mpc_" + mpc_type + "_m", m_set, FemSet.TYPES.NSET) sset = FemSet("mpc_" + mpc_type + "_s", s_set, FemSet.TYPES.NSET) return Constraint(mpc_name, Constraint.TYPES.MPC, mset, sset, mpc_type=mpc_type, parent=fem) mpcs = [get_mpc(mpc_values_in) for mpc_values_in in mpc_dict.values()] return { c.name: c for c in chain.from_iterable([constraints, couplings, sh2solids, mpcs]) }
def grab_name(m): d = m.groupdict() return str_to_int(d["geo_no"]), d["name"]