weac 2.6.0__py3-none-any.whl → 2.6.2__py3-none-any.whl
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/__init__.py +4 -8
- weac/eigensystem.py +180 -139
- weac/inverse.py +5 -8
- weac/layered.py +24 -9
- weac/mixins.py +423 -426
- weac/plot.py +244 -196
- weac/tools.py +84 -69
- {weac-2.6.0.dist-info → weac-2.6.2.dist-info}/METADATA +22 -8
- weac-2.6.2.dist-info/RECORD +12 -0
- {weac-2.6.0.dist-info → weac-2.6.2.dist-info}/WHEEL +1 -1
- weac-2.6.0.dist-info/RECORD +0 -12
- {weac-2.6.0.dist-info → weac-2.6.2.dist-info/licenses}/LICENSE +0 -0
- {weac-2.6.0.dist-info → weac-2.6.2.dist-info}/top_level.txt +0 -0
weac/tools.py
CHANGED
|
@@ -3,66 +3,74 @@
|
|
|
3
3
|
|
|
4
4
|
# Standard library imports
|
|
5
5
|
from timeit import default_timer as timer
|
|
6
|
-
from IPython import get_ipython
|
|
7
6
|
|
|
8
7
|
# Third party imports
|
|
9
8
|
import numpy as np
|
|
9
|
+
|
|
10
10
|
import weac
|
|
11
11
|
|
|
12
|
+
try:
|
|
13
|
+
from IPython import get_ipython
|
|
14
|
+
except ImportError:
|
|
15
|
+
get_ipython = None
|
|
16
|
+
|
|
12
17
|
|
|
13
18
|
def time():
|
|
14
19
|
"""Return current time in milliseconds."""
|
|
15
|
-
return 1e3*timer()
|
|
20
|
+
return 1e3 * timer()
|
|
16
21
|
|
|
17
22
|
|
|
18
23
|
def isnotebook():
|
|
19
24
|
"""Identify shell environment."""
|
|
20
25
|
try:
|
|
26
|
+
if get_ipython is None:
|
|
27
|
+
return False
|
|
21
28
|
shell = get_ipython().__class__.__name__
|
|
22
|
-
if shell ==
|
|
23
|
-
return True
|
|
24
|
-
|
|
29
|
+
if shell == "ZMQInteractiveShell":
|
|
30
|
+
return True # Jupyter notebook or qtconsole
|
|
31
|
+
elif shell == "TerminalInteractiveShell":
|
|
25
32
|
return False # Terminal running IPython
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
except NameError:
|
|
29
|
-
return False
|
|
33
|
+
else:
|
|
34
|
+
return False # Other type
|
|
35
|
+
except (NameError, AttributeError):
|
|
36
|
+
return False # Probably standard Python interpreter
|
|
30
37
|
|
|
31
38
|
|
|
32
39
|
def load_dummy_profile(profile_id):
|
|
33
40
|
"""Define standard layering types for comparison."""
|
|
34
41
|
# Layers [density (kg/m^3), thickness (mm), Young's modulus (N/mm^2)]
|
|
35
|
-
soft = [180
|
|
36
|
-
medium = [270
|
|
37
|
-
hard = [350
|
|
42
|
+
soft = [180.0, 120.0, 5]
|
|
43
|
+
medium = [270.0, 120.0, 30]
|
|
44
|
+
hard = [350.0, 120.0, 93.8]
|
|
38
45
|
# soft = [120., 120., 0.3]
|
|
39
46
|
# medium = [180., 120., 1.5]
|
|
40
47
|
# hard = [270., 120., 7.5]
|
|
41
48
|
|
|
42
|
-
|
|
43
49
|
# Database (top to bottom)
|
|
44
50
|
database = {
|
|
45
51
|
# Layered
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
"a": [hard, medium, soft],
|
|
53
|
+
"b": [soft, medium, hard],
|
|
54
|
+
"c": [hard, soft, hard],
|
|
55
|
+
"d": [soft, hard, soft],
|
|
56
|
+
"e": [hard, soft, soft],
|
|
57
|
+
"f": [soft, soft, hard],
|
|
52
58
|
# Homogeneous
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
"h": [medium, medium, medium],
|
|
60
|
+
"soft": [soft, soft, soft],
|
|
61
|
+
"medium": [medium, medium, medium],
|
|
62
|
+
"hard": [hard, hard, hard],
|
|
57
63
|
# Comparison
|
|
58
|
-
|
|
64
|
+
"comp": [
|
|
65
|
+
[240.0, 200.0, 5.23],
|
|
66
|
+
],
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
# Load profile
|
|
62
70
|
try:
|
|
63
71
|
profile = np.array(database[profile_id.lower()])
|
|
64
72
|
except KeyError:
|
|
65
|
-
raise ValueError(f
|
|
73
|
+
raise ValueError(f"Profile {profile_id} is not defined.") from None
|
|
66
74
|
|
|
67
75
|
# Prepare output
|
|
68
76
|
layers = profile[:, 0:2]
|
|
@@ -90,14 +98,14 @@ def calc_center_of_gravity(layers):
|
|
|
90
98
|
Z-coordinate of center of gravity (mm).
|
|
91
99
|
"""
|
|
92
100
|
# Layering info for center of gravity calculation (bottom to top)
|
|
93
|
-
n = layers.shape[0]
|
|
94
|
-
rho = 1e-12*np.flipud(layers[:, 0])
|
|
95
|
-
h = np.flipud(layers[:, 1])
|
|
96
|
-
H = sum(h)
|
|
101
|
+
n = layers.shape[0] # Number of layers
|
|
102
|
+
rho = 1e-12 * np.flipud(layers[:, 0]) # Layer densities (kg/m^3 -> t/mm^3)
|
|
103
|
+
h = np.flipud(layers[:, 1]) # Layer thicknesses
|
|
104
|
+
H = sum(h) # Total slab thickness
|
|
97
105
|
# Layer center coordinates (bottom to top)
|
|
98
|
-
zi = [H/2 - sum(h[0:j]) - h[j]/2 for j in range(n)]
|
|
106
|
+
zi = [H / 2 - sum(h[0:j]) - h[j] / 2 for j in range(n)]
|
|
99
107
|
# Z-coordinate of the center of gravity
|
|
100
|
-
zs = sum(zi*h*rho)/sum(h*rho)
|
|
108
|
+
zs = sum(zi * h * rho) / sum(h * rho)
|
|
101
109
|
# Return slab thickness and center of gravity
|
|
102
110
|
return H, zs
|
|
103
111
|
|
|
@@ -127,7 +135,7 @@ def calc_vertical_bc_center_of_gravity(slab, phi):
|
|
|
127
135
|
"""
|
|
128
136
|
# Convert slope angle to radians
|
|
129
137
|
phi = np.deg2rad(phi)
|
|
130
|
-
|
|
138
|
+
|
|
131
139
|
# Catch flat-field case
|
|
132
140
|
if phi == 0:
|
|
133
141
|
xs = 0
|
|
@@ -135,28 +143,29 @@ def calc_vertical_bc_center_of_gravity(slab, phi):
|
|
|
135
143
|
w = 0
|
|
136
144
|
else:
|
|
137
145
|
# Layering info for center of gravity calculation (top to bottom)
|
|
138
|
-
n = slab.shape[0]
|
|
139
|
-
rho = 1e-12*slab[:, 0]
|
|
140
|
-
hi = slab[:, 1]
|
|
141
|
-
H = sum(hi)
|
|
146
|
+
n = slab.shape[0] # Number of slab
|
|
147
|
+
rho = 1e-12 * slab[:, 0] # Layer densities (kg/m^3 -> t/mm^3)
|
|
148
|
+
hi = slab[:, 1] # Layer thicknesses
|
|
149
|
+
H = sum(hi) # Total slab thickness
|
|
142
150
|
# Layer coordinates z_i (top to bottom)
|
|
143
|
-
z = np.array([-H/2 + sum(hi[0:j]) for j in range(n + 1)])
|
|
144
|
-
zi = z[:-1]
|
|
145
|
-
zii = z[1:]
|
|
151
|
+
z = np.array([-H / 2 + sum(hi[0:j]) for j in range(n + 1)])
|
|
152
|
+
zi = z[:-1] # z_i
|
|
153
|
+
zii = z[1:] # z_{i+1}
|
|
146
154
|
# Center of gravity of all layers (top to bottom)
|
|
147
|
-
zsi = zi + hi/3*(3/2*H - zi - 2*zii)/(H - zi - zii)
|
|
155
|
+
zsi = zi + hi / 3 * (3 / 2 * H - zi - 2 * zii) / (H - zi - zii)
|
|
148
156
|
# Surface area of all layers (top to bottom)
|
|
149
|
-
Ai = hi/2*(H - zi - zii)*np.tan(phi)
|
|
157
|
+
Ai = hi / 2 * (H - zi - zii) * np.tan(phi)
|
|
150
158
|
# Center of gravity in vertical direction
|
|
151
|
-
zs = sum(zsi*rho*Ai)/sum(rho*Ai)
|
|
159
|
+
zs = sum(zsi * rho * Ai) / sum(rho * Ai)
|
|
152
160
|
# Center of gravity in horizontal direction
|
|
153
|
-
xs = (H/2 - zs)*np.tan(phi/2)
|
|
161
|
+
xs = (H / 2 - zs) * np.tan(phi / 2)
|
|
154
162
|
# Weight of added or cut off slab segments (t)
|
|
155
|
-
w = sum(Ai*rho)
|
|
156
|
-
|
|
163
|
+
w = sum(Ai * rho)
|
|
164
|
+
|
|
157
165
|
# Return center of gravity and weight of slab segment
|
|
158
166
|
return xs, zs, w
|
|
159
167
|
|
|
168
|
+
|
|
160
169
|
def scapozza(rho):
|
|
161
170
|
"""
|
|
162
171
|
Compute Young's modulus (MPa) from density (kg/m^3).
|
|
@@ -171,9 +180,9 @@ def scapozza(rho):
|
|
|
171
180
|
E : float or ndarray
|
|
172
181
|
Young's modulus (MPa).
|
|
173
182
|
"""
|
|
174
|
-
rho = rho*1e-12
|
|
175
|
-
rho0 = 917e-12
|
|
176
|
-
E = 5.07e3*(rho/rho0)**5.13
|
|
183
|
+
rho = rho * 1e-12 # Convert to t/mm^3
|
|
184
|
+
rho0 = 917e-12 # Desity of ice in t/mm^3
|
|
185
|
+
E = 5.07e3 * (rho / rho0) ** 5.13 # Young's modulus in MPa
|
|
177
186
|
return E
|
|
178
187
|
|
|
179
188
|
|
|
@@ -197,10 +206,10 @@ def gerling(rho, C0=6.0, C1=4.6):
|
|
|
197
206
|
E : float or ndarray
|
|
198
207
|
Young's modulus (MPa).
|
|
199
208
|
"""
|
|
200
|
-
return C0*1e-10*rho**C1
|
|
209
|
+
return C0 * 1e-10 * rho**C1
|
|
201
210
|
|
|
202
211
|
|
|
203
|
-
def bergfeld(rho, rho0=
|
|
212
|
+
def bergfeld(rho, rho0=916.7, C0=6.5, C1=4.4):
|
|
204
213
|
"""
|
|
205
214
|
Compute Young's modulus from density according to Bergfeld et al. (2023).
|
|
206
215
|
|
|
@@ -222,12 +231,12 @@ def bergfeld(rho, rho0=917, C0=6.5, C1=4.4):
|
|
|
222
231
|
E : float or ndarray
|
|
223
232
|
Young's modulus (MPa).
|
|
224
233
|
"""
|
|
225
|
-
return C0*1e3*(rho/rho0)**C1
|
|
234
|
+
return C0 * 1e3 * (rho / rho0) ** C1
|
|
226
235
|
|
|
227
236
|
|
|
228
|
-
def tensile_strength_slab(rho, unit=
|
|
237
|
+
def tensile_strength_slab(rho, unit="kPa"):
|
|
229
238
|
"""
|
|
230
|
-
Estimate the tensile
|
|
239
|
+
Estimate the tensile strength of a slab layer from its density.
|
|
231
240
|
|
|
232
241
|
Uses the density parametrization of Sigrist (2006).
|
|
233
242
|
|
|
@@ -241,23 +250,23 @@ def tensile_strength_slab(rho, unit='kPa'):
|
|
|
241
250
|
Returns
|
|
242
251
|
-------
|
|
243
252
|
ndarray
|
|
244
|
-
Tensile
|
|
253
|
+
Tensile strength in specified unit.
|
|
245
254
|
"""
|
|
246
|
-
convert = {
|
|
247
|
-
'kPa': 1,
|
|
248
|
-
'MPa': 1e-3
|
|
249
|
-
}
|
|
255
|
+
convert = {"kPa": 1, "MPa": 1e-3, "m": 1, "mm": 1e3, "cm": 1e2}
|
|
250
256
|
rho_ice = 917
|
|
251
257
|
# Sigrist's equation is given in kPa
|
|
252
|
-
|
|
258
|
+
value = convert[unit] * 240 * (rho / rho_ice) ** 2.44
|
|
259
|
+
return value
|
|
260
|
+
|
|
253
261
|
|
|
254
262
|
def touchdown_distance(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
263
|
+
layers: np.ndarray | str | None = None,
|
|
264
|
+
C0: float = 6.5,
|
|
265
|
+
C1: float = 4.4,
|
|
266
|
+
Ewl: float = 0.25,
|
|
267
|
+
t: float = 10,
|
|
268
|
+
phi: float = 0,
|
|
269
|
+
):
|
|
261
270
|
"""
|
|
262
271
|
Calculate cut length at first contanct and steady-state touchdown distance.
|
|
263
272
|
|
|
@@ -279,7 +288,7 @@ def touchdown_distance(
|
|
|
279
288
|
Thickness of the weak layer (mm). Default is 10.
|
|
280
289
|
phi : float, optional
|
|
281
290
|
Inclination of the slab (°). Default is 0.
|
|
282
|
-
|
|
291
|
+
|
|
283
292
|
Returns
|
|
284
293
|
-------
|
|
285
294
|
first_contact : float
|
|
@@ -291,10 +300,16 @@ def touchdown_distance(
|
|
|
291
300
|
Steady-state touchdown distance (mm).
|
|
292
301
|
"""
|
|
293
302
|
# Check if layering is defined
|
|
294
|
-
layers =
|
|
303
|
+
layers = (
|
|
304
|
+
layers
|
|
305
|
+
if layers
|
|
306
|
+
else [
|
|
307
|
+
[240, 200],
|
|
308
|
+
]
|
|
309
|
+
)
|
|
295
310
|
|
|
296
311
|
# Initialize model with user input
|
|
297
|
-
touchdown = weac.Layered(system=
|
|
312
|
+
touchdown = weac.Layered(system="pst-", touchdown=True)
|
|
298
313
|
|
|
299
314
|
# Set material properties
|
|
300
315
|
touchdown.set_foundation_properties(E=Ewl, t=t, update=True)
|
|
@@ -311,7 +326,7 @@ def touchdown_distance(
|
|
|
311
326
|
|
|
312
327
|
# Compute steady-state touchdown distance in a dummy PST with a cut
|
|
313
328
|
# of 5 times the first contact distance
|
|
314
|
-
touchdown.calc_segments(L=1e5, a=5*first_contact, phi=phi)
|
|
329
|
+
touchdown.calc_segments(L=1e5, a=5 * first_contact, phi=phi)
|
|
315
330
|
steady_state = touchdown.calc_lC()
|
|
316
331
|
|
|
317
332
|
# Return first-contact cut length, full-contact cut length,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: weac
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.2
|
|
4
4
|
Summary: Weak layer anticrack nucleation model
|
|
5
|
-
|
|
6
|
-
Author: 2phi GbR
|
|
7
|
-
Author-email: mail@2phi.de
|
|
5
|
+
Author-email: 2phi GbR <mail@2phi.de>
|
|
8
6
|
License: Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/2phi/weac
|
|
9
8
|
Project-URL: Demo, https://github.com/2phi/weac/blob/main/demo/demo.ipynb
|
|
10
9
|
Project-URL: Documentation, https://2phi.github.io/weac
|
|
11
10
|
Project-URL: Issues and feature requests, https://github.com/2phi/weac/issues
|
|
@@ -16,11 +15,26 @@ Classifier: Topic :: Scientific/Engineering
|
|
|
16
15
|
Requires-Python: >=3.10
|
|
17
16
|
Description-Content-Type: text/markdown
|
|
18
17
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: matplotlib
|
|
20
|
-
Requires-Dist: numpy
|
|
21
|
-
Requires-Dist: scipy
|
|
18
|
+
Requires-Dist: matplotlib>=3.9.1
|
|
19
|
+
Requires-Dist: numpy>=2.0.1
|
|
20
|
+
Requires-Dist: scipy>=1.14.0
|
|
22
21
|
Provides-Extra: interactive
|
|
23
22
|
Requires-Dist: jupyter; extra == "interactive"
|
|
23
|
+
Requires-Dist: ipython>=8.12.3; extra == "interactive"
|
|
24
|
+
Requires-Dist: notebook>=7.0.0; extra == "interactive"
|
|
25
|
+
Requires-Dist: ipywidgets>=8.0.0; extra == "interactive"
|
|
26
|
+
Provides-Extra: docs
|
|
27
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
28
|
+
Requires-Dist: sphinxawesome-theme; extra == "docs"
|
|
29
|
+
Provides-Extra: test
|
|
30
|
+
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
37
|
+
Dynamic: license-file
|
|
24
38
|
|
|
25
39
|
<!-- LOGO AND TITLE-->
|
|
26
40
|
<!-- <p align="right"><img src="https://github.com/2phi/weac/raw/main/img/logo.png" alt="Logo" width="80" height="80"></p> -->
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
weac/__init__.py,sha256=QluJIYzVcaSRVJhnjdjrAsqkiemXiBu7-aQdncVct3k,345
|
|
2
|
+
weac/eigensystem.py,sha256=dooypI10GrLXWMGKly-Ym4RrhQ750CsIuPHN0lfDke8,22836
|
|
3
|
+
weac/inverse.py,sha256=IUDtvbioKrkdya5kPWwAeSxgSkV7-iHXNk_W86YnUM8,1890
|
|
4
|
+
weac/layered.py,sha256=CwRx6cVfRqh51vrUCo7EutmghyMM0dW34pUVF8AJX9Q,2086
|
|
5
|
+
weac/mixins.py,sha256=VviOwfkVrGQ8_hvzafYNaIvpHQWpPkWAmVZJRsWWKmc,69369
|
|
6
|
+
weac/plot.py,sha256=0g7MsmssonqVt2tevxdyloKCuA7wOAZ877Hbr7i-44c,21122
|
|
7
|
+
weac/tools.py,sha256=MZ_QrmuWlPiallUu1FH66I-gi0gvWdL3A0LsppkMK0Q,9960
|
|
8
|
+
weac-2.6.2.dist-info/licenses/LICENSE,sha256=CZlY87tZ1Kq7QxKLVrMknnDXGpc1yEZ8SKoXMAk-d4k,1463
|
|
9
|
+
weac-2.6.2.dist-info/METADATA,sha256=xbJG71c6gryCZ-IJSiF3KN_0qsU2d9LuC2Ej-js6fvw,20132
|
|
10
|
+
weac-2.6.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
+
weac-2.6.2.dist-info/top_level.txt,sha256=8tyXUHPFU4Ba_5kPtpwvXo5l6GjJmOnODVBJFygpdeE,5
|
|
12
|
+
weac-2.6.2.dist-info/RECORD,,
|
weac-2.6.0.dist-info/RECORD
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
weac/__init__.py,sha256=mKK2r2XOcQPpaIYJO6ec1M7MYI03uyKgTtiHRhp7VgE,359
|
|
2
|
-
weac/eigensystem.py,sha256=a-RBqON9Sta2c0z412BXgrfxM96heDKNyfiD0PbYLmM,22476
|
|
3
|
-
weac/inverse.py,sha256=pfpE5PaMgKA2sMVk4t-Q6mPJisA-Yyo873XCKI_-HtA,1980
|
|
4
|
-
weac/layered.py,sha256=S18d1PwGrj9K6HFu2u1JBiA94zzM8mX_JiKBGaph9_I,2064
|
|
5
|
-
weac/mixins.py,sha256=NPkhZVwYpcxhMkS9t3ismvfgeQdZZNTg4rz7Y1DH6EQ,70269
|
|
6
|
-
weac/plot.py,sha256=-s0aOV-c2KEgMa5HypiLgIgASsNVz0BR80_7h8J5o68,20705
|
|
7
|
-
weac/tools.py,sha256=ddieeBfXh8APlgxjIf1HuoCjk7UgTSwvS5XKv77dS0M,9961
|
|
8
|
-
weac-2.6.0.dist-info/LICENSE,sha256=CZlY87tZ1Kq7QxKLVrMknnDXGpc1yEZ8SKoXMAk-d4k,1463
|
|
9
|
-
weac-2.6.0.dist-info/METADATA,sha256=tpyRnWRgtJpCzamOcZr1CfmS2paHTLebGD4MczeE9Kg,19484
|
|
10
|
-
weac-2.6.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
11
|
-
weac-2.6.0.dist-info/top_level.txt,sha256=8tyXUHPFU4Ba_5kPtpwvXo5l6GjJmOnODVBJFygpdeE,5
|
|
12
|
-
weac-2.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|