weac 3.0.1__tar.gz → 3.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. {weac-3.0.1 → weac-3.1.0}/CITATION.cff +1 -1
  2. {weac-3.0.1/src/weac.egg-info → weac-3.1.0}/PKG-INFO +105 -8
  3. {weac-3.0.1 → weac-3.1.0}/README.md +101 -6
  4. {weac-3.0.1 → weac-3.1.0}/pyproject.toml +3 -5
  5. {weac-3.0.1 → weac-3.1.0}/src/weac/__init__.py +1 -1
  6. {weac-3.0.1 → weac-3.1.0}/src/weac/analysis/__init__.py +2 -2
  7. {weac-3.0.1 → weac-3.1.0}/src/weac/analysis/analyzer.py +57 -19
  8. {weac-3.0.1 → weac-3.1.0}/src/weac/analysis/criteria_evaluator.py +130 -37
  9. {weac-3.0.1 → weac-3.1.0}/src/weac/analysis/plotter.py +402 -49
  10. {weac-3.0.1 → weac-3.1.0}/src/weac/components/model_input.py +3 -4
  11. {weac-3.0.1 → weac-3.1.0}/src/weac/core/eigensystem.py +21 -21
  12. {weac-3.0.1 → weac-3.1.0}/src/weac/core/scenario.py +7 -7
  13. {weac-3.0.1 → weac-3.1.0}/src/weac/core/slab.py +2 -4
  14. {weac-3.0.1 → weac-3.1.0}/src/weac/core/slab_touchdown.py +3 -3
  15. {weac-3.0.1 → weac-3.1.0}/src/weac/core/system_model.py +8 -9
  16. {weac-3.0.1 → weac-3.1.0}/src/weac/core/unknown_constants_solver.py +11 -14
  17. {weac-3.0.1 → weac-3.1.0}/src/weac/logging_config.py +1 -2
  18. {weac-3.0.1 → weac-3.1.0}/src/weac/utils/snowpilot_parser.py +12 -13
  19. {weac-3.0.1 → weac-3.1.0/src/weac.egg-info}/PKG-INFO +105 -8
  20. {weac-3.0.1 → weac-3.1.0}/src/weac.egg-info/requires.txt +4 -1
  21. {weac-3.0.1 → weac-3.1.0}/tests/analysis/test_analyzer.py +36 -0
  22. {weac-3.0.1 → weac-3.1.0}/tests/analysis/test_criteria_evaluator.py +12 -6
  23. {weac-3.0.1 → weac-3.1.0}/tests/test_regression_simulation.py +5 -5
  24. {weac-3.0.1 → weac-3.1.0}/tests/utils/weac_reference_runner.py +5 -5
  25. {weac-3.0.1 → weac-3.1.0}/LICENSE +0 -0
  26. {weac-3.0.1 → weac-3.1.0}/MANIFEST.in +0 -0
  27. {weac-3.0.1 → weac-3.1.0}/img/bc.png +0 -0
  28. {weac-3.0.1 → weac-3.1.0}/img/layering.png +0 -0
  29. {weac-3.0.1 → weac-3.1.0}/img/logo.png +0 -0
  30. {weac-3.0.1 → weac-3.1.0}/img/model.png +0 -0
  31. {weac-3.0.1 → weac-3.1.0}/img/profiles.png +0 -0
  32. {weac-3.0.1 → weac-3.1.0}/img/systems.png +0 -0
  33. {weac-3.0.1 → weac-3.1.0}/setup.cfg +0 -0
  34. {weac-3.0.1 → weac-3.1.0}/src/weac/components/__init__.py +0 -0
  35. {weac-3.0.1 → weac-3.1.0}/src/weac/components/config.py +0 -0
  36. {weac-3.0.1 → weac-3.1.0}/src/weac/components/criteria_config.py +0 -0
  37. {weac-3.0.1 → weac-3.1.0}/src/weac/components/layer.py +0 -0
  38. {weac-3.0.1 → weac-3.1.0}/src/weac/components/scenario_config.py +0 -0
  39. {weac-3.0.1 → weac-3.1.0}/src/weac/components/segment.py +0 -0
  40. {weac-3.0.1 → weac-3.1.0}/src/weac/constants.py +0 -0
  41. {weac-3.0.1 → weac-3.1.0}/src/weac/core/__init__.py +0 -0
  42. {weac-3.0.1 → weac-3.1.0}/src/weac/core/field_quantities.py +0 -0
  43. {weac-3.0.1 → weac-3.1.0}/src/weac/utils/__init__.py +0 -0
  44. {weac-3.0.1 → weac-3.1.0}/src/weac/utils/geldsetzer.py +0 -0
  45. {weac-3.0.1 → weac-3.1.0}/src/weac/utils/misc.py +0 -0
  46. {weac-3.0.1 → weac-3.1.0}/src/weac/utils/snow_types.py +0 -0
  47. {weac-3.0.1 → weac-3.1.0}/src/weac.egg-info/SOURCES.txt +0 -0
  48. {weac-3.0.1 → weac-3.1.0}/src/weac.egg-info/dependency_links.txt +0 -0
  49. {weac-3.0.1 → weac-3.1.0}/src/weac.egg-info/top_level.txt +0 -0
  50. {weac-3.0.1 → weac-3.1.0}/tests/__init__.py +0 -0
  51. {weac-3.0.1 → weac-3.1.0}/tests/analysis/__init__.py +0 -0
  52. {weac-3.0.1 → weac-3.1.0}/tests/components/__init__.py +0 -0
  53. {weac-3.0.1 → weac-3.1.0}/tests/components/test_configs.py +0 -0
  54. {weac-3.0.1 → weac-3.1.0}/tests/components/test_layer.py +0 -0
  55. {weac-3.0.1 → weac-3.1.0}/tests/core/__init__.py +0 -0
  56. {weac-3.0.1 → weac-3.1.0}/tests/core/test_eigensystem.py +0 -0
  57. {weac-3.0.1 → weac-3.1.0}/tests/core/test_field_quantities.py +0 -0
  58. {weac-3.0.1 → weac-3.1.0}/tests/core/test_scenario.py +0 -0
  59. {weac-3.0.1 → weac-3.1.0}/tests/core/test_slab.py +0 -0
  60. {weac-3.0.1 → weac-3.1.0}/tests/core/test_slab_touchdown.py +0 -0
  61. {weac-3.0.1 → weac-3.1.0}/tests/core/test_system_model.py +0 -0
  62. {weac-3.0.1 → weac-3.1.0}/tests/run_tests.py +0 -0
  63. {weac-3.0.1 → weac-3.1.0}/tests/test_comparison_results.py +0 -0
  64. {weac-3.0.1 → weac-3.1.0}/tests/utils/__init__.py +0 -0
  65. {weac-3.0.1 → weac-3.1.0}/tests/utils/json_helpers.py +0 -0
  66. {weac-3.0.1 → weac-3.1.0}/tests/utils/test_json_helpers.py +0 -0
  67. {weac-3.0.1 → weac-3.1.0}/tests/utils/test_misc.py +0 -0
  68. {weac-3.0.1 → weac-3.1.0}/tests/utils/test_snowpilot_parser.py +0 -0
@@ -8,7 +8,7 @@ authors:
8
8
  - family-names: "Weissgraeber"
9
9
  given-names: "Philipp"
10
10
  orcid: "https://orcid.org/0000-0001-8320-8672"
11
- version: 3.0.1
11
+ version: 3.1.0
12
12
  date-released: 2021-12-30
13
13
  identifiers:
14
14
  - description: Collection of archived snapshots of all versions of WEAC
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weac
3
- Version: 3.0.1
3
+ Version: 3.1.0
4
4
  Summary: Weak layer anticrack nucleation model
5
5
  Author-email: 2phi GbR <mail@2phi.de>
6
6
  License-Expression: MIT
@@ -35,6 +35,9 @@ Requires-Dist: traitlets>=5.14.3; extra == "interactive"
35
35
  Provides-Extra: docs
36
36
  Requires-Dist: sphinx; extra == "docs"
37
37
  Requires-Dist: sphinxawesome-theme; extra == "docs"
38
+ Provides-Extra: build
39
+ Requires-Dist: build; extra == "build"
40
+ Requires-Dist: twine; extra == "build"
38
41
  Provides-Extra: dev
39
42
  Requires-Dist: nbclient>=0.10.0; extra == "dev"
40
43
  Requires-Dist: nbconvert>=7.16.4; extra == "dev"
@@ -55,7 +58,6 @@ Requires-Dist: pycodestyle>=2.11.1; extra == "dev"
55
58
  Requires-Dist: black>=24.4.0; extra == "dev"
56
59
  Requires-Dist: isort>=5.13.0; extra == "dev"
57
60
  Requires-Dist: bump-my-version; extra == "dev"
58
- Requires-Dist: build; extra == "dev"
59
61
  Dynamic: license-file
60
62
 
61
63
  <!-- LOGO AND TITLE-->
@@ -128,12 +130,13 @@ Dynamic: license-file
128
130
 
129
131
  1. [About the project](#about-the-project)
130
132
  2. [Installation](#installation)
131
- 3. [Usage](#usage)
132
- 4. [Roadmap](#roadmap)
133
- 5. [Release history](#release-history)
134
- 6. [How to contribute](#how-to-contribute)
135
- 7. [License](#license)
136
- 8. [Contact](#contact)
133
+ 3. [Development Setup](#development-setup)
134
+ 4. [Usage](#usage)
135
+ 5. [Roadmap](#roadmap)
136
+ 6. [Release history](#release-history)
137
+ 7. [How to contribute](#how-to-contribute)
138
+ 8. [License](#license)
139
+ 9. [Contact](#contact)
137
140
 
138
141
  <!-- ABOUT THE PROJECT -->
139
142
  ## About the project
@@ -189,6 +192,100 @@ Needs (runtime dependencies are declared in [pyproject.toml](https://github.com/
189
192
  - [Snowpylot](https://github.com/connellymk/snowpylot) ≥ 1.1.3
190
193
 
191
194
 
195
+ <!-- DEVELOPMENT SETUP -->
196
+ ## Development Setup
197
+
198
+ This project uses [uv](https://github.com/astral-sh/uv) for fast Python package management and project handling.
199
+
200
+ ### Installing uv
201
+
202
+ Install uv following the [official installation guide](https://github.com/astral-sh/uv#installation):
203
+
204
+ ```bash
205
+ # On macOS and Linux
206
+ curl -LsSf https://astral.sh/uv/install.sh | sh
207
+
208
+ # Using pip (alternative)
209
+ pip install uv
210
+ ```
211
+
212
+ ### Setting up the development environment
213
+
214
+ Clone the repository and set up the development environment:
215
+
216
+ ```bash
217
+ git clone https://github.com/2phi/weac
218
+ cd weac
219
+
220
+ # Install Python 3.12+ if not already available
221
+ # uv will automatically use the version specified in .python-version
222
+
223
+ # For basic setup (if only running the package):
224
+ uv sync
225
+
226
+ # For development (recommended for contributors):
227
+ uv sync --extra dev
228
+
229
+ # Activate the virtual environment
230
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
231
+ ```
232
+
233
+ ### Running tests
234
+
235
+ Run the test suite using uv:
236
+
237
+ ```bash
238
+ # Run all tests
239
+ uv run python tests/run_tests.py
240
+
241
+ # Or use pytest directly (if installed)
242
+ uv run pytest
243
+ ```
244
+
245
+ ### Code formatting and linting
246
+
247
+ This project uses [ruff](https://github.com/astral-sh/ruff) for fast Python linting and formatting:
248
+
249
+ ```bash
250
+ # Format code
251
+ uv run ruff format .
252
+
253
+ # Check for linting issues
254
+ uv run ruff check .
255
+
256
+ # Fix auto-fixable linting issues
257
+ uv run ruff check . --fix
258
+ ```
259
+
260
+ ### Building the package
261
+
262
+ Build the package for distribution:
263
+
264
+ ```bash
265
+ # Build wheel and source distribution
266
+ uv build
267
+
268
+ # Install in editable mode for development
269
+ uv pip install -e .
270
+ ```
271
+
272
+ ### Additional uv commands
273
+
274
+ ```bash
275
+ # Update dependencies
276
+ uv sync --upgrade
277
+
278
+ # Add a new dependency
279
+ uv add package-name
280
+
281
+ # Add a development dependency
282
+ uv add --dev package-name
283
+
284
+ # Show environment info
285
+ uv run python --version
286
+ uv run pip list
287
+ ```
288
+
192
289
  <!-- USAGE EXAMPLES -->
193
290
  ## Usage
194
291
 
@@ -68,12 +68,13 @@
68
68
 
69
69
  1. [About the project](#about-the-project)
70
70
  2. [Installation](#installation)
71
- 3. [Usage](#usage)
72
- 4. [Roadmap](#roadmap)
73
- 5. [Release history](#release-history)
74
- 6. [How to contribute](#how-to-contribute)
75
- 7. [License](#license)
76
- 8. [Contact](#contact)
71
+ 3. [Development Setup](#development-setup)
72
+ 4. [Usage](#usage)
73
+ 5. [Roadmap](#roadmap)
74
+ 6. [Release history](#release-history)
75
+ 7. [How to contribute](#how-to-contribute)
76
+ 8. [License](#license)
77
+ 9. [Contact](#contact)
77
78
 
78
79
  <!-- ABOUT THE PROJECT -->
79
80
  ## About the project
@@ -129,6 +130,100 @@ Needs (runtime dependencies are declared in [pyproject.toml](https://github.com/
129
130
  - [Snowpylot](https://github.com/connellymk/snowpylot) ≥ 1.1.3
130
131
 
131
132
 
133
+ <!-- DEVELOPMENT SETUP -->
134
+ ## Development Setup
135
+
136
+ This project uses [uv](https://github.com/astral-sh/uv) for fast Python package management and project handling.
137
+
138
+ ### Installing uv
139
+
140
+ Install uv following the [official installation guide](https://github.com/astral-sh/uv#installation):
141
+
142
+ ```bash
143
+ # On macOS and Linux
144
+ curl -LsSf https://astral.sh/uv/install.sh | sh
145
+
146
+ # Using pip (alternative)
147
+ pip install uv
148
+ ```
149
+
150
+ ### Setting up the development environment
151
+
152
+ Clone the repository and set up the development environment:
153
+
154
+ ```bash
155
+ git clone https://github.com/2phi/weac
156
+ cd weac
157
+
158
+ # Install Python 3.12+ if not already available
159
+ # uv will automatically use the version specified in .python-version
160
+
161
+ # For basic setup (if only running the package):
162
+ uv sync
163
+
164
+ # For development (recommended for contributors):
165
+ uv sync --extra dev
166
+
167
+ # Activate the virtual environment
168
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
169
+ ```
170
+
171
+ ### Running tests
172
+
173
+ Run the test suite using uv:
174
+
175
+ ```bash
176
+ # Run all tests
177
+ uv run python tests/run_tests.py
178
+
179
+ # Or use pytest directly (if installed)
180
+ uv run pytest
181
+ ```
182
+
183
+ ### Code formatting and linting
184
+
185
+ This project uses [ruff](https://github.com/astral-sh/ruff) for fast Python linting and formatting:
186
+
187
+ ```bash
188
+ # Format code
189
+ uv run ruff format .
190
+
191
+ # Check for linting issues
192
+ uv run ruff check .
193
+
194
+ # Fix auto-fixable linting issues
195
+ uv run ruff check . --fix
196
+ ```
197
+
198
+ ### Building the package
199
+
200
+ Build the package for distribution:
201
+
202
+ ```bash
203
+ # Build wheel and source distribution
204
+ uv build
205
+
206
+ # Install in editable mode for development
207
+ uv pip install -e .
208
+ ```
209
+
210
+ ### Additional uv commands
211
+
212
+ ```bash
213
+ # Update dependencies
214
+ uv sync --upgrade
215
+
216
+ # Add a new dependency
217
+ uv add package-name
218
+
219
+ # Add a development dependency
220
+ uv add --dev package-name
221
+
222
+ # Show environment info
223
+ uv run python --version
224
+ uv run pip list
225
+ ```
226
+
132
227
  <!-- USAGE EXAMPLES -->
133
228
  ## Usage
134
229
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "weac"
7
- version = "3.0.1"
7
+ version = "3.1.0"
8
8
  authors = [{ name = "2phi GbR", email = "mail@2phi.de" }]
9
9
  description = "Weak layer anticrack nucleation model"
10
10
  readme = "README.md"
@@ -46,6 +46,7 @@ interactive = [
46
46
  "traitlets>=5.14.3",
47
47
  ]
48
48
  docs = ["sphinx", "sphinxawesome-theme"]
49
+ build = ["build", "twine"]
49
50
  dev = [
50
51
  # Notebook execution (to run demo.ipynb non-interactively)
51
52
  "nbclient>=0.10.0",
@@ -73,9 +74,6 @@ dev = [
73
74
 
74
75
  # Versioning helper matching [tool.bumpversion]
75
76
  "bump-my-version", # e.g. bump-my-version bump patch
76
-
77
- # Building for Testing
78
- "build",
79
77
  ]
80
78
 
81
79
  [tool.setuptools]
@@ -125,7 +123,7 @@ ignore = [
125
123
  ]
126
124
 
127
125
  [tool.bumpversion]
128
- current_version = "3.0.1"
126
+ current_version = "3.1.0"
129
127
 
130
128
  [[tool.bumpversion.files]]
131
129
  filename = "pyproject.toml"
@@ -2,4 +2,4 @@
2
2
  WEAC - Weak Layer Anticrack Nucleation Model
3
3
  """
4
4
 
5
- __version__ = "3.0.1"
5
+ __version__ = "3.1.0"
@@ -8,7 +8,7 @@ from .criteria_evaluator import (
8
8
  CoupledCriterionResult,
9
9
  CriteriaEvaluator,
10
10
  FindMinimumForceResult,
11
- SSERRResult,
11
+ SteadyStateResult,
12
12
  )
13
13
  from .plotter import Plotter
14
14
 
@@ -18,6 +18,6 @@ __all__ = [
18
18
  "CoupledCriterionHistory",
19
19
  "CoupledCriterionResult",
20
20
  "FindMinimumForceResult",
21
- "SSERRResult",
21
+ "SteadyStateResult",
22
22
  "Plotter",
23
23
  ]
@@ -214,7 +214,7 @@ class Analyzer:
214
214
  ], # Convert to t/mm^3
215
215
  "tensile_strength": [
216
216
  layer.tensile_strength for layer in self.sm.slab.layers
217
- ],
217
+ ], # in kPa
218
218
  }
219
219
 
220
220
  # Repeat properties for each grid point in the layer
@@ -225,7 +225,7 @@ class Analyzer:
225
225
  return si
226
226
 
227
227
  @track_analyzer_call
228
- def Sxx(self, Z, phi, dz=2, unit="kPa"):
228
+ def Sxx(self, Z, phi, dz=2, unit="kPa", normalize: bool = False):
229
229
  """
230
230
  Compute axial normal stress in slab layers.
231
231
 
@@ -239,6 +239,10 @@ class Analyzer:
239
239
  Element size along z-axis (mm). Default is 2 mm.
240
240
  unit : {'kPa', 'MPa'}, optional
241
241
  Desired output unit. Default is 'kPa'.
242
+ normalize : bool, optional
243
+ Toggle normalization. If True, normalize stress values to the tensile strength of each layer (dimensionless).
244
+ When normalized, the `unit` parameter is ignored and values are returned as ratios.
245
+ Default is False.
242
246
 
243
247
  Returns
244
248
  -------
@@ -258,13 +262,13 @@ class Analyzer:
258
262
  m = Z.shape[1]
259
263
 
260
264
  # Initialize axial normal stress Sxx
261
- Sxx = np.zeros(shape=[n, m])
265
+ Sxx_MPa = np.zeros(shape=[n, m])
262
266
 
263
267
  # Compute axial normal stress Sxx at grid points in MPa
264
268
  for i, z in enumerate(zi):
265
- E = zmesh["E"][i]
269
+ E_MPa = zmesh["E"][i]
266
270
  nu = zmesh["nu"][i]
267
- Sxx[i, :] = E / (1 - nu**2) * self.sm.fq.du_dx(Z, z)
271
+ Sxx_MPa[i, :] = E_MPa / (1 - nu**2) * self.sm.fq.du_dx(Z, z)
268
272
 
269
273
  # Calculate weight load at grid points and superimpose on stress field
270
274
  qt = -rho * G_MM_S2 * np.sin(np.deg2rad(phi))
@@ -274,14 +278,22 @@ class Analyzer:
274
278
  # Sxx[-1, :] += qt[-1] * (zi[-1] - zi[-2])
275
279
  # New Implementation: Changed for numerical stability
276
280
  dz = np.diff(zi)
277
- Sxx[:-1, :] += qt[:-1, np.newaxis] * dz[:, np.newaxis]
278
- Sxx[-1, :] += qt[-1] * dz[-1]
281
+ Sxx_MPa[:-1, :] += qt[:-1, np.newaxis] * dz[:, np.newaxis]
282
+ Sxx_MPa[-1, :] += qt[-1] * dz[-1]
283
+
284
+ # Normalize tensile stresses to tensile strength
285
+ if normalize:
286
+ tensile_strength_kPa = zmesh["tensile_strength"]
287
+ tensile_strength_MPa = tensile_strength_kPa / 1e3
288
+ # Normalize axial normal stress to layers' tensile strength
289
+ normalized_Sxx = Sxx_MPa / tensile_strength_MPa[:, None]
290
+ return normalized_Sxx
279
291
 
280
292
  # Return axial normal stress in specified unit
281
- return convert[unit] * Sxx
293
+ return convert[unit] * Sxx_MPa
282
294
 
283
295
  @track_analyzer_call
284
- def Txz(self, Z, phi, dz=2, unit="kPa"):
296
+ def Txz(self, Z, phi, dz=2, unit="kPa", normalize: bool = False):
285
297
  """
286
298
  Compute shear stress in slab layers.
287
299
 
@@ -295,6 +307,9 @@ class Analyzer:
295
307
  Element size along z-axis (mm). Default is 2 mm.
296
308
  unit : {'kPa', 'MPa'}, optional
297
309
  Desired output unit. Default is 'kPa'.
310
+ normalize : bool, optional
311
+ Toggle normalization. If True, normalize shear stress values to the tensile strength of each layer (dimensionless).
312
+ When normalized, the `unit` parameter is ignored and values are returned as ratios. Default is False.
298
313
 
299
314
  Returns
300
315
  -------
@@ -332,14 +347,22 @@ class Analyzer:
332
347
 
333
348
  # Integrate -dsxx_dx along z and add cumulative weight load
334
349
  # to obtain shear stress Txz in MPa
335
- Txz = cumulative_trapezoid(dsxx_dx, zi, axis=0, initial=0)
336
- Txz += cumulative_trapezoid(qt, zi, initial=0)[:, None]
350
+ Txz_MPa = cumulative_trapezoid(dsxx_dx, zi, axis=0, initial=0)
351
+ Txz_MPa += cumulative_trapezoid(qt, zi, initial=0)[:, None]
352
+
353
+ # Normalize shear stresses to tensile strength
354
+ if normalize:
355
+ tensile_strength_kPa = zmesh["tensile_strength"]
356
+ tensile_strength_MPa = tensile_strength_kPa / 1e3
357
+ # Normalize shear stress to layers' tensile strength
358
+ normalized_Txz = Txz_MPa / tensile_strength_MPa[:, None]
359
+ return normalized_Txz
337
360
 
338
361
  # Return shear stress Txz in specified unit
339
- return convert[unit] * Txz
362
+ return convert[unit] * Txz_MPa
340
363
 
341
364
  @track_analyzer_call
342
- def Szz(self, Z, phi, dz=2, unit="kPa"):
365
+ def Szz(self, Z, phi, dz=2, unit="kPa", normalize: bool = False):
343
366
  """
344
367
  Compute transverse normal stress in slab layers.
345
368
 
@@ -353,6 +376,10 @@ class Analyzer:
353
376
  Element size along z-axis (mm). Default is 2 mm.
354
377
  unit : {'kPa', 'MPa'}, optional
355
378
  Desired output unit. Default is 'kPa'.
379
+ normalize : bool, optional
380
+ Toggle normalization. If True, normalize stress values to the tensile strength of each layer (dimensionless).
381
+ When normalized, the `unit` parameter is ignored and values are returned as ratios.
382
+ Default is False.
356
383
 
357
384
  Returns
358
385
  -------
@@ -392,11 +419,19 @@ class Analyzer:
392
419
  # Integrate dsxx_dxdx twice along z to obtain transverse
393
420
  # normal stress Szz in MPa
394
421
  integrand = cumulative_trapezoid(dsxx_dxdx, zi, axis=0, initial=0)
395
- Szz = cumulative_trapezoid(integrand, zi, axis=0, initial=0)
396
- Szz += cumulative_trapezoid(-qn, zi, initial=0)[:, None]
422
+ Szz_MPa = cumulative_trapezoid(integrand, zi, axis=0, initial=0)
423
+ Szz_MPa += cumulative_trapezoid(-qn, zi, initial=0)[:, None]
397
424
 
398
- # Return shear stress txz in specified unit
399
- return convert[unit] * Szz
425
+ # Normalize tensile stresses to tensile strength
426
+ if normalize:
427
+ tensile_strength_kPa = zmesh["tensile_strength"]
428
+ tensile_strength_MPa = tensile_strength_kPa / 1e3
429
+ # Normalize transverse normal stress to layers' tensile strength
430
+ normalized_Szz = Szz_MPa / tensile_strength_MPa[:, None]
431
+ return normalized_Szz
432
+
433
+ # Return transverse normal stress Szz in specified unit
434
+ return convert[unit] * Szz_MPa
400
435
 
401
436
  @track_analyzer_call
402
437
  def principal_stress_slab(
@@ -438,6 +473,8 @@ class Analyzer:
438
473
  'min', or if normalization of compressive principal stress
439
474
  is requested.
440
475
  """
476
+ convert = {"kPa": 1e3, "MPa": 1}
477
+
441
478
  # Raise error if specified component is not available
442
479
  if val not in ["min", "max"]:
443
480
  raise ValueError(f"Component {val} not defined.")
@@ -460,9 +497,10 @@ class Analyzer:
460
497
  # Normalize tensile stresses to tensile strength
461
498
  if normalize and val == "max":
462
499
  zmesh = self.get_zmesh(dz=dz)
463
- tensile_strength = zmesh["tensile_strength"]
500
+ tensile_strength_kPa = zmesh["tensile_strength"]
501
+ tensile_strength_converted = tensile_strength_kPa / 1e3 * convert[unit]
464
502
  # Normalize maximum principal stress to layers' tensile strength
465
- normalized_Ps = Ps / tensile_strength[:, None]
503
+ normalized_Ps = Ps / tensile_strength_converted[:, None]
466
504
  return normalized_Ps
467
505
 
468
506
  # Return absolute principal stresses