weac 3.1.0__py3-none-any.whl → 3.1.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 CHANGED
@@ -2,4 +2,4 @@
2
2
  WEAC - Weak Layer Anticrack Nucleation Model
3
3
  """
4
4
 
5
- __version__ = "3.1.0"
5
+ __version__ = "3.1.1"
weac/analysis/analyzer.py CHANGED
@@ -272,11 +272,7 @@ class Analyzer:
272
272
 
273
273
  # Calculate weight load at grid points and superimpose on stress field
274
274
  qt = -rho * G_MM_S2 * np.sin(np.deg2rad(phi))
275
- # Old Implementation: Changed for numerical stability
276
- # for i, qi in enumerate(qt[:-1]):
277
- # Sxx[i, :] += qi * (zi[i + 1] - zi[i])
278
- # Sxx[-1, :] += qt[-1] * (zi[-1] - zi[-2])
279
- # New Implementation: Changed for numerical stability
275
+
280
276
  dz = np.diff(zi)
281
277
  Sxx_MPa[:-1, :] += qt[:-1, np.newaxis] * dz[:, np.newaxis]
282
278
  Sxx_MPa[-1, :] += qt[-1] * dz[-1]
@@ -393,7 +389,7 @@ class Analyzer:
393
389
  # Get mesh along z-axis
394
390
  zmesh = self.get_zmesh(dz=dz)
395
391
  zi = zmesh["z"]
396
- rho = zmesh["rho"]
392
+ rho_t_mm3 = zmesh["rho"]
397
393
  qs = self.sm.scenario.surface_load
398
394
  # Get dimensions of stress field (n rows, m columns)
399
395
  n = len(zi)
@@ -414,13 +410,13 @@ class Analyzer:
414
410
  dsxx_dxdx[i, :] = E / (1 - nu**2) * (du0_dxdxdx + z * dpsi_dxdxdx)
415
411
 
416
412
  # Calculate weight load at grid points
417
- qn = rho * G_MM_S2 * np.cos(np.deg2rad(phi))
413
+ qn = -rho_t_mm3 * G_MM_S2 * np.cos(np.deg2rad(phi))
418
414
 
419
415
  # Integrate dsxx_dxdx twice along z to obtain transverse
420
416
  # normal stress Szz in MPa
421
417
  integrand = cumulative_trapezoid(dsxx_dxdx, zi, axis=0, initial=0)
422
418
  Szz_MPa = cumulative_trapezoid(integrand, zi, axis=0, initial=0)
423
- Szz_MPa += cumulative_trapezoid(-qn, zi, initial=0)[:, None]
419
+ Szz_MPa += cumulative_trapezoid(qn, zi, initial=0)[:, None]
424
420
 
425
421
  # Normalize tensile stresses to tensile strength
426
422
  if normalize:
@@ -113,6 +113,9 @@ class MaximalStressResult:
113
113
  The normalized maximum principal stress to the tensile strength of the layers.
114
114
  max_Sxx_norm: float
115
115
  The normalized maximum axial normal stress to the tensile strength of the layers.
116
+ slab_tensile_criterion: float
117
+ The slab tensile criterion, i.e. the portion of the slab thickness that is prone
118
+ to fail under tensile stresses in the steady state (between 0 and 1).
116
119
  """
117
120
 
118
121
  principal_stress_kPa: np.ndarray
@@ -121,6 +124,7 @@ class MaximalStressResult:
121
124
  Sxx_norm: np.ndarray
122
125
  max_principal_stress_norm: float
123
126
  max_Sxx_norm: float
127
+ slab_tensile_criterion: float
124
128
 
125
129
 
126
130
  @dataclass
@@ -706,9 +710,9 @@ class CriteriaEvaluator:
706
710
  UserWarning,
707
711
  )
708
712
  system_copy = copy.deepcopy(system)
709
- system_copy.config.touchdown = True
713
+ system_copy.toggle_touchdown(True)
710
714
  system_copy.update_scenario(scenario_config=ScenarioConfig(phi=0.0))
711
- l_BC = system.slab_touchdown.l_BC
715
+ l_BC = system_copy.slab_touchdown.l_BC
712
716
 
713
717
  segments = [
714
718
  Segment(length=5e3, has_foundation=True, m=0.0),
@@ -719,7 +723,6 @@ class CriteriaEvaluator:
719
723
  phi=0.0, # Slab Touchdown works only for flat slab
720
724
  cut_length=2 * l_BC,
721
725
  )
722
- # system_copy.config.touchdown = True
723
726
  system_copy.update_scenario(segments=segments, scenario_config=scenario_config)
724
727
  touchdown_distance = system_copy.slab_touchdown.touchdown_distance
725
728
  analyzer = Analyzer(system_copy, printing_enabled=print_call_stats)
@@ -1248,6 +1251,9 @@ class CriteriaEvaluator:
1248
1251
  )
1249
1252
  max_principal_stress_norm = np.max(principal_stress_norm)
1250
1253
  max_Sxx_norm = np.max(Sxx_norm)
1254
+ # evaluate for each height level if the slab is prone to fail under tensile stresses
1255
+ height_level_prone_to_fail = np.max(Sxx_norm, axis=1)
1256
+ slab_tensile_criterion = np.mean(height_level_prone_to_fail)
1251
1257
  if print_call_stats:
1252
1258
  analyzer.print_call_stats(
1253
1259
  message="_calculate_maximal_stresses Call Statistics"
@@ -1259,4 +1265,5 @@ class CriteriaEvaluator:
1259
1265
  Sxx_norm=Sxx_norm,
1260
1266
  max_principal_stress_norm=max_principal_stress_norm,
1261
1267
  max_Sxx_norm=max_Sxx_norm,
1268
+ slab_tensile_criterion=slab_tensile_criterion,
1262
1269
  )
weac/analysis/plotter.py CHANGED
@@ -1041,6 +1041,7 @@ class Plotter:
1041
1041
  xwl: np.ndarray,
1042
1042
  z: np.ndarray,
1043
1043
  analyzer: Analyzer,
1044
+ window: float | None = None,
1044
1045
  weaklayer_proportion: float | None = None,
1045
1046
  dz: int = 2,
1046
1047
  levels: int = 300,
@@ -1061,6 +1062,8 @@ class Plotter:
1061
1062
  Solution vector.
1062
1063
  analyzer : Analyzer
1063
1064
  Analyzer instance.
1065
+ window: float | None, optional
1066
+ Window size for the plot. Shows the right edge of the slab, where the slab is deformed. Default is None.
1064
1067
  weaklayer_proportion: float | None, optional
1065
1068
  Proportion of the plot to allocate to the weak layer. Default is None.
1066
1069
  dz : int, optional
@@ -1087,6 +1090,9 @@ class Plotter:
1087
1090
  phi = analyzer.sm.scenario.phi
1088
1091
  system_type = analyzer.sm.scenario.system_type
1089
1092
  fq = analyzer.sm.fq
1093
+ sigma_comp = (
1094
+ analyzer.sm.weak_layer.sigma_comp
1095
+ ) # Compressive strength of the weak layer [kPa]
1090
1096
 
1091
1097
  # Compute slab displacements on grid (cm)
1092
1098
  Usl = np.vstack([fq.u(z, h0=h0, unit="cm") for h0 in zi])
@@ -1204,7 +1210,7 @@ class Plotter:
1204
1210
  z, phi, dz=dz, val="max", unit="kPa", normalize=normalize
1205
1211
  )
1206
1212
  weak_full = analyzer.principal_stress_weaklayer(
1207
- z, val="min", unit="kPa", normalize=normalize
1213
+ z, sc=sigma_comp, val="min", unit="kPa", normalize=normalize
1208
1214
  )
1209
1215
  weak = weak_full[nanmask]
1210
1216
  if normalize:
@@ -1249,13 +1255,14 @@ class Plotter:
1249
1255
  [slab_proportion + cracked_proportion, total_height_plot],
1250
1256
  )
1251
1257
  # No displacements for the cracked weak layer outline (undeformed)
1252
- ax.plot(
1253
- _outline(Xwl_cracked),
1254
- _outline(Zwl_cracked_plot),
1255
- "k-",
1256
- alpha=0.3,
1257
- linewidth=1,
1258
- )
1258
+ if xwl_cracked.shape[0] > 0:
1259
+ ax.plot(
1260
+ _outline(Xwl_cracked),
1261
+ _outline(Zwl_cracked_plot),
1262
+ "k-",
1263
+ alpha=0.3,
1264
+ linewidth=1,
1265
+ )
1259
1266
 
1260
1267
  # Then plot the deformed weak-layer outline where it exists
1261
1268
  if system_type in ["-pst", "pst-", "-vpst", "vpst-"]:
@@ -1287,14 +1294,15 @@ class Plotter:
1287
1294
  cmap=cmap,
1288
1295
  extend="both",
1289
1296
  )
1290
- ax.contourf(
1291
- Xwl_cracked,
1292
- Zwl_cracked_plot,
1293
- np.zeros((2, xwl_cracked.shape[0])),
1294
- levels=levels,
1295
- cmap=cmap,
1296
- extend="both",
1297
- )
1297
+ if xwl_cracked.shape[0] > 0:
1298
+ ax.contourf(
1299
+ Xwl_cracked,
1300
+ Zwl_cracked_plot,
1301
+ np.zeros((2, xwl_cracked.shape[0])),
1302
+ levels=levels,
1303
+ cmap=cmap,
1304
+ extend="both",
1305
+ )
1298
1306
 
1299
1307
  # Plot setup
1300
1308
  # Set y-limits to match plot coordinate system (0 to total_height_plot = 1.0)
@@ -1304,7 +1312,10 @@ class Plotter:
1304
1312
  )
1305
1313
 
1306
1314
  # Set limits first, then aspect ratio to avoid matplotlib adjusting limits
1307
- ax.set_xlim([xmin, xmax])
1315
+ if window is None:
1316
+ ax.set_xlim([xmin, xmax])
1317
+ else:
1318
+ ax.set_xlim([xmax - window, xmax])
1308
1319
  ax.set_ylim([plot_ymin, plot_ymax])
1309
1320
  ax.invert_yaxis()
1310
1321
  ax.use_sticky_edges = False
@@ -1360,6 +1371,10 @@ class Plotter:
1360
1371
 
1361
1372
  # Plot labels
1362
1373
  ax.set_xlabel(r"lateral position $x$ (cm) $\longrightarrow$")
1374
+ ax.set_title(
1375
+ f"{field}{' (normalized to tensile strength)' if normalize else ''}",
1376
+ size=10,
1377
+ )
1363
1378
 
1364
1379
  # Show colorbar
1365
1380
  ticks = np.linspace(levels[0], levels[-1], num=11, endpoint=True)
weac/components/layer.py CHANGED
@@ -94,6 +94,10 @@ def _sigrist_tensile_strength(rho, unit: Literal["kPa", "MPa"] = "kPa"):
94
94
  return convert[unit] * 240 * (rho / RHO_ICE) ** 2.44
95
95
 
96
96
 
97
+ # TODO: Compressive Strength from Schöttner
98
+ # (11 +/- 7) * (rho/rho_0) ^ (5.4 +/- 0.5)
99
+
100
+
97
101
  class Layer(BaseModel):
98
102
  """
99
103
  Regular slab layer (no foundation springs).
@@ -225,6 +229,9 @@ class WeakLayer(BaseModel):
225
229
  )
226
230
  sigma_c: float = Field(default=6.16, gt=0, description="Tensile strength [kPa]")
227
231
  tau_c: float = Field(default=5.09, gt=0, description="Shear strength [kPa]")
232
+ sigma_comp: float = Field(
233
+ default=2.6, gt=0, description="Compressive strength [kPa]"
234
+ )
228
235
  E_method: Literal["bergfeld", "scapazzo", "gerling"] = Field(
229
236
  default="bergfeld",
230
237
  description="Method to calculate the Young's modulus",
@@ -58,19 +58,23 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
58
58
  h0: float = 0,
59
59
  unit: LengthUnit = "mm",
60
60
  ) -> float | np.ndarray:
61
- """Horizontal displacement *u = u₀ + h₀ ψ* at depth h₀."""
61
+ """
62
+ Horizontal displacement `u = u₀ + h₀ ψ` at depth `h₀` (mm).
63
+ """
62
64
  return self._unit_factor(unit) * (Z[0, :] + h0 * self.psi(Z))
63
65
 
64
66
  def du_dx(self, Z: np.ndarray, h0: float) -> float | np.ndarray:
65
- """Derivative u' = u₀' + h₀ ψ'."""
67
+ """Derivative u' = u₀' + h₀ ψ' (-)."""
66
68
  return Z[1, :] + h0 * self.dpsi_dx(Z)
67
69
 
68
70
  def w(self, Z: np.ndarray, unit: LengthUnit = "mm") -> float | np.ndarray:
69
- """Center-line deflection *w*."""
71
+ """
72
+ Center-line (vertical) deflection `w` (mm).
73
+ """
70
74
  return self._unit_factor(unit) * Z[2, :]
71
75
 
72
76
  def dw_dx(self, Z: np.ndarray) -> float | np.ndarray:
73
- """First derivative w'."""
77
+ """First derivative `w'` (-)."""
74
78
  return Z[3, :]
75
79
 
76
80
  def psi(
@@ -78,32 +82,32 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
78
82
  Z: np.ndarray,
79
83
  unit: AngleUnit = "rad",
80
84
  ) -> float | np.ndarray:
81
- """Rotation ψ of the mid-plane."""
85
+ """Rotation `ψ` of the mid-plane (rad)."""
82
86
  factor = self._unit_factor(unit)
83
87
  return factor * Z[4, :]
84
88
 
85
89
  def dpsi_dx(self, Z: np.ndarray) -> float | np.ndarray:
86
- """First derivative ψ′."""
90
+ """First derivative `ψ'` (rad/mm)."""
87
91
  return Z[5, :]
88
92
 
89
93
  def N(self, Z: np.ndarray) -> float | np.ndarray:
90
- """Axial normal force N = A11 u' + B11 psi' in the slab [N]"""
94
+ """Axial normal force `N = A11 u' + B11 ψ'` in the slab [N]"""
91
95
  return self.es.A11 * Z[1, :] + self.es.B11 * Z[5, :]
92
96
 
93
97
  def M(self, Z: np.ndarray) -> float | np.ndarray:
94
- """Bending moment M = B11 u' + D11 psi' in the slab [Nmm]"""
98
+ """Bending moment `M = B11 u' + D11 ψ'` in the slab [Nmm]"""
95
99
  return self.es.B11 * Z[1, :] + self.es.D11 * Z[5, :]
96
100
 
97
101
  def V(self, Z: np.ndarray) -> float | np.ndarray:
98
- """Vertical shear force V = kA55(w' + psi) [N]"""
102
+ """Vertical shear force `V = kA55(w' + ψ)` [N]"""
99
103
  return self.es.kA55 * (Z[3, :] + Z[4, :])
100
104
 
101
105
  def sig(self, Z: np.ndarray, unit: StressUnit = "MPa") -> float | np.ndarray:
102
- """Weak-layer normal stress"""
106
+ """Weak-layer normal stress `sig = -kn * w`"""
103
107
  return -self._unit_factor(unit) * self.es.weak_layer.kn * self.w(Z)
104
108
 
105
109
  def tau(self, Z: np.ndarray, unit: StressUnit = "MPa") -> float | np.ndarray:
106
- """Weak-layer shear stress"""
110
+ """Weak-layer shear stress `tau = -kt * (w' * h/2 - u(h=H/2))`"""
107
111
  return (
108
112
  -self._unit_factor(unit)
109
113
  * self.es.weak_layer.kt
@@ -114,11 +118,11 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
114
118
  )
115
119
 
116
120
  def eps(self, Z: np.ndarray) -> float | np.ndarray:
117
- """Weak-layer normal strain"""
121
+ """Weak-layer normal strain `eps = -w / h`"""
118
122
  return -self.w(Z) / self.es.weak_layer.h
119
123
 
120
124
  def gamma(self, Z: np.ndarray) -> float | np.ndarray:
121
- """Weak-layer shear strain."""
125
+ """Weak-layer shear strain `gamma = (w' * h/2 - u(h=H/2)) / h`"""
122
126
  return (
123
127
  self.dw_dx(Z) / 2 - self.u(Z, h0=self.es.slab.H / 2) / self.es.weak_layer.h
124
128
  )
@@ -176,9 +180,9 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
176
180
 
177
181
  def dz_dxdx(self, z: np.ndarray, phi: float, qs: float) -> np.ndarray:
178
182
  """
179
- Get second derivative z''(x) = K*z'(x) of the solution vector.
183
+ Get second derivative `z''(x) = K*z'(x)` of the solution vector.
180
184
 
181
- z''(x) = [u''(x) u'''(x) w''(x) w'''(x) psi''(x), psi'''(x)]^T
185
+ `z''(x) = [u''(x) u'''(x) w''(x) w'''(x) psi''(x), psi'''(x)]^T`
182
186
 
183
187
  Parameters
184
188
  ----------
@@ -200,7 +204,7 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
200
204
 
201
205
  def du0_dxdx(self, z: np.ndarray, phi: float, qs: float) -> float | np.ndarray:
202
206
  """
203
- Get second derivative of the horiz. centerline displacement u0''(x).
207
+ Get second derivative of the horiz. centerline displacement `u0''(x)` (mm⁻¹).
204
208
 
205
209
  Parameters
206
210
  ----------
@@ -213,13 +217,13 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
213
217
  -------
214
218
  ndarray, float
215
219
  Second derivative of the horizontal centerline displacement
216
- u0''(x) (1/mm).
220
+ `u0''(x)`.
217
221
  """
218
222
  return self.dz_dx(z, phi, qs)[1, :]
219
223
 
220
224
  def dpsi_dxdx(self, z: np.ndarray, phi: float, qs: float) -> float | np.ndarray:
221
225
  """
222
- Get second derivative of the cross-section rotation psi''(x).
226
+ Get second derivative of the cross-section rotation `psi''(x)` (mm⁻²).
223
227
 
224
228
  Parameters
225
229
  ----------
@@ -231,13 +235,13 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
231
235
  Returns
232
236
  -------
233
237
  ndarray, float
234
- Second derivative of the cross-section rotation psi''(x) (1/mm^2).
238
+ Second derivative of the cross-section rotation psi''(x).
235
239
  """
236
240
  return self.dz_dx(z, phi, qs)[5, :]
237
241
 
238
242
  def du0_dxdxdx(self, z: np.ndarray, phi: float, qs: float) -> float | np.ndarray:
239
243
  """
240
- Get third derivative of the horiz. centerline displacement u0'''(x).
244
+ Get third derivative of the horiz. centerline displacement `u0'''(x)` (mm⁻²).
241
245
 
242
246
  Parameters
243
247
  ----------
@@ -250,13 +254,13 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
250
254
  -------
251
255
  ndarray, float
252
256
  Third derivative of the horizontal centerline displacement
253
- u0'''(x) (1/mm^2).
257
+ u0'''(x).
254
258
  """
255
259
  return self.dz_dxdx(z, phi, qs)[1, :]
256
260
 
257
261
  def dpsi_dxdxdx(self, z: np.ndarray, phi: float, qs: float) -> float | np.ndarray:
258
262
  """
259
- Get third derivative of the cross-section rotation psi'''(x).
263
+ Get third derivative of the cross-section rotation `psi'''(x)` (mm⁻³).
260
264
 
261
265
  Parameters
262
266
  ----------
@@ -268,6 +272,6 @@ class FieldQuantities: # pylint: disable=too-many-instance-attributes, too-many
268
272
  Returns
269
273
  -------
270
274
  ndarray, float
271
- Third derivative of the cross-section rotation psi'''(x) (1/mm^3).
275
+ Third derivative of the cross-section rotation psi'''(x).
272
276
  """
273
277
  return self.dz_dxdx(z, phi, qs)[5, :]
@@ -273,17 +273,17 @@ class UnknownConstantsSolver:
273
273
  Arguments
274
274
  ---------
275
275
  zl : ndarray
276
- Solution vector (6x1) or (6x6) at left end of beam segement.
276
+ Solution vector (6x1) or (6x6) at left end of beam segment.
277
277
  zr : ndarray
278
- Solution vector (6x1) or (6x6) at right end of beam segement.
278
+ Solution vector (6x1) or (6x6) at right end of beam segment.
279
279
  has_foundation : boolean
280
280
  Indicates whether segment has foundation(True) or not (False).
281
281
  Default is False.
282
282
  pos: {'left', 'mid', 'right', 'l', 'm', 'r'}, optional
283
- Determines whether the segement under consideration
284
- is a left boundary segement (left, l), one of the
285
- center segement (mid, m), or a right boundary
286
- segement (right, r). Default is 'mid'.
283
+ Determines whether the segment under consideration
284
+ is a left boundary segment (left, l), one of the
285
+ center segment (mid, m), or a right boundary
286
+ segment (right, r). Default is 'mid'.
287
287
 
288
288
  Returns
289
289
  -------
@@ -310,7 +310,7 @@ class UnknownConstantsSolver:
310
310
  bcs[2],
311
311
  fq.u(zr, h0=0), # ui(xi = li)
312
312
  fq.w(zr), # wi(xi = li)
313
- fq.psi(zr), # psii(xi = li)
313
+ fq.psi(zr), # psi(xi = li)
314
314
  fq.N(zr), # Ni(xi = li)
315
315
  fq.M(zr), # Mi(xi = li)
316
316
  fq.V(zr), # Vi(xi = li)
@@ -321,13 +321,13 @@ class UnknownConstantsSolver:
321
321
  [
322
322
  -fq.u(zl, h0=0), # -ui(xi = 0)
323
323
  -fq.w(zl), # -wi(xi = 0)
324
- -fq.psi(zl), # -psii(xi = 0)
324
+ -fq.psi(zl), # -psi(xi = 0)
325
325
  -fq.N(zl), # -Ni(xi = 0)
326
326
  -fq.M(zl), # -Mi(xi = 0)
327
327
  -fq.V(zl), # -Vi(xi = 0)
328
328
  fq.u(zr, h0=0), # ui(xi = li)
329
329
  fq.w(zr), # wi(xi = li)
330
- fq.psi(zr), # psii(xi = li)
330
+ fq.psi(zr), # psi(xi = li)
331
331
  fq.N(zr), # Ni(xi = li)
332
332
  fq.M(zr), # Mi(xi = li)
333
333
  fq.V(zr), # Vi(xi = li)
@@ -347,7 +347,7 @@ class UnknownConstantsSolver:
347
347
  [
348
348
  -fq.u(zl, h0=0), # -ui(xi = 0)
349
349
  -fq.w(zl), # -wi(xi = 0)
350
- -fq.psi(zl), # -psii(xi = 0)
350
+ -fq.psi(zl), # -psi(xi = 0)
351
351
  -fq.N(zl), # -Ni(xi = 0)
352
352
  -fq.M(zl), # -Mi(xi = 0)
353
353
  -fq.V(zl), # -Vi(xi = 0)
@@ -385,9 +385,9 @@ class UnknownConstantsSolver:
385
385
  Default is False.
386
386
  pos : {'left', 'mid', 'right', 'l', 'm', 'r'}, optional
387
387
  Determines whether the segement under consideration
388
- is a left boundary segement (left, l), one of the
389
- center segement (mid, m), or a right boundary
390
- segement (right, r). Default is 'mid'.
388
+ is a left boundary segment (left, l), one of the
389
+ center segment (mid, m), or a right boundary
390
+ segment (right, r). Default is 'mid'.
391
391
 
392
392
  Returns
393
393
  -------
weac/utils/geldsetzer.py CHANGED
@@ -82,18 +82,23 @@ HAND_HARDNESS = {
82
82
  "F-": 0.67,
83
83
  "F": 1,
84
84
  "F+": 1.33,
85
+ "F-4F": 1.5,
85
86
  "4F-": 1.67,
86
87
  "4F": 2,
87
88
  "4F+": 2.33,
89
+ "4F-1F": 2.5,
88
90
  "1F-": 2.67,
89
91
  "1F": 3,
90
92
  "1F+": 3.33,
93
+ "1F-P": 3.5,
91
94
  "P-": 3.67,
92
95
  "P": 4,
93
96
  "P+": 4.33,
97
+ "P-K": 4.5,
94
98
  "K-": 4.67,
95
99
  "K": 5,
96
100
  "K+": 5.33,
101
+ "K-I": 5.5,
97
102
  "I-": 5.67,
98
103
  "I": 6,
99
104
  "I+": 6.33,
@@ -117,18 +122,23 @@ HAND_HARDNESS_TO_DENSITY = {
117
122
  "F-": 71.7,
118
123
  "F": 103.7,
119
124
  "F+": 118.4,
125
+ "F-4F": 123.15,
120
126
  "4F-": 127.9,
121
127
  "4F": 158.2,
122
128
  "4F+": 163.7,
129
+ "4F-1F": 176.15,
123
130
  "1F-": 188.6,
124
131
  "1F": 208,
125
132
  "1F+": 224.4,
133
+ "1F-P": 238.6,
126
134
  "P-": 252.8,
127
135
  "P": 275.9,
128
136
  "P+": 314.6,
137
+ "P-K": 336.85,
129
138
  "K-": 359.1,
130
139
  "K": 347.4,
131
140
  "K+": 407.8,
141
+ "K-I": 407.8,
132
142
  "I-": 407.8,
133
143
  "I": 407.8,
134
144
  "I+": 407.8,
weac/utils/snow_types.py CHANGED
@@ -65,18 +65,23 @@ class HandHardness(str, Enum):
65
65
  Fm = "F-"
66
66
  F = "F"
67
67
  Fp = "F+"
68
+ F_4F = "F-4F"
68
69
  _4Fm = "4F-"
69
70
  _4F = "4F"
70
71
  _4Fp = "4F+"
72
+ _4F_1F = "4F-1F"
71
73
  _1Fm = "1F-"
72
74
  _1F = "1F"
73
75
  _1Fp = "1F+"
76
+ _1F_P = "1F-P"
74
77
  Pm = "P-"
75
78
  P = "P"
76
79
  Pp = "P+"
80
+ P_K = "P-K"
77
81
  Km = "K-"
78
82
  K = "K"
79
83
  Kp = "K+"
84
+ K_I = "K-I"
80
85
  Im = "I-"
81
86
  I = "I"
82
87
  Ip = "I+"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weac
3
- Version: 3.1.0
3
+ Version: 3.1.1
4
4
  Summary: Weak layer anticrack nucleation model
5
5
  Author-email: 2phi GbR <mail@2phi.de>
6
6
  License-Expression: MIT
@@ -17,7 +17,7 @@ Requires-Python: >=3.12
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  Requires-Dist: matplotlib>=3.9.1
20
- Requires-Dist: numpy>=2.0.1
20
+ Requires-Dist: numpy<2.4.0,>=2.3.5
21
21
  Requires-Dist: scipy>=1.14.0
22
22
  Requires-Dist: pydantic>=2.11.7
23
23
  Requires-Dist: snowpylot>=1.1.3
@@ -1,32 +1,32 @@
1
- weac/__init__.py,sha256=kXYZMl1LWws7VLAGdIwS5HzKkzmlgH3PVBeN8JOoCQg,76
1
+ weac/__init__.py,sha256=kgTwOD6mYTXI3qvj9z5uFDNJH84Toa29jQuKAu-5P_M,76
2
2
  weac/constants.py,sha256=BX8ifZhFciCuzzako1p-2Wh5CWWzR3cPdvyu501UtUs,1194
3
3
  weac/logging_config.py,sha256=GJn4Fs80dDRpbPkSPByCmIOLkEI01dbeuMMSv_IDgoM,1103
4
4
  weac/analysis/__init__.py,sha256=FDbmQLC5zmT8OJftqNYgihXc8WYB1b9FasFPGzkKVU8,498
5
- weac/analysis/analyzer.py,sha256=JbtOK35mWlHq6eI8eD2vdZcsClhWl1r6I72-_9mS1Yk,29352
6
- weac/analysis/criteria_evaluator.py,sha256=B8Y-_qXJX4rKaE8JgKONqaYYjFoqlHv75WeFTNMUvjk,47148
7
- weac/analysis/plotter.py,sha256=lZXE6mHmIDwe9Y4wWmk_P8Tf0HmV2ruKVwFd5b25qdA,79860
5
+ weac/analysis/analyzer.py,sha256=-yoOqsdQvpNvBc-U2nqB4UEKHGTMBu23lVPJqKxUVcs,29095
6
+ weac/analysis/criteria_evaluator.py,sha256=yiKQV6ccgNnDMEky18zlHT3YfvoxdqCQtnPHKhbnrJA,47624
7
+ weac/analysis/plotter.py,sha256=ibkH4rzQ2pqQVXPRfek722e8eU3vP63uysb-Q-EzfC0,80556
8
8
  weac/components/__init__.py,sha256=94WIUVjPI3U-grN_7v0oi9bZB3Z8rCBcx9wJPOwJBAQ,439
9
9
  weac/components/config.py,sha256=tnOnJ0M-_knZBhdr052nDyyFFAZN0f2hQ68XRuXG6d8,869
10
10
  weac/components/criteria_config.py,sha256=f2agU7nXWURFAw8_68igiSk5aICUxwaB9u3Qasit-Q0,2909
11
- weac/components/layer.py,sha256=sF47006ORRmNnHW7QMk9h-M0vQQR6TL_PKOvInjdNsk,10560
11
+ weac/components/layer.py,sha256=kfghjavzCqzzGrkKzllMMT4qD3F0pcYfk1ZHgM6rvE0,10755
12
12
  weac/components/model_input.py,sha256=oyX4p7PgaAtUXXtpvV8XO_KxwOXtG1TB0x7rXxNfCFA,3330
13
13
  weac/components/scenario_config.py,sha256=Tam-m9DQtdjmTm-lKQ8Dcjqje04ttJS2X3v_Nn7AUHQ,2563
14
14
  weac/components/segment.py,sha256=F279KcAAkRuJKWav_BZ4BanO96WZm4KXtKHinFZki7s,941
15
15
  weac/core/__init__.py,sha256=pRyCKD8XD3qXVUWtFG7N3cS91P5x5d8Jpr1hMEgxQ2U,233
16
16
  weac/core/eigensystem.py,sha256=b7KXi2weCY9IVlH_7lCTXzKSx_pLdWY-x8BPjHL5nKo,13736
17
- weac/core/field_quantities.py,sha256=ci7MvhJ4aYdbW6xxH8vHVgWtk5iypCYv6dZ6KjFNvt8,8964
17
+ weac/core/field_quantities.py,sha256=rr0KvM5Eu9AR43CQrrODJJkXkM2b2N3BWk2dE38f64c,9175
18
18
  weac/core/scenario.py,sha256=vHHe-JDWc-8ECVfy6lFGVtJmIIKRc0J9iUEGR8zckdw,6050
19
19
  weac/core/slab.py,sha256=YwbAf7ogYDn3p0nXfj3IjVqwA6ro3jBSg2wXb_io_gQ,5125
20
20
  weac/core/slab_touchdown.py,sha256=k30FyvclH_Q3mCZNTbJkNhSenv3ja6qSNhhkmi5p04A,14009
21
21
  weac/core/system_model.py,sha256=HAZuquY6p1wf5QuUPA6VOVDIICeCxOaeXqk1dSfEzNY,15513
22
- weac/core/unknown_constants_solver.py,sha256=pzE7soTo7v-jdDECa21pOWRGBp8YeMU3k7egJOemfSY,17766
22
+ weac/core/unknown_constants_solver.py,sha256=kzB8351UC03rVcJWez0FAwdawI2tERbpcgqMRKgYbi8,17753
23
23
  weac/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- weac/utils/geldsetzer.py,sha256=DxvpqmWulBacl-mGeAmAuJcv2xqFBx92PEfNC3aeDzk,3500
24
+ weac/utils/geldsetzer.py,sha256=Rmn_PUyeomPLfxZlj9LDbdBBRDWovavrQenka318TIM,3681
25
25
  weac/utils/misc.py,sha256=lGz0IDDJ_3nvYjSkivPJ5Xscl1D_AmvQLSjaL7SUbKs,3674
26
- weac/utils/snow_types.py,sha256=eX9-5La6Oom7zh6pg5JZ4MZ6nLdWdc7RoUzm5e6b9w8,1483
26
+ weac/utils/snow_types.py,sha256=OKSY8LzfKycSjg7uSUZkSXUzwhcw1D1fZs5S3hVQtUM,1573
27
27
  weac/utils/snowpilot_parser.py,sha256=drOLnUg7uzMJMO9qU9x79xZkqQfFPCCQonVpU9S0x8U,13682
28
- weac-3.1.0.dist-info/licenses/LICENSE,sha256=ojZPWKFHbFGDrlNOvuAKGH9WcKhpLHWZPcQ4SzhK91M,1082
29
- weac-3.1.0.dist-info/METADATA,sha256=Lkr3EVyJEoTwmFglEhx8aI01zqjivnTREoJOLuvMDww,25586
30
- weac-3.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
- weac-3.1.0.dist-info/top_level.txt,sha256=8tyXUHPFU4Ba_5kPtpwvXo5l6GjJmOnODVBJFygpdeE,5
32
- weac-3.1.0.dist-info/RECORD,,
28
+ weac-3.1.1.dist-info/licenses/LICENSE,sha256=ojZPWKFHbFGDrlNOvuAKGH9WcKhpLHWZPcQ4SzhK91M,1082
29
+ weac-3.1.1.dist-info/METADATA,sha256=0cdfjFenF40KllOBi5gLkyOSkdA3Ko_1LAdX43AlUK4,25593
30
+ weac-3.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
+ weac-3.1.1.dist-info/top_level.txt,sha256=8tyXUHPFU4Ba_5kPtpwvXo5l6GjJmOnODVBJFygpdeE,5
32
+ weac-3.1.1.dist-info/RECORD,,
File without changes