Skip to content

Commit

Permalink
Reasonable shape solution achieved!
Browse files Browse the repository at this point in the history
  • Loading branch information
cmccomb committed Dec 15, 2023
1 parent 85e10e5 commit c1b7362
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 120 deletions.
1 change: 1 addition & 0 deletions trussme/evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)])
Expand Down
134 changes: 31 additions & 103 deletions trussme/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,45 @@


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)

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

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:
Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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()
Expand All @@ -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
Expand Down
10 changes: 5 additions & 5 deletions trussme/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
25 changes: 13 additions & 12 deletions trussme/truss.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 = []
Expand All @@ -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])
Expand Down

0 comments on commit c1b7362

Please sign in to comment.