Skip to content

Commit

Permalink
Code cleanup with black
Browse files Browse the repository at this point in the history
  • Loading branch information
cmccomb committed Dec 17, 2023
1 parent 6a53250 commit c52de3c
Show file tree
Hide file tree
Showing 7 changed files with 417 additions and 144 deletions.
18 changes: 9 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
from setuptools import setup, find_packages

with open('README.md') as f:
with open("README.md") as f:
readme = f.read()

with open('LICENSE') as f:
with open("LICENSE") as f:
license = f.read()

setup(
name='trussme',
version='0.0.1',
description='Truss construction and analysis',
name="trussme",
version="0.0.1",
description="Truss construction and analysis",
long_description=readme,
license=license,
author='Christopher McComb',
author_email='[email protected]',
url='https://github.com/cmccomb/TrussMe',
author="Christopher McComb",
author_email="[email protected]",
url="https://github.com/cmccomb/TrussMe",
install_requires=["numpy", "pandas", "tabulate"],
packages=find_packages(exclude='tests')
packages=find_packages(exclude="tests"),
)
35 changes: 19 additions & 16 deletions tests/test_truss.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

import trussme

TEST_TRUSS_FILENAME = os.path.join(os.path.dirname(__file__), 'example.trs')
TEST_TRUSS_FILENAME = os.path.join(os.path.dirname(__file__), "example.trs")


class TestSequenceFunctions(unittest.TestCase):

def test_build_methods(self):
# Build truss from scratch
t1 = trussme.Truss()
Expand Down Expand Up @@ -64,17 +63,19 @@ def test_build_methods(self):
t2.maximum_deflection = 6e-3

# Save reports
t1.save_report(os.path.join(os.path.dirname(__file__), 'report_1.md'))
t2.save_report(os.path.join(os.path.dirname(__file__), 'report_2.md'))
t1.save_report(os.path.join(os.path.dirname(__file__), "report_1.md"))
t2.save_report(os.path.join(os.path.dirname(__file__), "report_2.md"))

# Test for sameness
file_are_the_same = filecmp.cmp(os.path.join(os.path.dirname(__file__), 'report_1.md'),
os.path.join(os.path.dirname(__file__), 'report_2.md'))
file_are_the_same = filecmp.cmp(
os.path.join(os.path.dirname(__file__), "report_1.md"),
os.path.join(os.path.dirname(__file__), "report_2.md"),
)
self.assertTrue(file_are_the_same)

# Clean up
os.remove(os.path.join(os.path.dirname(__file__), 'report_1.md'))
os.remove(os.path.join(os.path.dirname(__file__), 'report_2.md'))
os.remove(os.path.join(os.path.dirname(__file__), "report_1.md"))
os.remove(os.path.join(os.path.dirname(__file__), "report_2.md"))

def test_save_and_rebuild(self):
# Build truss from file
Expand All @@ -85,26 +86,28 @@ def test_save_and_rebuild(self):
t2.maximum_deflection = 6e-3

# Save
t2.save_report(os.path.join(os.path.dirname(__file__), 'report_2.md'))
t2.save_truss(os.path.join(os.path.dirname(__file__), 'asdf.trs'))
t2.save_report(os.path.join(os.path.dirname(__file__), "report_2.md"))
t2.save_truss(os.path.join(os.path.dirname(__file__), "asdf.trs"))

# Rebuild
t3 = trussme.read_trs(os.path.join(os.path.dirname(__file__), 'asdf.trs'))
t3 = trussme.read_trs(os.path.join(os.path.dirname(__file__), "asdf.trs"))
t3.minimum_fos_buckling = 1.5
t3.min_fos_yielding = 1.5
t3.max_mass = 5.0
t3.maximum_deflection = 6e-3

t3.save_report(os.path.join(os.path.dirname(__file__), 'report_3.md'))
t3.save_report(os.path.join(os.path.dirname(__file__), "report_3.md"))

with open(os.path.join(os.path.dirname(__file__), 'report_3.md')) as f:
with open(os.path.join(os.path.dirname(__file__), "report_3.md")) as f:
print(f.read())
with open(os.path.join(os.path.dirname(__file__), 'report_2.md')) as f:
with open(os.path.join(os.path.dirname(__file__), "report_2.md")) as f:
print(f.read())

# Test for sameness
file_are_the_same = filecmp.cmp(os.path.join(os.path.dirname(__file__), 'report_3.md'),
os.path.join(os.path.dirname(__file__), 'report_2.md'))
file_are_the_same = filecmp.cmp(
os.path.join(os.path.dirname(__file__), "report_3.md"),
os.path.join(os.path.dirname(__file__), "report_2.md"),
)
self.assertTrue(file_are_the_same)


Expand Down
2 changes: 1 addition & 1 deletion trussme/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .truss import Truss, read_trs
from .components import MATERIALS, Shape, Material, Box, Pipe, Bar, Square
from .truss import Truss, read_trs
72 changes: 54 additions & 18 deletions trussme/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,37 @@
# Gravitational constant for computing weight from mass
g: float = 9.80665

Material = TypedDict("Material", {"name": str, "density": float, "elastic_modulus": float, "yield_strength": float, })
Material = TypedDict(
"Material",
{
"name": str,
"density": float,
"elastic_modulus": float,
"yield_strength": float,
},
)

# Material properties
MATERIALS: list[Material] = [
{"name": "A36_Steel", "density": 7800.0, "elastic_modulus": 200 * pow(10, 9), "yield_strength": 250 * pow(10, 6)},
{"name": "A992_Steel", "density": 7800.0, "elastic_modulus": 200 * pow(10, 9), "yield_strength": 345 * pow(10, 6)},
{"name": "6061_T6_Aluminum", "density": 2700.0, "elastic_modulus": 68.9 * pow(10, 9),
"yield_strength": 276 * pow(10, 6)}]
{
"name": "A36_Steel",
"density": 7800.0,
"elastic_modulus": 200 * pow(10, 9),
"yield_strength": 250 * pow(10, 6),
},
{
"name": "A992_Steel",
"density": 7800.0,
"elastic_modulus": 200 * pow(10, 9),
"yield_strength": 345 * pow(10, 6),
},
{
"name": "6061_T6_Aluminum",
"density": 2700.0,
"elastic_modulus": 68.9 * pow(10, 9),
"yield_strength": 276 * pow(10, 6),
},
]


class Shape(abc.ABC):
Expand Down Expand Up @@ -45,10 +68,10 @@ def __init__(self, r: float = 0.0, t: float = 0.0):
self.h = None

def moi(self) -> float:
return (numpy.pi / 4.) * (self.r ** 4 - (self.r - 2 * self.t) ** 4)
return (numpy.pi / 4.0) * (self.r**4 - (self.r - 2 * self.t) ** 4)

def area(self) -> float:
return numpy.pi * (self.r ** 2 - (self.r - self.t) ** 2)
return numpy.pi * (self.r**2 - (self.r - self.t) ** 2)

def name(self) -> str:
return "pipe"
Expand All @@ -62,10 +85,10 @@ def __init__(self, r: float = 0.0):
self.t = None

def moi(self) -> float:
return (numpy.pi / 4.) * self.r ** 4
return (numpy.pi / 4.0) * self.r**4

def area(self) -> float:
return numpy.pi * self.r ** 2
return numpy.pi * self.r**2

def name(self) -> str:
return "bar"
Expand All @@ -80,9 +103,9 @@ def __init__(self, w: float = 0.0, h: float = 0.0):

def moi(self) -> float:
if self.h > self.w:
return (1. / 12.) * self.w * self.h ** 3
return (1.0 / 12.0) * self.w * self.h**3
else:
return (1. / 12.) * self.h * self.w ** 3
return (1.0 / 12.0) * self.h * self.w**3

def area(self) -> float:
return self.w * self.h
Expand All @@ -100,9 +123,13 @@ def __init__(self, w: float = 0.0, h: float = 0.0, t: float = 0.0):

def moi(self) -> float:
if self.h > self.w:
return (1. / 12.) * (self.w * self.h ** 3) - (1. / 12.) * (self.w - 2 * self.t) * (self.h - 2 * self.t) ** 3
return (1.0 / 12.0) * (self.w * self.h**3) - (1.0 / 12.0) * (
self.w - 2 * self.t
) * (self.h - 2 * self.t) ** 3
else:
return (1. / 12.) * (self.h * self.w ** 3) - (1. / 12.) * (self.h - 2 * self.t) * (self.w - 2 * self.t) ** 3
return (1.0 / 12.0) * (self.h * self.w**3) - (1.0 / 12.0) * (
self.h - 2 * self.t
) * (self.w - 2 * self.t) ** 3

def area(self) -> float:
return self.w * self.h - (self.h - 2 * self.t) * (self.w - 2 * self.t)
Expand All @@ -112,7 +139,6 @@ def name(self) -> str:


class Joint(object):

def __init__(self, coordinates: list[float]):
# Save the joint id
self.idx: int = 0
Expand Down Expand Up @@ -145,7 +171,7 @@ def pinned(self):
# Restrict all translation
self.translation = [True, True, True]

def roller(self, axis: Literal["x", "y"] = 'y', d: int = 3):
def roller(self, axis: Literal["x", "y"] = "y", d: int = 3):
# Only support reaction along denoted axis
self.translation = [False, False, False]
self.translation[ord(axis) - 120] = True
Expand All @@ -156,7 +182,6 @@ def roller(self, axis: Literal["x", "y"] = 'y', d: int = 3):


class Member(object):

def __init__(self, begin_joint: Joint, end_joint: Joint):
# Save id number
self.idx: int = 0
Expand Down Expand Up @@ -211,7 +236,10 @@ def linear_weight(self) -> float:

@property
def length(self) -> float:
return numpy.linalg.norm(numpy.array(self.begin_joint.coordinates) - numpy.array(self.end_joint.coordinates))
return numpy.linalg.norm(
numpy.array(self.begin_joint.coordinates)
- numpy.array(self.end_joint.coordinates)
)

@property
def mass(self) -> float:
Expand All @@ -231,4 +259,12 @@ def fos_yielding(self) -> float:

@property
def fos_buckling(self) -> float:
return -((numpy.pi ** 2) * self.elastic_modulus * self.moment_of_inertia / (self.length ** 2)) / self.force
return (
-(
(numpy.pi**2)
* self.elastic_modulus
* self.moment_of_inertia
/ (self.length**2)
)
/ self.force
)
54 changes: 42 additions & 12 deletions trussme/evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,30 @@
import numpy
from numpy.typing import NDArray

TrussInfo = TypedDict("TrussInfo", {"coordinates": numpy.ndarray, "connections": numpy.ndarray, "loads": numpy.ndarray,
"reactions": numpy.ndarray, "area": numpy.ndarray, "elastic_modulus": numpy.ndarray})
TrussInfo = TypedDict(
"TrussInfo",
{
"coordinates": numpy.ndarray,
"connections": numpy.ndarray,
"loads": numpy.ndarray,
"reactions": numpy.ndarray,
"area": numpy.ndarray,
"elastic_modulus": numpy.ndarray,
},
)


def the_forces(truss_info: TrussInfo) -> tuple[NDArray[float], NDArray[float], NDArray[float], float]:
print(truss_info['area'])
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)])
[
numpy.size(truss_info["reactions"], axis=0),
numpy.size(truss_info["reactions"], axis=1),
]
)
dof: numpy.ndarray = numpy.zeros([3 * w[1], 3 * w[1]])
deflections: numpy.ndarray = numpy.ones(w)
deflections -= truss_info["reactions"]
Expand All @@ -22,15 +37,25 @@ def the_forces(truss_info: TrussInfo) -> tuple[NDArray[float], NDArray[float], N
# Build the global stiffness matrix
for i in range(numpy.size(truss_info["connections"], axis=1)):
ends = truss_info["connections"][:, i]
length_vector = truss_info["coordinates"][:, ends[1]] - truss_info["coordinates"][:, ends[0]]
length_vector = (
truss_info["coordinates"][:, ends[1]]
- truss_info["coordinates"][:, ends[0]]
)
length = numpy.linalg.norm(length_vector)
direction = length_vector / length
d2 = numpy.outer(direction, direction)
ea_over_l = truss_info["elastic_modulus"][i] * truss_info["area"][i] / length
ss = ea_over_l * numpy.concatenate((numpy.concatenate((d2, -d2), axis=1), numpy.concatenate((-d2, d2), axis=1)),
axis=0)
ss = ea_over_l * numpy.concatenate(
(
numpy.concatenate((d2, -d2), axis=1),
numpy.concatenate((-d2, d2), axis=1),
),
axis=0,
)
tj[:, i] = ea_over_l * direction
e = list(range((3 * ends[0]), (3 * ends[0] + 3))) + list(range((3 * ends[1]), (3 * ends[1] + 3)))
e = list(range((3 * ends[0]), (3 * ends[0] + 3))) + list(
range((3 * ends[1]), (3 * ends[1] + 3))
)
for ii in range(6):
for j in range(6):
dof[e[ii], e[j]] += ss[ii, j]
Expand All @@ -46,9 +71,14 @@ def the_forces(truss_info: TrussInfo) -> tuple[NDArray[float], NDArray[float], N
ff = numpy.where(deflections.T == 1)
for i in range(len(ff[0])):
deflections[ff[1][i], ff[0][i]] = flat_deflections[i]
forces = numpy.sum(numpy.multiply(tj, deflections[:, truss_info["connections"][1, :]] - deflections[:,
truss_info["connections"][0,
:]]), axis=0)
forces = numpy.sum(
numpy.multiply(
tj,
deflections[:, truss_info["connections"][1, :]]
- deflections[:, truss_info["connections"][0, :]],
),
axis=0,
)

# Check the condition number, and warn the user if it is out of range
cond = numpy.linalg.cond(SSff)
Expand Down
Loading

0 comments on commit c52de3c

Please sign in to comment.