diff --git a/trussme/evaluate.py b/trussme/evaluate.py index 2154a41..61f97cb 100644 --- a/trussme/evaluate.py +++ b/trussme/evaluate.py @@ -15,6 +15,7 @@ def the_forces(truss_info: TrussInfo) -> tuple[NDArray[float], NDArray[float], NDArray[float], float]: + print(truss_info['area']) tj: numpy.ndarray = numpy.zeros([3, numpy.size(truss_info["connections"], axis=1)]) w: numpy.ndarray = numpy.array( [numpy.size(truss_info["reactions"], axis=0), numpy.size(truss_info["reactions"], axis=1)]) diff --git a/trussme/member.py b/trussme/member.py index 4863c30..3f52ce2 100644 --- a/trussme/member.py +++ b/trussme/member.py @@ -6,9 +6,11 @@ class Pipe(object): - def __init__(self, r: float, t: float): + def __init__(self, r: float = 0.0, t: float = 0.0): self.r: float = r self.t: float = t + self.w = "N/A" + self.h = "N/A" def moi(self) -> float: return (numpy.pi / 4.) * (self.r ** 4 - (self.r - 2 * self.t) ** 4) @@ -16,10 +18,16 @@ def moi(self) -> float: def area(self) -> float: return numpy.pi * (self.r ** 2 - (self.r - self.t) ** 2) + def to_str(self) -> str: + return "pipe" + class Bar(object): - def __init__(self, r: float): + def __init__(self, r: float = 0.0): self.r: float = r + self.w = "N/A" + self.h = "N/A" + self.t = "N/A" def moi(self) -> float: return (numpy.pi / 4.) * self.r ** 4 @@ -27,11 +35,16 @@ def moi(self) -> float: def area(self) -> float: return numpy.pi*self.r**2 + def to_str(self) -> str: + return "bar" + class Square(object): - def __init__(self, w: float, h: float): + def __init__(self, w: float = 0.0, h: float = 0.0): self.w: float = w self.h: float = h + self.t = "N/A" + self.r = "N/A" def moi(self) -> float: if self.h > self.w: @@ -42,11 +55,15 @@ def moi(self) -> float: def area(self) -> float: return self.w * self.h + def to_str(self) -> str: + return "square" + class Box(object): - def __init__(self, w: float, h: float, t: float): + def __init__(self, w: float = 0.0, h: float = 0.0, t: float = 0.0): self.w: float = w self.h: float = h self.t: float = t + self.r = "N/A" def moi(self) -> float: if self.h > self.w: @@ -59,25 +76,21 @@ def moi(self) -> float: def area(self) -> float: return self.w*self.h - (self.h - 2*self.t)*(self.w - 2*self.t) + def to_str(self) -> str: + return "box" + Shape = Union[Pipe, Bar, Square, Box, None] class Member(object): - # Shape types - shapes: list[str] = ["pipe", "bar", "square", "box"] - def __init__(self, joint_a: Joint, joint_b: Joint): # Save id number self.idx = -1 # Shape independent variables self.shape: Shape = None - self.t: float = 0.0 # thickness - self.w: float = 0.0 # outer width - self.h: float = 0.0 # outer height - self.r: float = 0.0 # outer radius # Material properties self.material: str = '' # string specifying material @@ -103,31 +116,11 @@ def __init__(self, joint_a: Joint, joint_b: Joint): self.end_b = [] # Calculate properties - self.set_shape("pipe", update_props=False) - self.set_material(MATERIALS[0], update_props=False) - self.set_parameters(t=0.002, r=0.02, update_props=True) - - def set_shape(self, new_shape: Literal["pipe", "bar", "square", "box"], update_props: bool = True): - # Read and save hte shape name - if self.shape_name_is_ok(new_shape): - self.shape = new_shape - else: - raise ValueError(new_shape+' is not a defined shape. Try ' + - ', '.join(self.shapes[0:-1]) + ', or ' + - self.shapes[-1] + '.') - - if self.shape is "pipe": - self.w = "N/A" - self.h = "N/A" - elif self.shape is "bar": - self.w = "N/A" - self.h = "N/A" - self.r = "N/A" - elif self.shape is "square": - self.r = "N/A" - self.t = "N/A" - elif self.shape is "box": - self.r = "N/A" + self.set_shape(Pipe(t=0.002, r=0.02), update_props=False) + self.set_material(MATERIALS[0], update_props=True) + + def set_shape(self, new_shape: Shape, update_props: bool = True): + self.shape = new_shape # If required, update properties if update_props: @@ -144,49 +137,6 @@ def set_material(self, new_material: Material, update_props: bool = True): if update_props: self.calc_properties() - def set_parameters(self, **kwargs): - prop_update = False - # Save the values - for key in kwargs.keys(): - if key is "radius": - self.r = kwargs["radius"] - elif key is "r": - self.r = kwargs["r"] - elif key is "thickness": - self.t = kwargs["thickness"] - elif key is "t": - self.t = kwargs["t"] - elif key is "width": - self.w = kwargs["width"] - elif key is "w": - self.w = kwargs["w"] - elif key is "height": - self.h = kwargs["height"] - elif key is "h": - self.h = kwargs["h"] - elif kwargs["update_props"]: - prop_update = True - else: - raise ValueError(key+' is not an defined shape. ' - 'Try thickness (t), width (w), ' - 'height (h), or radius (r).') - - # Check parameters - if self.shape == "pipe": - if self.t > self.r: - warnings.warn("Thickness is greater than radius." - "Changing shape to bar.") - if self.shape == "box": - if 2*self.t > self.w: - warnings.warn("Thickness is greater than half of width." - "Changing shape to square.") - elif 2*self.t > self.h: - warnings.warn("Thickness is greater than half of height." - "Changing shape to square.") - - if prop_update: - self.calc_properties() - def calc_properties(self): # Calculate moment of inertia self.calc_moi() @@ -201,32 +151,10 @@ def calc_properties(self): self.calc_geometry() def calc_moi(self): - if self.shape == "pipe": - self.I = (numpy.pi/4.)*(self.r**4 - (self.r - 2*self.t)**4) - elif self.shape == "bar": - self.I = (numpy.pi/4.)*self.r**4 - elif self.shape == "square": - if self.h > self.w: - self.I = (1./12.)*self.w*self.h**3 - else: - self.I = (1./12.)*self.h*self.w**3 - elif self.shape == "box": - if self.h > self.w: - self.I = (1./12.)*(self.w*self.h**3)\ - - (1./12.)*(self.w - 2*self.t)*(self.h - 2*self.t)**3 - else: - self.I = (1./12.)*(self.h*self.w**3)\ - - (1./12.)*(self.h - 2*self.t)*(self.w - 2*self.t)**3 + self.I = self.shape.moi() def calc_area(self): - if self.shape == "pipe": - self.area = numpy.pi*(self.r**2 - (self.r-self.t)**2) - elif self.shape == "bar": - self.area = numpy.pi*self.r**2 - elif self.shape == "box": - self.area = self.w*self.h - (self.h - 2*self.t)*(self.w - 2*self.t) - elif self.shape == "square": - self.area = self.w * self.h + self.area = self.shape.area() def calc_lw(self): self.LW = self.area * self.rho diff --git a/trussme/report.py b/trussme/report.py index 9377b5b..15ed16a 100644 --- a/trussme/report.py +++ b/trussme/report.py @@ -114,11 +114,11 @@ def print_instantiation_information(f, the_truss, verbose=False): data.append([str(m.joints[0].idx), str(m.joints[1].idx), m.material, - m.shape, - m.h, - m.w, - m.r, - m.t]) + m.shape.to_str(), + m.shape.h, + m.shape.w, + m.shape.r, + m.shape.t]) pw(f, pandas.DataFrame(data, index=rows, diff --git a/trussme/truss.py b/trussme/truss.py index 2e8f8ec..64c7eef 100644 --- a/trussme/truss.py +++ b/trussme/truss.py @@ -1,7 +1,7 @@ import numpy from numpy.typing import NDArray from trussme.joint import Joint -from trussme.member import Member +from trussme.member import Member, Pipe, Box, Square, Bar from trussme import report from trussme import evaluate from trussme.physical_properties import g, Material, MATERIALS @@ -239,15 +239,15 @@ def save_truss(self, file_name: str = ""): + str(m.joints[0].idx) + "\t" + str(m.joints[1].idx) + "\t" + m.material + "\t" - + m.shape + "\t") - if m.t != "N/A": - f.write("t=" + str(m.t) + "\t") - if m.r != "N/A": - f.write("r=" + str(m.r) + "\t") - if m.w != "N/A": - f.write("w=" + str(m.w) + "\t") - if m.h != "N/A": - f.write("h=" + str(m.h) + "\t") + + m.shape.to_str() + "\t") + if str(m.shape.t) != "N/A": + f.write("t=" + str(m.shape.t) + "\t") + if str(m.shape.r) != "N/A": + f.write("r=" + str(m.shape.r) + "\t") + if str(m.shape.w) != "N/A": + f.write("w=" + str(m.shape.w) + "\t") + if str(m.shape.h) != "N/A": + f.write("h=" + str(m.shape.h) + "\t") f.write("\n") # Do the loads @@ -279,7 +279,6 @@ def read_trs(file_name: str) -> Truss: truss.add_member(int(info[0]), int(info[1])) material = next(item for item in truss.materials if item["name"] == info[2]) truss.members[-1].set_material(material) - truss.members[-1].set_shape(info[3]) # Parse parameters ks = [] @@ -288,7 +287,9 @@ def read_trs(file_name: str) -> Truss: kvpair = info[param].split("=") ks.append(kvpair[0]) vs.append(float(kvpair[1])) - truss.members[-1].set_parameters(**dict(zip(ks, vs))) + shape = eval(str(info[3]).title())(**dict(zip(ks, vs))) + truss.members[-1].set_shape(shape) + elif line[0] is "L": info = line.split()[1:] truss.joints[int(info[0])].loads[0] = float(info[1])