weac 2.5.2__tar.gz → 2.6.1__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.
- {weac-2.5.2 → weac-2.6.1}/CITATION.cff +4 -1
- weac-2.6.1/LICENSE +24 -0
- weac-2.5.2/README.md → weac-2.6.1/PKG-INFO +48 -9
- weac-2.5.2/PKG-INFO → weac-2.6.1/README.md +21 -33
- weac-2.6.1/pyproject.toml +72 -0
- weac-2.6.1/setup.cfg +4 -0
- weac-2.6.1/tests/test_eigensystem.py +104 -0
- weac-2.6.1/tests/test_layered.py +191 -0
- weac-2.6.1/tests/test_mixins.py +121 -0
- weac-2.6.1/tests/test_plot.py +121 -0
- weac-2.6.1/tests/test_tools.py +41 -0
- {weac-2.5.2 → weac-2.6.1}/weac/__init__.py +1 -1
- {weac-2.5.2 → weac-2.6.1}/weac/mixins.py +426 -427
- {weac-2.5.2 → weac-2.6.1}/weac/tools.py +80 -66
- weac-2.6.1/weac.egg-info/PKG-INFO +353 -0
- weac-2.6.1/weac.egg-info/SOURCES.txt +28 -0
- weac-2.6.1/weac.egg-info/dependency_links.txt +1 -0
- weac-2.6.1/weac.egg-info/requires.txt +11 -0
- weac-2.6.1/weac.egg-info/top_level.txt +1 -0
- weac-2.5.2/LICENSE +0 -3
- weac-2.5.2/build/weac.egg-info/SOURCES.txt +0 -19
- weac-2.5.2/pyproject.toml +0 -9
- weac-2.5.2/setup.cfg +0 -45
- {weac-2.5.2 → weac-2.6.1}/MANIFEST.in +0 -0
- {weac-2.5.2 → weac-2.6.1}/img/bc.png +0 -0
- {weac-2.5.2 → weac-2.6.1}/img/layering.png +0 -0
- {weac-2.5.2 → weac-2.6.1}/img/logo.png +0 -0
- {weac-2.5.2 → weac-2.6.1}/img/model.png +0 -0
- {weac-2.5.2 → weac-2.6.1}/img/profiles.png +0 -0
- {weac-2.5.2 → weac-2.6.1}/img/systems.png +0 -0
- {weac-2.5.2 → weac-2.6.1}/weac/eigensystem.py +0 -0
- {weac-2.5.2 → weac-2.6.1}/weac/inverse.py +0 -0
- {weac-2.5.2 → weac-2.6.1}/weac/layered.py +0 -0
- {weac-2.5.2 → weac-2.6.1}/weac/plot.py +0 -0
|
@@ -8,12 +8,15 @@ authors:
|
|
|
8
8
|
- family-names: "Weissgraeber"
|
|
9
9
|
given-names: "Philipp"
|
|
10
10
|
orcid: "https://orcid.org/0000-0001-8320-8672"
|
|
11
|
-
version: 2.
|
|
11
|
+
version: 2.6.1
|
|
12
12
|
date-released: 2021-12-30
|
|
13
13
|
identifiers:
|
|
14
14
|
- description: Collection of archived snapshots of all versions of WEAC
|
|
15
15
|
type: doi
|
|
16
16
|
value: 10.5281/zenodo.5773113
|
|
17
|
+
- description: Release v2.5 with the implementation of slab touchdown in PST experiments
|
|
18
|
+
type: doi
|
|
19
|
+
value: 10.5281/zenodo.11121171
|
|
17
20
|
- description: Release v2.4 for the analysis of slope-normal and vertical PST boundary conditions
|
|
18
21
|
type: doi
|
|
19
22
|
value: 10.5281/zenodo.10555144
|
weac-2.6.1/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
|
2
|
+
|
|
3
|
+
WEAC (c) 2024 is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/.
|
|
4
|
+
|
|
5
|
+
You are free to:
|
|
6
|
+
|
|
7
|
+
- Share — copy and redistribute the material in any medium or format
|
|
8
|
+
- Adapt — remix, transform, and build upon the material.
|
|
9
|
+
|
|
10
|
+
Under the following terms:
|
|
11
|
+
|
|
12
|
+
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
|
13
|
+
|
|
14
|
+
- NonCommercial — You may not use the material for commercial purposes.
|
|
15
|
+
|
|
16
|
+
- ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
|
|
17
|
+
|
|
18
|
+
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
|
19
|
+
|
|
20
|
+
Notices:
|
|
21
|
+
|
|
22
|
+
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
|
|
23
|
+
|
|
24
|
+
No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
|
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: weac
|
|
3
|
+
Version: 2.6.1
|
|
4
|
+
Summary: Weak layer anticrack nucleation model
|
|
5
|
+
Author-email: 2phi GbR <mail@2phi.de>
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/2phi/weac
|
|
8
|
+
Project-URL: Demo, https://github.com/2phi/weac/blob/main/demo/demo.ipynb
|
|
9
|
+
Project-URL: Documentation, https://2phi.github.io/weac
|
|
10
|
+
Project-URL: Issues and feature requests, https://github.com/2phi/weac/issues
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: Other/Proprietary License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: matplotlib>=3.9.1
|
|
19
|
+
Requires-Dist: numpy>=2.0.1
|
|
20
|
+
Requires-Dist: scipy>=1.14.0
|
|
21
|
+
Provides-Extra: interactive
|
|
22
|
+
Requires-Dist: jupyter; extra == "interactive"
|
|
23
|
+
Requires-Dist: ipython>=8.12.3; extra == "interactive"
|
|
24
|
+
Provides-Extra: docs
|
|
25
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
26
|
+
Requires-Dist: sphinxawesome-theme; extra == "docs"
|
|
27
|
+
|
|
1
28
|
<!-- LOGO AND TITLE-->
|
|
2
29
|
<!-- <p align="right"><img src="https://github.com/2phi/weac/raw/main/img/logo.png" alt="Logo" width="80" height="80"></p> -->
|
|
3
30
|
|
|
@@ -120,12 +147,11 @@ git clone https://github.com/2phi/weac
|
|
|
120
147
|
```
|
|
121
148
|
for local use.
|
|
122
149
|
|
|
123
|
-
Needs
|
|
150
|
+
Needs (see also [requirements.txt](https://github.com/2phi/weac/blob/main/weac/requirements.txt)):
|
|
124
151
|
- [Python](https://www.python.org/downloads/release/python-3100/) ≥ 3.10
|
|
125
|
-
- [Numpy](https://numpy.org/)
|
|
126
|
-
- [Scipy](https://www.scipy.org/)
|
|
127
|
-
- [
|
|
128
|
-
- [Matplotlib](https://matplotlib.org/) for plotting
|
|
152
|
+
- [Numpy](https://numpy.org/) ≥ 2.0.1
|
|
153
|
+
- [Scipy](https://www.scipy.org/) ≥ 1.14.0
|
|
154
|
+
- [Matplotlib](https://matplotlib.org/) ≥ 3.9.1
|
|
129
155
|
|
|
130
156
|
<!-- USAGE EXAMPLES -->
|
|
131
157
|
## Usage
|
|
@@ -260,18 +286,31 @@ See the [open issues](https://github.com/2phi/weac/issues) for a list of propose
|
|
|
260
286
|
5. Open a pull request
|
|
261
287
|
|
|
262
288
|
|
|
263
|
-
<!--
|
|
289
|
+
<!-- WORKFLOWS -->
|
|
264
290
|
## Workflows
|
|
265
291
|
[](https://github.com/2phi/weac/actions/workflows/release.yml)<br>
|
|
266
292
|
[](https://github.com/2phi/weac/actions/workflows/docs.yml)
|
|
267
293
|
|
|
268
294
|
|
|
295
|
+
|
|
269
296
|
<!-- LICENSE -->
|
|
270
297
|
## License
|
|
271
298
|
|
|
272
|
-
|
|
299
|
+
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/">WEAC is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY-NC-SA 4.0 <img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt=""></a></p>
|
|
300
|
+
|
|
301
|
+
You are free to:
|
|
302
|
+
|
|
303
|
+
- **Share** — copy and redistribute the material in any medium or format
|
|
304
|
+
- **Adapt** — remix, transform, and build upon the material for any purpose, even commercially.
|
|
305
|
+
|
|
306
|
+
Under the following terms:
|
|
307
|
+
|
|
308
|
+
- **Attribution** — You must give [appropriate credit](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-appropriate-credit), provide a link to the license, and [indicate if changes were made](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-indicate-changes). You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
|
309
|
+
|
|
310
|
+
- **NonCommercial** — You may not use the material for [commercial purposes](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-commercial-purposes).
|
|
311
|
+
|
|
312
|
+
- **ShareAlike** — If you remix, transform, or build upon the material, you must distribute your contributions under the [same license](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-same-license) as the original.
|
|
273
313
|
|
|
274
|
-
We currently do not offer an open-source license. Please contact us for private licensing options.
|
|
275
314
|
|
|
276
315
|
|
|
277
316
|
<!-- CONTACT -->
|
|
@@ -311,4 +350,4 @@ E-mail: mail@2phi.de · Web: https://2phi.de · Project Link: [https://github.co
|
|
|
311
350
|
[pypi-url]: https://pypi.org/project/weac/
|
|
312
351
|
[release-url]: https://github.com/2phi/weac/releases
|
|
313
352
|
[weac-url]: https://github.com/2phi/weac/
|
|
314
|
-
[doi-url]: https://zenodo.org/badge/latestdoi/203163531
|
|
353
|
+
[doi-url]: https://zenodo.org/badge/latestdoi/203163531
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: weac
|
|
3
|
-
Version: 2.5.2
|
|
4
|
-
Summary: Weak layer anticrack nucleation model
|
|
5
|
-
Home-page: https://github.com/2phi/weac
|
|
6
|
-
Author: 2phi GbR
|
|
7
|
-
Author-email: mail@2phi.de
|
|
8
|
-
License: Proprietary
|
|
9
|
-
Project-URL: Demo, https://github.com/2phi/weac/blob/main/demo/demo.ipynb
|
|
10
|
-
Project-URL: Documentation, https://2phi.github.io/weac
|
|
11
|
-
Project-URL: Issues and feature requests, https://github.com/2phi/weac/issues
|
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: License :: Other/Proprietary License
|
|
14
|
-
Classifier: Operating System :: OS Independent
|
|
15
|
-
Classifier: Topic :: Scientific/Engineering
|
|
16
|
-
Requires-Python: >=3.10
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
License-File: LICENSE
|
|
19
|
-
Requires-Dist: matplotlib
|
|
20
|
-
Requires-Dist: numpy
|
|
21
|
-
Requires-Dist: scipy
|
|
22
|
-
Provides-Extra: interactive
|
|
23
|
-
Requires-Dist: jupyter; extra == "interactive"
|
|
24
|
-
|
|
25
1
|
<!-- LOGO AND TITLE-->
|
|
26
2
|
<!-- <p align="right"><img src="https://github.com/2phi/weac/raw/main/img/logo.png" alt="Logo" width="80" height="80"></p> -->
|
|
27
3
|
|
|
@@ -144,12 +120,11 @@ git clone https://github.com/2phi/weac
|
|
|
144
120
|
```
|
|
145
121
|
for local use.
|
|
146
122
|
|
|
147
|
-
Needs
|
|
123
|
+
Needs (see also [requirements.txt](https://github.com/2phi/weac/blob/main/weac/requirements.txt)):
|
|
148
124
|
- [Python](https://www.python.org/downloads/release/python-3100/) ≥ 3.10
|
|
149
|
-
- [Numpy](https://numpy.org/)
|
|
150
|
-
- [Scipy](https://www.scipy.org/)
|
|
151
|
-
- [
|
|
152
|
-
- [Matplotlib](https://matplotlib.org/) for plotting
|
|
125
|
+
- [Numpy](https://numpy.org/) ≥ 2.0.1
|
|
126
|
+
- [Scipy](https://www.scipy.org/) ≥ 1.14.0
|
|
127
|
+
- [Matplotlib](https://matplotlib.org/) ≥ 3.9.1
|
|
153
128
|
|
|
154
129
|
<!-- USAGE EXAMPLES -->
|
|
155
130
|
## Usage
|
|
@@ -284,18 +259,31 @@ See the [open issues](https://github.com/2phi/weac/issues) for a list of propose
|
|
|
284
259
|
5. Open a pull request
|
|
285
260
|
|
|
286
261
|
|
|
287
|
-
<!--
|
|
262
|
+
<!-- WORKFLOWS -->
|
|
288
263
|
## Workflows
|
|
289
264
|
[](https://github.com/2phi/weac/actions/workflows/release.yml)<br>
|
|
290
265
|
[](https://github.com/2phi/weac/actions/workflows/docs.yml)
|
|
291
266
|
|
|
292
267
|
|
|
268
|
+
|
|
293
269
|
<!-- LICENSE -->
|
|
294
270
|
## License
|
|
295
271
|
|
|
296
|
-
|
|
272
|
+
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/">WEAC is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY-NC-SA 4.0 <img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt=""></a></p>
|
|
273
|
+
|
|
274
|
+
You are free to:
|
|
275
|
+
|
|
276
|
+
- **Share** — copy and redistribute the material in any medium or format
|
|
277
|
+
- **Adapt** — remix, transform, and build upon the material for any purpose, even commercially.
|
|
278
|
+
|
|
279
|
+
Under the following terms:
|
|
280
|
+
|
|
281
|
+
- **Attribution** — You must give [appropriate credit](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-appropriate-credit), provide a link to the license, and [indicate if changes were made](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-indicate-changes). You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
|
282
|
+
|
|
283
|
+
- **NonCommercial** — You may not use the material for [commercial purposes](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-commercial-purposes).
|
|
284
|
+
|
|
285
|
+
- **ShareAlike** — If you remix, transform, or build upon the material, you must distribute your contributions under the [same license](https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1#ref-same-license) as the original.
|
|
297
286
|
|
|
298
|
-
We currently do not offer an open-source license. Please contact us for private licensing options.
|
|
299
287
|
|
|
300
288
|
|
|
301
289
|
<!-- CONTACT -->
|
|
@@ -335,4 +323,4 @@ E-mail: mail@2phi.de · Web: https://2phi.de · Project Link: [https://github.co
|
|
|
335
323
|
[pypi-url]: https://pypi.org/project/weac/
|
|
336
324
|
[release-url]: https://github.com/2phi/weac/releases
|
|
337
325
|
[weac-url]: https://github.com/2phi/weac/
|
|
338
|
-
[doi-url]: https://zenodo.org/badge/latestdoi/203163531
|
|
326
|
+
[doi-url]: https://zenodo.org/badge/latestdoi/203163531
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "weac"
|
|
7
|
+
version = "2.6.1"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "2phi GbR", email = "mail@2phi.de"},
|
|
10
|
+
]
|
|
11
|
+
description = "Weak layer anticrack nucleation model"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
license = {text = "Proprietary"}
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"License :: Other/Proprietary License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Topic :: Scientific/Engineering",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"matplotlib>=3.9.1",
|
|
23
|
+
"numpy>=2.0.1",
|
|
24
|
+
"scipy>=1.14.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/2phi/weac"
|
|
29
|
+
Demo = "https://github.com/2phi/weac/blob/main/demo/demo.ipynb"
|
|
30
|
+
Documentation = "https://2phi.github.io/weac"
|
|
31
|
+
"Issues and feature requests" = "https://github.com/2phi/weac/issues"
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
interactive = ["jupyter", "ipython>=8.12.3"]
|
|
35
|
+
docs = ["sphinx", "sphinxawesome-theme"]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools]
|
|
38
|
+
packages = ["weac"]
|
|
39
|
+
package-data = {"*" = ["CITATION.cff"], "img" = ["*.png"]}
|
|
40
|
+
|
|
41
|
+
[tool.ruff]
|
|
42
|
+
ignore = ["E741"]
|
|
43
|
+
|
|
44
|
+
[tool.pylint.typecheck]
|
|
45
|
+
generated-members = "matplotlib.cm.*"
|
|
46
|
+
|
|
47
|
+
[tool.pycodestyle]
|
|
48
|
+
ignore = ["E121", "E123", "E126", "E211", "E226", "E24", "E704", "W503", "W504", "E741"]
|
|
49
|
+
|
|
50
|
+
[tool.bumpversion]
|
|
51
|
+
current_version = "2.6.1"
|
|
52
|
+
tag = true
|
|
53
|
+
commit = true
|
|
54
|
+
|
|
55
|
+
[[tool.bumpversion.files]]
|
|
56
|
+
filename = "pyproject.toml"
|
|
57
|
+
|
|
58
|
+
[[tool.bumpversion.files]]
|
|
59
|
+
filename = "CITATION.cff"
|
|
60
|
+
|
|
61
|
+
[[tool.bumpversion.files]]
|
|
62
|
+
filename = "weac/__init__.py"
|
|
63
|
+
search = "__version__ = '{current_version}'"
|
|
64
|
+
replace = "__version__ = '{new_version}'"
|
|
65
|
+
|
|
66
|
+
[[tool.bumpversion.files]]
|
|
67
|
+
filename = "demo/demo.ipynb"
|
|
68
|
+
|
|
69
|
+
[[tool.bumpversion.files]]
|
|
70
|
+
filename = "docs/sphinx/conf.py"
|
|
71
|
+
search = "release = '{current_version}'"
|
|
72
|
+
replace = "release = '{new_version}'"
|
weac-2.6.1/setup.cfg
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for the Eigensystem class in the WEAC package.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import unittest
|
|
6
|
+
|
|
7
|
+
from weac.eigensystem import Eigensystem
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestEigensystem(unittest.TestCase):
|
|
11
|
+
"""Test cases for the Eigensystem class."""
|
|
12
|
+
|
|
13
|
+
def setUp(self):
|
|
14
|
+
"""Set up test fixtures."""
|
|
15
|
+
# Create an Eigensystem instance for testing
|
|
16
|
+
self.eigen = Eigensystem(system="pst-")
|
|
17
|
+
|
|
18
|
+
# Set up properties needed for tests
|
|
19
|
+
self.eigen.set_beam_properties([[300, 200]])
|
|
20
|
+
self.eigen.set_foundation_properties()
|
|
21
|
+
|
|
22
|
+
def test_initialization(self):
|
|
23
|
+
"""Test that Eigensystem initializes with correct default values."""
|
|
24
|
+
# Test default initialization
|
|
25
|
+
self.assertEqual(self.eigen.system, "pst-")
|
|
26
|
+
self.assertFalse(self.eigen.touchdown)
|
|
27
|
+
self.assertAlmostEqual(self.eigen.g, 9810.0) # Gravitational constant
|
|
28
|
+
|
|
29
|
+
def test_set_beam_properties(self):
|
|
30
|
+
"""Test setting beam properties with different layer configurations."""
|
|
31
|
+
# Create a new instance to test from scratch
|
|
32
|
+
eigen = Eigensystem(system="pst-")
|
|
33
|
+
|
|
34
|
+
# Test with a single layer
|
|
35
|
+
eigen.set_beam_properties([[300, 200]]) # [density (kg/m^3), thickness (mm)]
|
|
36
|
+
|
|
37
|
+
# Check that slab property is set
|
|
38
|
+
self.assertIsNotNone(eigen.slab)
|
|
39
|
+
# The actual shape might be different from what we expected
|
|
40
|
+
# Let's just check that it's a 2D array with at least one row
|
|
41
|
+
self.assertGreaterEqual(eigen.slab.shape[0], 1)
|
|
42
|
+
|
|
43
|
+
# Test with multiple layers
|
|
44
|
+
eigen.set_beam_properties(
|
|
45
|
+
[
|
|
46
|
+
[200, 100], # [density (kg/m^3), thickness (mm)]
|
|
47
|
+
[300, 150],
|
|
48
|
+
[400, 50],
|
|
49
|
+
]
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Check that slab property is updated
|
|
53
|
+
self.assertIsNotNone(eigen.slab)
|
|
54
|
+
# Check that we have the right number of layers
|
|
55
|
+
self.assertEqual(eigen.slab.shape[0], 3)
|
|
56
|
+
|
|
57
|
+
def test_set_foundation_properties(self):
|
|
58
|
+
"""Test setting foundation properties."""
|
|
59
|
+
# Create a new instance to test from scratch
|
|
60
|
+
eigen = Eigensystem(system="pst-")
|
|
61
|
+
|
|
62
|
+
# Test with default parameters
|
|
63
|
+
eigen.set_foundation_properties()
|
|
64
|
+
|
|
65
|
+
# Check that weak layer properties are set
|
|
66
|
+
self.assertIsNotNone(eigen.weak)
|
|
67
|
+
self.assertIn("E", eigen.weak)
|
|
68
|
+
self.assertIn("nu", eigen.weak)
|
|
69
|
+
|
|
70
|
+
# Test with custom parameters
|
|
71
|
+
eigen.set_foundation_properties(
|
|
72
|
+
t=50.0, # Weak layer thickness (mm)
|
|
73
|
+
E=0.5, # Young's modulus (MPa)
|
|
74
|
+
nu=0.3, # Poisson's ratio
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Check that weak layer properties are updated
|
|
78
|
+
self.assertIsNotNone(eigen.weak)
|
|
79
|
+
self.assertEqual(eigen.weak["E"], 0.5)
|
|
80
|
+
self.assertEqual(eigen.weak["nu"], 0.3)
|
|
81
|
+
self.assertEqual(eigen.t, 50.0)
|
|
82
|
+
|
|
83
|
+
def test_calc_fundamental_system(self):
|
|
84
|
+
"""Test calculation of the fundamental system."""
|
|
85
|
+
# Calculate the fundamental system
|
|
86
|
+
self.eigen.calc_fundamental_system()
|
|
87
|
+
|
|
88
|
+
# Check that the system has been initialized
|
|
89
|
+
self.assertIsNotNone(
|
|
90
|
+
getattr(self.eigen, "kn", None)
|
|
91
|
+
) # Foundation normal stiffness
|
|
92
|
+
self.assertIsNotNone(
|
|
93
|
+
getattr(self.eigen, "kt", None)
|
|
94
|
+
) # Foundation shear stiffness
|
|
95
|
+
self.assertIsNotNone(getattr(self.eigen, "A11", None)) # Extensional stiffness
|
|
96
|
+
self.assertIsNotNone(
|
|
97
|
+
getattr(self.eigen, "B11", None)
|
|
98
|
+
) # Bending-extension coupling stiffness
|
|
99
|
+
self.assertIsNotNone(getattr(self.eigen, "D11", None)) # Bending stiffness
|
|
100
|
+
self.assertIsNotNone(getattr(self.eigen, "kA55", None)) # Shear stiffness
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
if __name__ == "__main__":
|
|
104
|
+
unittest.main()
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for the Layered class in the WEAC package.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import unittest
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from weac.layered import Layered
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestLayered(unittest.TestCase):
|
|
13
|
+
"""Test cases for the Layered class."""
|
|
14
|
+
|
|
15
|
+
def setUp(self):
|
|
16
|
+
"""Set up test fixtures."""
|
|
17
|
+
# Create a default Layered instance for testing
|
|
18
|
+
self.layered = Layered(system="pst-")
|
|
19
|
+
|
|
20
|
+
# Create a Layered instance with custom parameters
|
|
21
|
+
self.custom_layered = Layered(
|
|
22
|
+
system="skier",
|
|
23
|
+
layers=[[240, 200]], # [density (kg/m^3), thickness (mm)]
|
|
24
|
+
touchdown=True,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def test_initialization(self):
|
|
28
|
+
"""Test that Layered initializes with correct default values."""
|
|
29
|
+
# Test default initialization
|
|
30
|
+
self.assertEqual(self.layered.system, "pst-")
|
|
31
|
+
self.assertFalse(self.layered.touchdown)
|
|
32
|
+
|
|
33
|
+
# Test custom initialization
|
|
34
|
+
self.assertEqual(self.custom_layered.system, "skier")
|
|
35
|
+
self.assertTrue(self.custom_layered.touchdown)
|
|
36
|
+
self.assertEqual(len(self.custom_layered.slab), 1)
|
|
37
|
+
self.assertAlmostEqual(self.custom_layered.slab[0, 0], 240.0) # Density
|
|
38
|
+
self.assertAlmostEqual(self.custom_layered.slab[0, 1], 200.0) # Thickness
|
|
39
|
+
|
|
40
|
+
def test_calc_segments(self):
|
|
41
|
+
"""Test calculation of segments for different systems."""
|
|
42
|
+
# Test for PST cut from right
|
|
43
|
+
self.layered.system = "pst-"
|
|
44
|
+
segments = self.layered.calc_segments(L=1000, a=300)
|
|
45
|
+
|
|
46
|
+
# Check that segments dictionary contains expected keys
|
|
47
|
+
self.assertIn("crack", segments)
|
|
48
|
+
self.assertIn("nocrack", segments)
|
|
49
|
+
self.assertIn("both", segments)
|
|
50
|
+
|
|
51
|
+
# Check segment lengths for crack configuration
|
|
52
|
+
crack_segments = segments["crack"]
|
|
53
|
+
self.assertIn("li", crack_segments)
|
|
54
|
+
self.assertEqual(len(crack_segments["li"]), 2) # Two segments for PST-
|
|
55
|
+
self.assertAlmostEqual(crack_segments["li"][0], 700.0) # First segment length
|
|
56
|
+
self.assertAlmostEqual(crack_segments["li"][1], 300.0) # Second segment length
|
|
57
|
+
|
|
58
|
+
# Test for skier system
|
|
59
|
+
self.layered.system = "skier"
|
|
60
|
+
segments = self.layered.calc_segments()
|
|
61
|
+
|
|
62
|
+
# Check that segments dictionary contains expected keys
|
|
63
|
+
self.assertIn("crack", segments)
|
|
64
|
+
|
|
65
|
+
# Check segment lengths for skier configuration
|
|
66
|
+
skier_segments = segments["crack"]
|
|
67
|
+
self.assertIn("li", skier_segments)
|
|
68
|
+
# Note: The actual implementation returns 4 segments for skier, not 2
|
|
69
|
+
self.assertEqual(len(skier_segments["li"]), 4) # Four segments for skier
|
|
70
|
+
|
|
71
|
+
# Test for multiple skiers
|
|
72
|
+
self.layered.system = "skiers"
|
|
73
|
+
segments = self.layered.calc_segments(
|
|
74
|
+
li=[500, 100, 250, 30, 30, 500],
|
|
75
|
+
ki=[True, True, True, False, False, True],
|
|
76
|
+
mi=[80, 80, 0, 0, 0],
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Check that segments dictionary contains expected keys
|
|
80
|
+
self.assertIn("crack", segments)
|
|
81
|
+
|
|
82
|
+
# Check segment lengths for multiple skiers configuration
|
|
83
|
+
skiers_segments = segments["crack"]
|
|
84
|
+
self.assertIn("li", skiers_segments)
|
|
85
|
+
self.assertEqual(len(skiers_segments["li"]), 6) # Six segments as specified
|
|
86
|
+
self.assertAlmostEqual(skiers_segments["li"][0], 500.0)
|
|
87
|
+
self.assertAlmostEqual(skiers_segments["li"][1], 100.0)
|
|
88
|
+
self.assertAlmostEqual(skiers_segments["li"][2], 250.0)
|
|
89
|
+
self.assertAlmostEqual(skiers_segments["li"][3], 30.0)
|
|
90
|
+
self.assertAlmostEqual(skiers_segments["li"][4], 30.0)
|
|
91
|
+
self.assertAlmostEqual(skiers_segments["li"][5], 500.0)
|
|
92
|
+
|
|
93
|
+
def test_assemble_and_solve(self):
|
|
94
|
+
"""Test assembly and solution of the system."""
|
|
95
|
+
# Set up a simple configuration
|
|
96
|
+
self.layered.set_beam_properties([[240, 200]])
|
|
97
|
+
self.layered.set_foundation_properties()
|
|
98
|
+
self.layered.calc_fundamental_system()
|
|
99
|
+
|
|
100
|
+
# Calculate segments
|
|
101
|
+
segments = self.layered.calc_segments(L=1000, a=300)
|
|
102
|
+
|
|
103
|
+
# Assemble and solve the system
|
|
104
|
+
C = self.layered.assemble_and_solve(phi=0, **segments["crack"])
|
|
105
|
+
|
|
106
|
+
# Check that solution vector has correct shape
|
|
107
|
+
self.assertIsNotNone(C)
|
|
108
|
+
self.assertEqual(C.shape, (6, 2)) # 6 state variables, 2 segments
|
|
109
|
+
|
|
110
|
+
# Test with non-zero slope angle
|
|
111
|
+
C_slope = self.layered.assemble_and_solve(phi=30, **segments["crack"])
|
|
112
|
+
self.assertIsNotNone(C_slope)
|
|
113
|
+
self.assertEqual(C_slope.shape, (6, 2))
|
|
114
|
+
|
|
115
|
+
def test_rasterize_solution(self):
|
|
116
|
+
"""Test rasterization of the solution."""
|
|
117
|
+
# Set up a simple configuration
|
|
118
|
+
self.layered.set_beam_properties([[240, 200]])
|
|
119
|
+
self.layered.set_foundation_properties()
|
|
120
|
+
self.layered.calc_fundamental_system()
|
|
121
|
+
|
|
122
|
+
# Calculate segments
|
|
123
|
+
segments = self.layered.calc_segments(L=1000, a=300)
|
|
124
|
+
|
|
125
|
+
# Assemble and solve the system
|
|
126
|
+
C = self.layered.assemble_and_solve(phi=0, **segments["crack"])
|
|
127
|
+
|
|
128
|
+
# Rasterize the solution
|
|
129
|
+
xsl, z, xwl = self.layered.rasterize_solution(C=C, phi=0, **segments["crack"])
|
|
130
|
+
|
|
131
|
+
# Check that output arrays have correct shapes
|
|
132
|
+
self.assertIsNotNone(xsl)
|
|
133
|
+
self.assertIsNotNone(z)
|
|
134
|
+
self.assertIsNotNone(xwl)
|
|
135
|
+
self.assertEqual(z.shape[0], 6) # 6 state variables
|
|
136
|
+
self.assertEqual(xsl.shape, z.shape[1:]) # Same length as state variables
|
|
137
|
+
|
|
138
|
+
# Check that x coordinates are within expected range
|
|
139
|
+
self.assertGreaterEqual(np.min(xsl), 0)
|
|
140
|
+
self.assertLessEqual(np.max(xsl), 1000)
|
|
141
|
+
|
|
142
|
+
def test_gdif(self):
|
|
143
|
+
"""Test calculation of differential energy release rate."""
|
|
144
|
+
# Set up a simple configuration
|
|
145
|
+
self.layered.set_beam_properties([[240, 200]])
|
|
146
|
+
self.layered.set_foundation_properties()
|
|
147
|
+
self.layered.calc_fundamental_system()
|
|
148
|
+
|
|
149
|
+
# Calculate segments
|
|
150
|
+
segments = self.layered.calc_segments(L=1000, a=300)
|
|
151
|
+
|
|
152
|
+
# Assemble and solve the system
|
|
153
|
+
C = self.layered.assemble_and_solve(phi=0, **segments["crack"])
|
|
154
|
+
|
|
155
|
+
# Calculate differential energy release rate
|
|
156
|
+
G = self.layered.gdif(C, phi=0, **segments["crack"])
|
|
157
|
+
|
|
158
|
+
# Check that energy release rate is non-negative
|
|
159
|
+
self.assertIsNotNone(G)
|
|
160
|
+
self.assertEqual(len(G), 3) # Three components: mode I, mode II, and total
|
|
161
|
+
self.assertGreaterEqual(
|
|
162
|
+
G[2], 0
|
|
163
|
+
) # Total energy release rate should be non-negative
|
|
164
|
+
|
|
165
|
+
def test_ginc(self):
|
|
166
|
+
"""Test calculation of incremental energy release rate."""
|
|
167
|
+
# Set up a simple configuration
|
|
168
|
+
self.layered.set_beam_properties([[240, 200]])
|
|
169
|
+
self.layered.set_foundation_properties()
|
|
170
|
+
self.layered.calc_fundamental_system()
|
|
171
|
+
|
|
172
|
+
# Calculate segments for both configurations
|
|
173
|
+
segments = self.layered.calc_segments(L=1000, a=300)
|
|
174
|
+
|
|
175
|
+
# Assemble and solve the system for both configurations
|
|
176
|
+
C0 = self.layered.assemble_and_solve(phi=0, **segments["nocrack"])
|
|
177
|
+
C1 = self.layered.assemble_and_solve(phi=0, **segments["crack"])
|
|
178
|
+
|
|
179
|
+
# Calculate incremental energy release rate
|
|
180
|
+
G = self.layered.ginc(C0, C1, phi=0, **segments["both"])
|
|
181
|
+
|
|
182
|
+
# Check that energy release rate is non-negative
|
|
183
|
+
self.assertIsNotNone(G)
|
|
184
|
+
self.assertEqual(len(G), 3) # Three components: mode I, mode II, and total
|
|
185
|
+
self.assertGreaterEqual(
|
|
186
|
+
G[2], 0
|
|
187
|
+
) # Total energy release rate should be non-negative
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
if __name__ == "__main__":
|
|
191
|
+
unittest.main()
|