-
Notifications
You must be signed in to change notification settings - Fork 3
Tensile Strength Evaluation as part of Steady State Analysis #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f2201a0
d9fda65
0102a08
b4b72ad
ab27c4a
d25fa03
50797e9
59dd3a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,4 +56,7 @@ scratch/ | |
| temp* | ||
| old* | ||
|
|
||
| .weac-reference/ | ||
| .weac-reference/ | ||
|
|
||
| # Folder for development and local testing | ||
| dev/ | ||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -214,7 +214,7 @@ def get_zmesh(self, dz=2): | |||||||||||||||||||||||||||||||||
| ], # Convert to t/mm^3 | ||||||||||||||||||||||||||||||||||
| "tensile_strength": [ | ||||||||||||||||||||||||||||||||||
| layer.tensile_strength for layer in self.sm.slab.layers | ||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||
| ], # in kPa | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Repeat properties for each grid point in the layer | ||||||||||||||||||||||||||||||||||
|
|
@@ -225,7 +225,7 @@ def get_zmesh(self, dz=2): | |||||||||||||||||||||||||||||||||
| return si | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @track_analyzer_call | ||||||||||||||||||||||||||||||||||
| def Sxx(self, Z, phi, dz=2, unit="kPa"): | ||||||||||||||||||||||||||||||||||
| def Sxx(self, Z, phi, dz=2, unit="kPa", normalize: bool = False): | ||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||
| Compute axial normal stress in slab layers. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
@@ -239,6 +239,10 @@ def Sxx(self, Z, phi, dz=2, unit="kPa"): | |||||||||||||||||||||||||||||||||
| Element size along z-axis (mm). Default is 2 mm. | ||||||||||||||||||||||||||||||||||
| unit : {'kPa', 'MPa'}, optional | ||||||||||||||||||||||||||||||||||
| Desired output unit. Default is 'kPa'. | ||||||||||||||||||||||||||||||||||
| normalize : bool, optional | ||||||||||||||||||||||||||||||||||
| Toggle normalization. If True, normalize stress values to the tensile strength of each layer (dimensionless). | ||||||||||||||||||||||||||||||||||
| When normalized, the `unit` parameter is ignored and values are returned as ratios. | ||||||||||||||||||||||||||||||||||
| Default is False. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Returns | ||||||||||||||||||||||||||||||||||
| ------- | ||||||||||||||||||||||||||||||||||
|
|
@@ -258,13 +262,13 @@ def Sxx(self, Z, phi, dz=2, unit="kPa"): | |||||||||||||||||||||||||||||||||
| m = Z.shape[1] | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Initialize axial normal stress Sxx | ||||||||||||||||||||||||||||||||||
| Sxx = np.zeros(shape=[n, m]) | ||||||||||||||||||||||||||||||||||
| Sxx_MPa = np.zeros(shape=[n, m]) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Compute axial normal stress Sxx at grid points in MPa | ||||||||||||||||||||||||||||||||||
| for i, z in enumerate(zi): | ||||||||||||||||||||||||||||||||||
| E = zmesh["E"][i] | ||||||||||||||||||||||||||||||||||
| E_MPa = zmesh["E"][i] | ||||||||||||||||||||||||||||||||||
| nu = zmesh["nu"][i] | ||||||||||||||||||||||||||||||||||
| Sxx[i, :] = E / (1 - nu**2) * self.sm.fq.du_dx(Z, z) | ||||||||||||||||||||||||||||||||||
| Sxx_MPa[i, :] = E_MPa / (1 - nu**2) * self.sm.fq.du_dx(Z, z) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Calculate weight load at grid points and superimpose on stress field | ||||||||||||||||||||||||||||||||||
| qt = -rho * G_MM_S2 * np.sin(np.deg2rad(phi)) | ||||||||||||||||||||||||||||||||||
|
|
@@ -274,14 +278,22 @@ def Sxx(self, Z, phi, dz=2, unit="kPa"): | |||||||||||||||||||||||||||||||||
| # Sxx[-1, :] += qt[-1] * (zi[-1] - zi[-2]) | ||||||||||||||||||||||||||||||||||
| # New Implementation: Changed for numerical stability | ||||||||||||||||||||||||||||||||||
| dz = np.diff(zi) | ||||||||||||||||||||||||||||||||||
| Sxx[:-1, :] += qt[:-1, np.newaxis] * dz[:, np.newaxis] | ||||||||||||||||||||||||||||||||||
| Sxx[-1, :] += qt[-1] * dz[-1] | ||||||||||||||||||||||||||||||||||
| Sxx_MPa[:-1, :] += qt[:-1, np.newaxis] * dz[:, np.newaxis] | ||||||||||||||||||||||||||||||||||
| Sxx_MPa[-1, :] += qt[-1] * dz[-1] | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Normalize tensile stresses to tensile strength | ||||||||||||||||||||||||||||||||||
| if normalize: | ||||||||||||||||||||||||||||||||||
| tensile_strength_kPa = zmesh["tensile_strength"] | ||||||||||||||||||||||||||||||||||
| tensile_strength_MPa = tensile_strength_kPa / 1e3 | ||||||||||||||||||||||||||||||||||
| # Normalize axial normal stress to layers' tensile strength | ||||||||||||||||||||||||||||||||||
| normalized_Sxx = Sxx_MPa / tensile_strength_MPa[:, None] | ||||||||||||||||||||||||||||||||||
| return normalized_Sxx | ||||||||||||||||||||||||||||||||||
|
pillowbeast marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Return axial normal stress in specified unit | ||||||||||||||||||||||||||||||||||
| return convert[unit] * Sxx | ||||||||||||||||||||||||||||||||||
| return convert[unit] * Sxx_MPa | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @track_analyzer_call | ||||||||||||||||||||||||||||||||||
| def Txz(self, Z, phi, dz=2, unit="kPa"): | ||||||||||||||||||||||||||||||||||
| def Txz(self, Z, phi, dz=2, unit="kPa", normalize: bool = False): | ||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||
| Compute shear stress in slab layers. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
@@ -295,6 +307,9 @@ def Txz(self, Z, phi, dz=2, unit="kPa"): | |||||||||||||||||||||||||||||||||
| Element size along z-axis (mm). Default is 2 mm. | ||||||||||||||||||||||||||||||||||
| unit : {'kPa', 'MPa'}, optional | ||||||||||||||||||||||||||||||||||
| Desired output unit. Default is 'kPa'. | ||||||||||||||||||||||||||||||||||
| normalize : bool, optional | ||||||||||||||||||||||||||||||||||
| Toggle normalization. If True, normalize shear stress values to the tensile strength of each layer (dimensionless). | ||||||||||||||||||||||||||||||||||
| When normalized, the `unit` parameter is ignored and values are returned as ratios. Default is False. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Returns | ||||||||||||||||||||||||||||||||||
| ------- | ||||||||||||||||||||||||||||||||||
|
|
@@ -332,14 +347,22 @@ def Txz(self, Z, phi, dz=2, unit="kPa"): | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Integrate -dsxx_dx along z and add cumulative weight load | ||||||||||||||||||||||||||||||||||
| # to obtain shear stress Txz in MPa | ||||||||||||||||||||||||||||||||||
| Txz = cumulative_trapezoid(dsxx_dx, zi, axis=0, initial=0) | ||||||||||||||||||||||||||||||||||
| Txz += cumulative_trapezoid(qt, zi, initial=0)[:, None] | ||||||||||||||||||||||||||||||||||
| Txz_MPa = cumulative_trapezoid(dsxx_dx, zi, axis=0, initial=0) | ||||||||||||||||||||||||||||||||||
| Txz_MPa += cumulative_trapezoid(qt, zi, initial=0)[:, None] | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Normalize shear stresses to tensile strength | ||||||||||||||||||||||||||||||||||
| if normalize: | ||||||||||||||||||||||||||||||||||
| tensile_strength_kPa = zmesh["tensile_strength"] | ||||||||||||||||||||||||||||||||||
| tensile_strength_MPa = tensile_strength_kPa / 1e3 | ||||||||||||||||||||||||||||||||||
| # Normalize shear stress to layers' tensile strength | ||||||||||||||||||||||||||||||||||
| normalized_Txz = Txz_MPa / tensile_strength_MPa[:, None] | ||||||||||||||||||||||||||||||||||
| return normalized_Txz | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+353
to
+359
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add guard against division by zero and clarify normalization approach. Two concerns:
Add the same guard as suggested for # Normalize shear stresses to tensile strength
if normalize:
tensile_strength_kPa = zmesh["tensile_strength"]
tensile_strength_MPa = tensile_strength_kPa / 1e3
+ if np.any(tensile_strength_MPa <= 0):
+ raise ValueError("Cannot normalize: tensile_strength must be positive for all layers.")
# Normalize shear stress to layers' tensile strength
normalized_Txz = Txz_MPa / tensile_strength_MPa[:, None]
return normalized_Txz📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Return shear stress Txz in specified unit | ||||||||||||||||||||||||||||||||||
| return convert[unit] * Txz | ||||||||||||||||||||||||||||||||||
| return convert[unit] * Txz_MPa | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @track_analyzer_call | ||||||||||||||||||||||||||||||||||
| def Szz(self, Z, phi, dz=2, unit="kPa"): | ||||||||||||||||||||||||||||||||||
| def Szz(self, Z, phi, dz=2, unit="kPa", normalize: bool = False): | ||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||
| Compute transverse normal stress in slab layers. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
@@ -353,6 +376,10 @@ def Szz(self, Z, phi, dz=2, unit="kPa"): | |||||||||||||||||||||||||||||||||
| Element size along z-axis (mm). Default is 2 mm. | ||||||||||||||||||||||||||||||||||
| unit : {'kPa', 'MPa'}, optional | ||||||||||||||||||||||||||||||||||
| Desired output unit. Default is 'kPa'. | ||||||||||||||||||||||||||||||||||
| normalize : bool, optional | ||||||||||||||||||||||||||||||||||
| Toggle normalization. If True, normalize stress values to the tensile strength of each layer (dimensionless). | ||||||||||||||||||||||||||||||||||
| When normalized, the `unit` parameter is ignored and values are returned as ratios. | ||||||||||||||||||||||||||||||||||
| Default is False. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Returns | ||||||||||||||||||||||||||||||||||
| ------- | ||||||||||||||||||||||||||||||||||
|
|
@@ -392,11 +419,19 @@ def Szz(self, Z, phi, dz=2, unit="kPa"): | |||||||||||||||||||||||||||||||||
| # Integrate dsxx_dxdx twice along z to obtain transverse | ||||||||||||||||||||||||||||||||||
| # normal stress Szz in MPa | ||||||||||||||||||||||||||||||||||
| integrand = cumulative_trapezoid(dsxx_dxdx, zi, axis=0, initial=0) | ||||||||||||||||||||||||||||||||||
| Szz = cumulative_trapezoid(integrand, zi, axis=0, initial=0) | ||||||||||||||||||||||||||||||||||
| Szz += cumulative_trapezoid(-qn, zi, initial=0)[:, None] | ||||||||||||||||||||||||||||||||||
| Szz_MPa = cumulative_trapezoid(integrand, zi, axis=0, initial=0) | ||||||||||||||||||||||||||||||||||
| Szz_MPa += cumulative_trapezoid(-qn, zi, initial=0)[:, None] | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Return shear stress txz in specified unit | ||||||||||||||||||||||||||||||||||
| return convert[unit] * Szz | ||||||||||||||||||||||||||||||||||
| # Normalize tensile stresses to tensile strength | ||||||||||||||||||||||||||||||||||
| if normalize: | ||||||||||||||||||||||||||||||||||
| tensile_strength_kPa = zmesh["tensile_strength"] | ||||||||||||||||||||||||||||||||||
| tensile_strength_MPa = tensile_strength_kPa / 1e3 | ||||||||||||||||||||||||||||||||||
| # Normalize transverse normal stress to layers' tensile strength | ||||||||||||||||||||||||||||||||||
| normalized_Szz = Szz_MPa / tensile_strength_MPa[:, None] | ||||||||||||||||||||||||||||||||||
| return normalized_Szz | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Return transverse normal stress Szz in specified unit | ||||||||||||||||||||||||||||||||||
| return convert[unit] * Szz_MPa | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| @track_analyzer_call | ||||||||||||||||||||||||||||||||||
| def principal_stress_slab( | ||||||||||||||||||||||||||||||||||
|
|
@@ -438,6 +473,8 @@ def principal_stress_slab( | |||||||||||||||||||||||||||||||||
| 'min', or if normalization of compressive principal stress | ||||||||||||||||||||||||||||||||||
| is requested. | ||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||
| convert = {"kPa": 1e3, "MPa": 1} | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Raise error if specified component is not available | ||||||||||||||||||||||||||||||||||
| if val not in ["min", "max"]: | ||||||||||||||||||||||||||||||||||
| raise ValueError(f"Component {val} not defined.") | ||||||||||||||||||||||||||||||||||
|
|
@@ -460,9 +497,10 @@ def principal_stress_slab( | |||||||||||||||||||||||||||||||||
| # Normalize tensile stresses to tensile strength | ||||||||||||||||||||||||||||||||||
| if normalize and val == "max": | ||||||||||||||||||||||||||||||||||
| zmesh = self.get_zmesh(dz=dz) | ||||||||||||||||||||||||||||||||||
| tensile_strength = zmesh["tensile_strength"] | ||||||||||||||||||||||||||||||||||
| tensile_strength_kPa = zmesh["tensile_strength"] | ||||||||||||||||||||||||||||||||||
| tensile_strength_converted = tensile_strength_kPa / 1e3 * convert[unit] | ||||||||||||||||||||||||||||||||||
| # Normalize maximum principal stress to layers' tensile strength | ||||||||||||||||||||||||||||||||||
| normalized_Ps = Ps / tensile_strength[:, None] | ||||||||||||||||||||||||||||||||||
| normalized_Ps = Ps / tensile_strength_converted[:, None] | ||||||||||||||||||||||||||||||||||
| return normalized_Ps | ||||||||||||||||||||||||||||||||||
|
Comment on lines
498
to
504
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add division by zero guard and consider simplifying normalization. Two issues:
Add guard: # Normalize tensile stresses to tensile strength
if normalize and val == "max":
zmesh = self.get_zmesh(dz=dz)
tensile_strength_kPa = zmesh["tensile_strength"]
tensile_strength_converted = tensile_strength_kPa / 1e3 * convert[unit]
+ if np.any(tensile_strength_converted <= 0):
+ raise ValueError("Cannot normalize: tensile_strength must be positive for all layers.")
# Normalize maximum principal stress to layers' tensile strength
normalized_Ps = Ps / tensile_strength_converted[:, None]
return normalized_Ps🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Return absolute principal stresses | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.