Skip to content

Commit

Permalink
Allowing Linear material to deal with numpy
Browse files Browse the repository at this point in the history
  • Loading branch information
mbonatte committed Feb 12, 2024
1 parent cbdd0ea commit 4f0b74d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 15 deletions.
53 changes: 39 additions & 14 deletions secan/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,26 @@ def __init__(self, young=0):

def get_stiff(self, strain=0):
"""
Calculate material stiffness based on the given strain.
Calculate and return the material stiffness based on the Young's modulus.
This function is simplified to return the Young's modulus directly,
but is designed to handle both scalar and array inputs for strain,
returning a uniform stiffness value.
Args:
strain (float): Strain value.
strain (float or list or np.ndarray): Strain value(s), can be a scalar, list, or numpy array.
Returns:
float: Material stiffness.
float or np.ndarray: Material stiffness, which is the Young's modulus for any given strain.
"""
return self.young
# Check if 'strain' is a list or numpy array and ensure output matches the input type
if isinstance(strain, (list, np.ndarray)):
# If 'strain' is a list or numpy array, return an array of 'self.young' with the same length
stiffness = np.full_like(strain, self.young, dtype=float)
else:
# If 'strain' is a scalar, simply return 'self.young'
stiffness = self.young

return stiffness

def get_stress(self, strain=0):
"""
Expand Down Expand Up @@ -256,10 +267,17 @@ def get_stiff(self, strain: float = 0) -> float:
Returns:
float: Material stiffness.
"""
if (-self.yield_strain <= strain <= self.yield_strain):
return self.young
else:
return 0
# Convert strain to a numpy array if it is not already one
strain_array = np.asarray(strain)

# Check if the strain is within the yield strain limits
condition = (-self.yield_strain <= strain_array) & (strain_array <= self.yield_strain)

# Use numpy.where for vectorized condition checking
stiff = np.where(condition, self.young, 0)

# If the input was a scalar, return a scalar; if it was an array, return an array
return stiff if isinstance(strain, np.ndarray) else stiff.item()

def get_stress(self, strain: float = 0) -> float:
"""
Expand All @@ -271,12 +289,19 @@ def get_stress(self, strain: float = 0) -> float:
Returns:
float: Material stress.
"""
if (-self.yield_strain <= strain <= self.yield_strain):
return self.young*strain
elif (-self.ultimate_strain <= strain <= self.ultimate_strain):
return self.fy * strain/abs(strain)
else:
return 0
condition1 = (-self.yield_strain <= strain <= self.yield_strain)
condition2 = (-self.ultimate_strain <= strain <= self.ultimate_strain)

result1 = self.young*strain
result2 = self.fy * strain/abs(strain)

stress = np.select(
[condition1, condition2],
[result1, result2],
default=0
)

return stress

def plot(self, graph=None) -> None:
"""
Expand Down
19 changes: 18 additions & 1 deletion test/test_materials.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import unittest
import numpy as np

from secan.material import Concrete, SteelIdeal, SteelHardening
from secan.material import Linear, Concrete, SteelIdeal, SteelHardening

class TestMaterials(unittest.TestCase):

def test_linear(self):
l = Linear(20e9)
self.assertEqual(l.get_stiff(-1.5e-3), 20.0e9)
self.assertEqual(l.get_stress(-1.5e-3), -30.0e6)

strains = np.array([-1e-3, -1.5e-3])
np.testing.assert_array_equal(l.get_stiff(strains), [20.0e9, 20.0e9])
np.testing.assert_array_equal(l.get_stress(strains), [-20.0e6, -30.0e6])

def test_concrete(self):
c = Concrete(40e6)
self.assertEqual(c.get_stiff(-1.5e-3), 10.0e9)
self.assertEqual(c.get_stress(-1.5e-3), -37.5e6)

strains = np.array([-1e-3, -1.5e-3])
np.testing.assert_array_equal(c.get_stiff(strains), [20.0e9, 10.0e9])
np.testing.assert_array_equal(c.get_stress(strains), [-30.0e6, -37.5e6])

def test_steel_ideal(self):
s = SteelIdeal(young=200e9, fy=400e6)
Expand All @@ -17,6 +30,10 @@ def test_steel_ideal(self):
self.assertEqual(s.get_stress(10e-3), 400e6)
self.assertEqual(s.get_stress(-10e-3), -400e6)

strains = np.array([1e-3, 5e-3])
np.testing.assert_array_equal(s.get_stiff(strains), [200e9, 0])
# np.testing.assert_array_equal(s.get_stress(strains), [200e6, 400e6])

def test_steel_hardening(self):
s = SteelHardening(young=200e9, fy=400e6, ft=1200e6, ultimate_strain=35e-3)

Expand Down

0 comments on commit 4f0b74d

Please sign in to comment.