weac 2.6.0__py3-none-any.whl → 2.6.1__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 +1 -1
- weac/mixins.py +426 -427
- weac/tools.py +80 -66
- {weac-2.6.0.dist-info → weac-2.6.1.dist-info}/METADATA +10 -7
- weac-2.6.1.dist-info/RECORD +12 -0
- weac-2.6.0.dist-info/RECORD +0 -12
- {weac-2.6.0.dist-info → weac-2.6.1.dist-info}/LICENSE +0 -0
- {weac-2.6.0.dist-info → weac-2.6.1.dist-info}/WHEEL +0 -0
- {weac-2.6.0.dist-info → weac-2.6.1.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,7 +206,7 @@ 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
212
|
def bergfeld(rho, rho0=917, C0=6.5, C1=4.4):
|
|
@@ -222,10 +231,10 @@ 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
239
|
Estimate the tensile strenght of a slab layer from its density.
|
|
231
240
|
|
|
@@ -243,21 +252,20 @@ def tensile_strength_slab(rho, unit='kPa'):
|
|
|
243
252
|
ndarray
|
|
244
253
|
Tensile strenght in specified unit.
|
|
245
254
|
"""
|
|
246
|
-
convert = {
|
|
247
|
-
'kPa': 1,
|
|
248
|
-
'MPa': 1e-3
|
|
249
|
-
}
|
|
255
|
+
convert = {"kPa": 1, "MPa": 1e-3}
|
|
250
256
|
rho_ice = 917
|
|
251
257
|
# Sigrist's equation is given in kPa
|
|
252
|
-
return convert[unit]*240*(rho/rho_ice)**2.44
|
|
258
|
+
return convert[unit] * 240 * (rho / rho_ice) ** 2.44
|
|
259
|
+
|
|
253
260
|
|
|
254
261
|
def touchdown_distance(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
262
|
+
layers: np.ndarray | str | None = None,
|
|
263
|
+
C0: float = 6.5,
|
|
264
|
+
C1: float = 4.4,
|
|
265
|
+
Ewl: float = 0.25,
|
|
266
|
+
t: float = 10,
|
|
267
|
+
phi: float = 0,
|
|
268
|
+
):
|
|
261
269
|
"""
|
|
262
270
|
Calculate cut length at first contanct and steady-state touchdown distance.
|
|
263
271
|
|
|
@@ -279,7 +287,7 @@ def touchdown_distance(
|
|
|
279
287
|
Thickness of the weak layer (mm). Default is 10.
|
|
280
288
|
phi : float, optional
|
|
281
289
|
Inclination of the slab (°). Default is 0.
|
|
282
|
-
|
|
290
|
+
|
|
283
291
|
Returns
|
|
284
292
|
-------
|
|
285
293
|
first_contact : float
|
|
@@ -291,10 +299,16 @@ def touchdown_distance(
|
|
|
291
299
|
Steady-state touchdown distance (mm).
|
|
292
300
|
"""
|
|
293
301
|
# Check if layering is defined
|
|
294
|
-
layers =
|
|
302
|
+
layers = (
|
|
303
|
+
layers
|
|
304
|
+
if layers
|
|
305
|
+
else [
|
|
306
|
+
[240, 200],
|
|
307
|
+
]
|
|
308
|
+
)
|
|
295
309
|
|
|
296
310
|
# Initialize model with user input
|
|
297
|
-
touchdown = weac.Layered(system=
|
|
311
|
+
touchdown = weac.Layered(system="pst-", touchdown=True)
|
|
298
312
|
|
|
299
313
|
# Set material properties
|
|
300
314
|
touchdown.set_foundation_properties(E=Ewl, t=t, update=True)
|
|
@@ -311,7 +325,7 @@ def touchdown_distance(
|
|
|
311
325
|
|
|
312
326
|
# Compute steady-state touchdown distance in a dummy PST with a cut
|
|
313
327
|
# of 5 times the first contact distance
|
|
314
|
-
touchdown.calc_segments(L=1e5, a=5*first_contact, phi=phi)
|
|
328
|
+
touchdown.calc_segments(L=1e5, a=5 * first_contact, phi=phi)
|
|
315
329
|
steady_state = touchdown.calc_lC()
|
|
316
330
|
|
|
317
331
|
# Return first-contact cut length, full-contact cut length,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: weac
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.1
|
|
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,15 @@ 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
|
+
Provides-Extra: docs
|
|
25
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
26
|
+
Requires-Dist: sphinxawesome-theme; extra == "docs"
|
|
24
27
|
|
|
25
28
|
<!-- LOGO AND TITLE-->
|
|
26
29
|
<!-- <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=ZGf0IghYj2r180TrU4HX4dH40LPbU8G2SBjDQU1R2ec,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=KRAAZc5fuKxq-RTNWJ48vGV410uBoeiJnZQ-eVBUm4c,69298
|
|
6
|
+
weac/plot.py,sha256=-s0aOV-c2KEgMa5HypiLgIgASsNVz0BR80_7h8J5o68,20705
|
|
7
|
+
weac/tools.py,sha256=cONo43EQ0LHtbCZcbBmda085h2rI8BCbj98SQUdyEgE,9910
|
|
8
|
+
weac-2.6.1.dist-info/LICENSE,sha256=CZlY87tZ1Kq7QxKLVrMknnDXGpc1yEZ8SKoXMAk-d4k,1463
|
|
9
|
+
weac-2.6.1.dist-info/METADATA,sha256=zo_RgP0qeIA-5ezvE4Chbe4XQIh_BHjtwfXGTcM66gI,19679
|
|
10
|
+
weac-2.6.1.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
11
|
+
weac-2.6.1.dist-info/top_level.txt,sha256=8tyXUHPFU4Ba_5kPtpwvXo5l6GjJmOnODVBJFygpdeE,5
|
|
12
|
+
weac-2.6.1.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
|
|
File without changes
|