Skip to content

Commit

Permalink
Updating documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
cmccomb committed Dec 29, 2023
1 parent 0d7c4ac commit 8173384
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 118 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
author="Christopher McComb",
author_email="[email protected]",
url="https://github.com/cmccomb/TrussMe",
install_requires=["numpy", "pandas", "tabulate"],
install_requires=["numpy", "pandas", "tabulate", "matplotlib"],
packages=find_packages(exclude="tests"),
)
2 changes: 1 addition & 1 deletion trussme/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@


class Shape(abc.ABC):
"""Abstract base class for shapes"""
"""Abstract base class for shapes, only ever used for typehints."""

@abc.abstractmethod
def __init__(self):
Expand Down
61 changes: 33 additions & 28 deletions trussme/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,53 @@
import trussme.visualize


def generate_summary(the_truss) -> str:
def generate_summary(truss) -> str:
"""
Generate a summary of the analysis.
:param the_truss: The truss to be summarized
:type the_truss: Truss
:return: A string containing the summary
:rtype: str
Parameters
----------
truss: Truss
The truss to be summarized
Returns
-------
str
A string containing the summary
"""
summary = "# SUMMARY OF ANALYSIS\n"
summary += (
"- The truss has a mass of "
+ format(the_truss.mass, ".2f")
+ format(truss.mass, ".2f")
+ " kg, and a total factor of safety of "
+ format(the_truss.fos_total, ".2f")
+ format(truss.fos_total, ".2f")
+ ".\n"
)
summary += "- The limit state is " + the_truss.limit_state + ".\n"
summary += "- The limit state is " + truss.limit_state + ".\n"

success_string = []
failure_string = []
if the_truss.minimum_fos_total < the_truss.fos_total:
if truss.minimum_fos_total < truss.fos_total:
success_string.append("total FOS")
else:
failure_string.append("total FOS")

if the_truss.minimum_fos_buckling < the_truss.fos_buckling:
if truss.minimum_fos_buckling < truss.fos_buckling:
success_string.append("buckling FOS")
else:
failure_string.append("buckling FOS")

if the_truss.minimum_fos_yielding < the_truss.fos_yielding:
if truss.minimum_fos_yielding < truss.fos_yielding:
success_string.append("yielding FOS")
else:
failure_string.append("yielding FOS")

if the_truss.maximum_mass > the_truss.mass:
if truss.maximum_mass > truss.mass:
success_string.append("mass")
else:
failure_string.append("mass")

if the_truss.maximum_deflection > the_truss.deflection:
if truss.maximum_deflection > truss.deflection:
success_string.append("deflection")
else:
failure_string.append("deflection")
Expand Down Expand Up @@ -101,37 +106,37 @@ def generate_summary(the_truss) -> str:
]
data.append(
[
the_truss.minimum_fos_total,
the_truss.fos_total,
"Yes" if the_truss.fos_total > the_truss.minimum_fos_total else "No",
truss.minimum_fos_total,
truss.fos_total,
"Yes" if truss.fos_total > truss.minimum_fos_total else "No",
]
)
data.append(
[
the_truss.minimum_fos_buckling,
the_truss.fos_buckling,
"Yes" if the_truss.fos_buckling > the_truss.minimum_fos_buckling else "No",
truss.minimum_fos_buckling,
truss.fos_buckling,
"Yes" if truss.fos_buckling > truss.minimum_fos_buckling else "No",
]
)
data.append(
[
the_truss.minimum_fos_yielding,
the_truss.fos_yielding,
"Yes" if the_truss.fos_yielding > the_truss.minimum_fos_yielding else "No",
truss.minimum_fos_yielding,
truss.fos_yielding,
"Yes" if truss.fos_yielding > truss.minimum_fos_yielding else "No",
]
)
data.append(
[
the_truss.maximum_mass,
the_truss.mass,
"Yes" if the_truss.mass < the_truss.maximum_mass else "No",
truss.maximum_mass,
truss.mass,
"Yes" if truss.mass < truss.maximum_mass else "No",
]
)
data.append(
[
the_truss.maximum_deflection,
the_truss.deflection,
"Yes" if the_truss.deflection < the_truss.maximum_deflection else "No",
truss.maximum_deflection,
truss.deflection,
"Yes" if truss.deflection < truss.maximum_deflection else "No",
]
)

Expand Down
146 changes: 64 additions & 82 deletions trussme/truss.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,12 @@ class Truss(object):
Attributes
----------
number_of_members
number_of_joints
mass
fos_yielding
fos_buckling
fos_total
deflection
members: list[Member]
A list of all members in the truss
joints: list[Joint]
A list of all joints in the truss
goals: Goals
A container of goals for truss design
"""

def __init__(self):
Expand All @@ -73,98 +72,53 @@ def __init__(self):

@property
def number_of_members(self) -> int:
"""Number of members in the truss, updated automatically
Returns
-------
int
"""
"""int: Number of members in the truss"""
return len(self.members)

@property
def number_of_joints(self) -> int:
"""Number of joints in the truss, updated automatically
Returns
-------
int
"""
"""int: Number of joints in the truss"""
return len(self.joints)

@property
def mass(self) -> float:
"""Total mass of the truss, updated automatically
Returns
-------
float
"""
"""float: Total mass of the truss"""
mass = 0
for m in self.members:
mass += m.mass
return mass

@property
def fos_yielding(self) -> float:
"""Smallest yielding FOS in the truss
Returns
-------
float
"""
"""float: Smallest yielding FOS of any member in the truss"""
return min([m.fos_yielding for m in self.members])

@property
def fos_buckling(self) -> float:
"""Smallest buckling FOS in the truss
Returns
-------
float
"""
"""float: Smallest buckling FOS of any member in the truss"""
return min(
[m.fos_buckling if m.fos_buckling > 0 else 10000 for m in self.members]
)

@property
def fos_total(self) -> float:
"""Smallest FOS in the truss
Returns
-------
float
"""
"""float: Smallest FOS of any member in the truss"""
return min(self.fos_buckling, self.fos_yielding)

@property
def deflection(self) -> float:
"""Largest single joint deflection in the truss
Returns
-------
float
"""
"""float: Largest single joint deflection in the truss"""
return max([numpy.linalg.norm(joint.deflections) for joint in self.joints])

@property
def materials(self) -> list[Material]:
"""List of unique materials used in the truss
Returns
-------
list[Material]
"""
"""list[Material]: List of unique materials used in the truss"""
material_library: list[Material] = [member.material for member in self.members]
return list({v["name"]: v for v in material_library}.values())

@property
def limit_state(self) -> Literal["buckling", "yielding"]:
"""The limit state of the truss, either "buckling" or "yielding"
Returns
-------
Literal["buckling", "yielding"]
"""
"""Literal["buckling", "yielding"]: The limit state of the truss, either "buckling" or "yielding" """
if self.fos_buckling < self.fos_yielding:
return "buckling"
else:
Expand Down Expand Up @@ -304,10 +258,7 @@ def calc_fos(self):

@property
def report(self) -> str:
"""
:return: A string containing a full report on the truss
:rtype: str
"""
"""str: A full report on the truss"""
self.calc_fos()

report_string = report.generate_summary(self) + "\n"
Expand All @@ -319,19 +270,31 @@ def report(self) -> str:
def report_to_md(self, file_name: str) -> None:
"""
Writes a report in Markdown format
:param file_name: A string with the name of the file
:type file_name: str
:return: None
Parameters
----------
file_name: str
The name of the file
Returns
-------
None
"""
with open(file_name, "w") as f:
f.write(self.report)

def to_json(self, file_name: str) -> None:
"""
Saves the truss to a JSON file
:param file_name: The filename to use for the truss file
:type file_name: str
:return: None
Parameters
----------
file_name: str
The filename to use for the JSON file
Returns
-------
None
"""

class JointEncoder(json.JSONEncoder):
Expand Down Expand Up @@ -379,10 +342,17 @@ def default(self, obj):
def to_trs(self, file_name: str) -> None:
"""
Saves the truss to a .trs file
:param file_name: The filename to use for the truss file
:type file_name: str
:return: None
Parameters
----------
file_name: str
The filename to use for the truss file
Returns
-------
None
"""

with open(file_name, "w") as f:
# Do materials
for material in self.materials:
Expand Down Expand Up @@ -457,10 +427,16 @@ def to_trs(self, file_name: str) -> None:
def read_trs(file_name: str) -> Truss:
"""
Read a .trs file and return a Truss object
:param file_name: The name of the .trs file to be read
:type file_name: str
:return: The object loaded from the .trs file
:rtype: Truss
Parameters
----------
file_name: str
The name of the .trs file to be read
Returns
-------
Truss
The object loaded from the .trs file
"""
truss = Truss()
material_library: list[Material] = []
Expand Down Expand Up @@ -519,10 +495,16 @@ def read_trs(file_name: str) -> Truss:
def read_json(file_name: str) -> Truss:
"""
Read a JSON file and return a Truss object
:param file_name: The name of the JSON file to be read
:type file_name: str
:return: The object loaded from the JSON file
:rtype: Truss
Parameters
----------
file_name: str
The name of the JSON file to be read
Returns
-------
Truss
The object loaded from the JSON file
"""
json_truss = json.load(open(file_name))

Expand Down
Loading

0 comments on commit 8173384

Please sign in to comment.