geolysis 0.8.0__py3-none-any.whl → 0.10.0__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.
Files changed (32) hide show
  1. geolysis/__init__.py +3 -3
  2. geolysis/bearing_capacity/abc/__init__.py +21 -0
  3. geolysis/bearing_capacity/abc/_cohl/__init__.py +109 -0
  4. geolysis/bearing_capacity/abc/{cohl → _cohl}/_core.py +20 -10
  5. geolysis/bearing_capacity/abc/_cohl/bowles_abc.py +103 -0
  6. geolysis/bearing_capacity/abc/_cohl/meyerhof_abc.py +100 -0
  7. geolysis/bearing_capacity/abc/_cohl/terzaghi_abc.py +143 -0
  8. geolysis/bearing_capacity/ubc/__init__.py +107 -128
  9. geolysis/bearing_capacity/ubc/_core.py +68 -66
  10. geolysis/bearing_capacity/ubc/_hansen_ubc.py +271 -0
  11. geolysis/bearing_capacity/ubc/_terzaghi_ubc.py +178 -0
  12. geolysis/bearing_capacity/ubc/_vesic_ubc.py +253 -0
  13. geolysis/foundation.py +160 -127
  14. geolysis/soil_classifier.py +386 -285
  15. geolysis/spt.py +323 -257
  16. geolysis/{utils/__init__.py → utils.py} +48 -36
  17. geolysis-0.10.0.dist-info/METADATA +181 -0
  18. geolysis-0.10.0.dist-info/RECORD +22 -0
  19. {geolysis-0.8.0.dist-info → geolysis-0.10.0.dist-info}/WHEEL +1 -1
  20. geolysis/bearing_capacity/abc/cohl/__init__.py +0 -137
  21. geolysis/bearing_capacity/abc/cohl/bowles_abc.py +0 -96
  22. geolysis/bearing_capacity/abc/cohl/meyerhof_abc.py +0 -96
  23. geolysis/bearing_capacity/abc/cohl/terzaghi_abc.py +0 -131
  24. geolysis/bearing_capacity/ubc/hansen_ubc.py +0 -287
  25. geolysis/bearing_capacity/ubc/terzaghi_ubc.py +0 -246
  26. geolysis/bearing_capacity/ubc/vesic_ubc.py +0 -293
  27. geolysis/utils/exceptions.py +0 -52
  28. geolysis/utils/validators.py +0 -129
  29. geolysis-0.8.0.dist-info/METADATA +0 -206
  30. geolysis-0.8.0.dist-info/RECORD +0 -24
  31. {geolysis-0.8.0.dist-info → geolysis-0.10.0.dist-info}/licenses/LICENSE.txt +0 -0
  32. {geolysis-0.8.0.dist-info → geolysis-0.10.0.dist-info}/top_level.txt +0 -0
geolysis/foundation.py CHANGED
@@ -1,40 +1,74 @@
1
- """This module provides classes and utilities for modeling various foundation
2
- footing types, their dimensions, and properties."""
3
1
  import enum
4
2
  from abc import ABC, abstractmethod
5
- from typing import Optional, TypeVar
3
+ from typing import Optional, TypeVar, Annotated
4
+
5
+ from func_validator import (
6
+ validate_func_args,
7
+ MustBePositive,
8
+ MustBeNonNegative,
9
+ MustBeBetween,
10
+ MustBeMemberOf,
11
+ )
12
+
13
+ from .utils import AbstractStrEnum, inf, isclose
14
+
15
+ __all__ = [
16
+ "create_foundation",
17
+ "Foundation",
18
+ "FoundationType",
19
+ "Shape",
20
+ "StripFooting",
21
+ "CircularFooting",
22
+ "SquareFooting",
23
+ "RectangularFooting",
24
+ ]
6
25
 
7
- from .utils import enum_repr, inf, isclose, validators
8
- from .utils.exceptions import ErrorMsg, ValidationError
26
+ T = TypeVar("T")
9
27
 
10
- __all__ = ["create_foundation",
11
- "FoundationSize",
12
- "FoundationType",
13
- "Shape",
14
- "StripFooting",
15
- "CircularFooting",
16
- "SquareFooting",
17
- "RectangularFooting"]
18
28
 
19
- T = TypeVar("T")
29
+ class Shape(AbstractStrEnum):
30
+ """Enumeration of foundation shapes.
20
31
 
32
+ Each member represents a standard geometric shape commonly used
33
+ in foundation design, which can affect bearing capacity and
34
+ settlement calculations.
35
+ """
21
36
 
22
- @enum_repr
23
- class Shape(enum.StrEnum):
24
- """Enumeration of foundation shapes."""
25
37
  STRIP = enum.auto()
38
+ """Strip (or continuous) foundation, typically long and narrow."""
39
+
26
40
  CIRCLE = enum.auto()
41
+ """Circular foundation, often used for columns or piers."""
42
+
27
43
  SQUARE = enum.auto()
44
+ """Square foundation, commonly used for isolated footings."""
45
+
28
46
  RECTANGLE = enum.auto()
47
+ """Rectangular foundation, used when length and width differ significantly."""
29
48
 
30
49
 
31
- @enum_repr
32
- class FoundationType(enum.StrEnum):
33
- """Enumeration of foundation types."""
50
+ class FoundationType(AbstractStrEnum):
51
+ """
52
+ Enumeration of foundation types.
53
+
54
+ Each member represents a common type of foundation used in
55
+ geotechnical engineering. Some members have aliases for
56
+ alternative naming conventions.
57
+ """
58
+
34
59
  PAD = enum.auto()
60
+ """Pad foundation, a small, isolated footing supporting a single column."""
61
+
35
62
  ISOLATED = PAD
63
+ """Alias for PAD foundation (isolated footing)."""
64
+
36
65
  MAT = enum.auto()
66
+ """Mat foundation, a large, continuous slab supporting multiple columns or
67
+ walls.
68
+ """
69
+
37
70
  RAFT = MAT
71
+ """Alias for MAT foundation (raft foundation)."""
38
72
 
39
73
 
40
74
  class FootingSize(ABC):
@@ -69,13 +103,10 @@ class StripFooting(FootingSize):
69
103
 
70
104
  _SHAPE = Shape.STRIP
71
105
 
72
- def __init__(self, width: float, length: float = inf) -> None:
106
+ def __init__(self, width: float, length: float = inf):
73
107
  """
74
108
  :param width: Width of foundation footing (m).
75
- :type width: float
76
-
77
- :param float length: Length of foundation footing, defaults to inf (m).
78
- :type length: float
109
+ :param length: Length of foundation footing (m).
79
110
  """
80
111
  self.width = width
81
112
  self.length = length
@@ -86,8 +117,8 @@ class StripFooting(FootingSize):
86
117
  return self._width
87
118
 
88
119
  @width.setter
89
- @validators.gt(0.0)
90
- def width(self, val: float):
120
+ @validate_func_args
121
+ def width(self, val: Annotated[float, MustBePositive]) -> None:
91
122
  self._width = val
92
123
 
93
124
  @property
@@ -96,17 +127,17 @@ class StripFooting(FootingSize):
96
127
  return self._length
97
128
 
98
129
  @length.setter
99
- @validators.ge(0.0)
100
- def length(self, val: float):
130
+ @validate_func_args
131
+ def length(self, val: Annotated[float, MustBePositive]) -> None:
101
132
  self._length = val
102
133
 
103
134
 
104
135
  class CircularFooting(FootingSize):
105
136
  """A class representation of circular footing.
106
137
 
107
- .. note::
138
+ !!! note
108
139
 
109
- The ``width`` and ``length`` properties refer to the diameter of the
140
+ The `width` and `length` properties refer to the diameter of the
110
141
  circular footing. This is to make it compatible with the protocol
111
142
  square and rectangular footing follow.
112
143
  """
@@ -115,7 +146,7 @@ class CircularFooting(FootingSize):
115
146
 
116
147
  def __init__(self, diameter: float):
117
148
  """
118
- :param float diameter: Diameter of foundation footing (m).
149
+ :param diameter: Diameter of foundation footing (m).
119
150
  """
120
151
  self.diameter = diameter
121
152
 
@@ -125,8 +156,8 @@ class CircularFooting(FootingSize):
125
156
  return self._diameter
126
157
 
127
158
  @diameter.setter
128
- @validators.gt(0.0)
129
- def diameter(self, val: float):
159
+ @validate_func_args
160
+ def diameter(self, val: Annotated[float, MustBePositive]) -> None:
130
161
  self._diameter = val
131
162
 
132
163
  @property
@@ -134,10 +165,12 @@ class CircularFooting(FootingSize):
134
165
  """Diameter of foundation footing (m)."""
135
166
  return self.diameter
136
167
 
168
+ # Not checking for positive as diameter setter already does that
137
169
  @width.setter
138
170
  def width(self, val: float):
139
171
  self.diameter = val
140
172
 
173
+ # Not checking for positive as diameter setter already does that
141
174
  @property
142
175
  def length(self):
143
176
  """Diameter of foundation footing (m)."""
@@ -165,8 +198,8 @@ class SquareFooting(FootingSize):
165
198
  return self._width
166
199
 
167
200
  @width.setter
168
- @validators.gt(0)
169
- def width(self, val):
201
+ @validate_func_args
202
+ def width(self, val: Annotated[float, MustBePositive]) -> None:
170
203
  self._width = val
171
204
 
172
205
  @property
@@ -174,6 +207,7 @@ class SquareFooting(FootingSize):
174
207
  """Width of foundation footing (m)."""
175
208
  return self.width
176
209
 
210
+ # Not checking for positive as width setter already does that
177
211
  @length.setter
178
212
  def length(self, val):
179
213
  self.width = val
@@ -187,10 +221,7 @@ class RectangularFooting(FootingSize):
187
221
  def __init__(self, width: float, length: float):
188
222
  """
189
223
  :param width: Width of foundation footing (m).
190
- :type width: float
191
-
192
224
  :param length: Length of foundation footing (m).
193
- :type length: float
194
225
  """
195
226
  self.width = width
196
227
  self.length = length
@@ -201,8 +232,8 @@ class RectangularFooting(FootingSize):
201
232
  return self._width
202
233
 
203
234
  @width.setter
204
- @validators.gt(0.0)
205
- def width(self, val):
235
+ @validate_func_args
236
+ def width(self, val: Annotated[float, MustBePositive]) -> None:
206
237
  self._width = val
207
238
 
208
239
  @property
@@ -211,47 +242,42 @@ class RectangularFooting(FootingSize):
211
242
  return self._length
212
243
 
213
244
  @length.setter
214
- @validators.gt(0.0)
215
- def length(self, val):
245
+ @validate_func_args
246
+ def length(self, val: Annotated[float, MustBePositive]) -> None:
216
247
  self._length = val
217
248
 
218
249
 
219
- class FoundationSize:
250
+ class Foundation:
220
251
  """A simple class representing a foundation structure."""
221
252
 
222
- def __init__(self, depth: float,
223
- footing_size: FootingSize,
224
- eccentricity: float = 0.0,
225
- ground_water_level: Optional[float] = None,
226
- foundation_type: FoundationType = FoundationType.PAD) -> None:
227
- """
253
+ def __init__(
254
+ self,
255
+ depth: float,
256
+ footing_size: FootingSize,
257
+ eccentricity: float = 0.0,
258
+ load_angle: float = 0.0,
259
+ ground_water_level: Optional[float] = None,
260
+ foundation_type: FoundationType = FoundationType.PAD,
261
+ ) -> None:
262
+ r"""
228
263
  :param depth: Depth of foundation (m).
229
- :type depth: float
230
-
231
264
  :param footing_size: Represents the size of the foundation footing.
232
- :type footing_size: FootingSize
233
-
234
- :param eccentricity: The deviation of the foundation load from the
235
- center of gravity of the foundation footing (m),
236
- defaults to 0.0. This means that the foundation
237
- load aligns with the center of gravity of the
238
- foundation footing.
239
- :type eccentricity: float, optional
240
-
241
- :param ground_water_level: Depth of the water below ground level (m),
242
- defaults to None.
243
- :type ground_water_level: float, optional
244
-
245
- :param foundation_type: Type of foundation, defaults to
246
- :py:enum:mem:`~FoundationType.PAD`
247
- :type foundation_type: FoundationType, optional
265
+ :param eccentricity: The deviation of the foundation load from
266
+ the center of gravity of the foundation
267
+ footing (m).
268
+ :param load_angle: Inclination of the applied load with the
269
+ vertical ($\alpha^{\circ}$)
270
+ :param ground_water_level: Depth of the water below ground level
271
+ (m).
272
+ :param foundation_type: Type of foundation.
248
273
  """
249
274
  self.depth = depth
250
275
  self.footing_size = footing_size
251
276
  self.eccentricity = eccentricity
277
+ self.load_angle = load_angle
252
278
 
253
279
  self._ground_water_level = ground_water_level
254
- self._foundation_type = foundation_type
280
+ self.foundation_type = foundation_type
255
281
 
256
282
  @property
257
283
  def depth(self) -> float:
@@ -259,8 +285,8 @@ class FoundationSize:
259
285
  return self._depth
260
286
 
261
287
  @depth.setter
262
- @validators.gt(0.0)
263
- def depth(self, val: float) -> None:
288
+ @validate_func_args
289
+ def depth(self, val: Annotated[float, MustBePositive]) -> None:
264
290
  self._depth = val
265
291
 
266
292
  @property
@@ -269,7 +295,7 @@ class FoundationSize:
269
295
  return self.footing_size.width
270
296
 
271
297
  @width.setter
272
- def width(self, val: float):
298
+ def width(self, val: Annotated[float, MustBePositive]):
273
299
  self.footing_size.width = val
274
300
 
275
301
  @property
@@ -278,7 +304,7 @@ class FoundationSize:
278
304
  return self.footing_size.length
279
305
 
280
306
  @length.setter
281
- def length(self, val: float):
307
+ def length(self, val: Annotated[float, MustBePositive]):
282
308
  self.footing_size.length = val
283
309
 
284
310
  @property
@@ -288,24 +314,37 @@ class FoundationSize:
288
314
 
289
315
  @property
290
316
  def eccentricity(self) -> float:
291
- """The deviation of the foundation load from the center of gravity of
292
- the foundation footing (m).
317
+ """The deviation of the foundation load from the center of
318
+ gravity of the foundation footing (m).
293
319
  """
294
320
  return self._eccentricity
295
321
 
296
322
  @eccentricity.setter
297
- @validators.ge(0.0)
298
- def eccentricity(self, val: float) -> None:
323
+ @validate_func_args
324
+ def eccentricity(self, val: Annotated[float, MustBeNonNegative]) -> None:
299
325
  self._eccentricity = val
300
326
 
327
+ @property
328
+ def load_angle(self) -> float:
329
+ """Inclination of the applied load with the vertical."""
330
+ return self._load_angle
331
+
332
+ @load_angle.setter
333
+ @validate_func_args
334
+ def load_angle(
335
+ self,
336
+ val: Annotated[float, MustBeBetween(min_value=0.0, max_value=90.0)]
337
+ ) -> None:
338
+ self._load_angle = val
339
+
301
340
  @property
302
341
  def ground_water_level(self) -> Optional[float]:
303
342
  """Depth of the water below ground level (m)."""
304
343
  return self._ground_water_level
305
344
 
306
345
  @ground_water_level.setter
307
- @validators.ge(0.0)
308
- def ground_water_level(self, val: float) -> None:
346
+ @validate_func_args
347
+ def ground_water_level(self, val: Annotated[float, MustBePositive]):
309
348
  self._ground_water_level = val
310
349
 
311
350
  @property
@@ -313,18 +352,25 @@ class FoundationSize:
313
352
  """Type of foundation."""
314
353
  return self._foundation_type
315
354
 
355
+ @foundation_type.setter
356
+ @validate_func_args
357
+ def foundation_type(
358
+ self,
359
+ val: Annotated[FoundationType, MustBeMemberOf(FoundationType)]
360
+ ):
361
+ self._foundation_type = val
362
+
316
363
  @property
317
364
  def effective_width(self) -> float:
318
365
  """Returns the effective width of the foundation footing (m)."""
319
366
  return self.width - 2.0 * self.eccentricity
320
367
 
321
368
  def footing_params(self) -> tuple[float, float, Shape]:
322
- """Returns the :attr:`effective_width`, :attr:`length`, and
323
- :attr:`footing_shape` of the foundation footing.
369
+ """Returns the `effective_width`, `length`, and `footing_shape`
370
+ of the foundation footing.
324
371
  """
325
- width, length, shape = (self.effective_width,
326
- self.length,
327
- self.footing_shape)
372
+ width, length, shape = (
373
+ self.effective_width, self.length, self.footing_shape)
328
374
 
329
375
  if not isclose(width, length) and shape != Shape.STRIP:
330
376
  shape = Shape.RECTANGLE
@@ -332,57 +378,43 @@ class FoundationSize:
332
378
  return width, length, shape
333
379
 
334
380
 
335
- def create_foundation(depth: float,
336
- width: float,
337
- length: Optional[float] = None,
338
- eccentricity: float = 0.0,
339
- ground_water_level: Optional[float] = None,
340
- foundation_type: FoundationType = FoundationType.PAD,
341
- shape: Shape | str = Shape.SQUARE) -> FoundationSize:
342
- """A factory function that encapsulate the creation of a foundation.
381
+ @validate_func_args
382
+ def create_foundation(
383
+ depth: float,
384
+ width: float,
385
+ length: Optional[float] = None,
386
+ eccentricity: float = 0.0,
387
+ load_angle: float = 0.0,
388
+ ground_water_level: Optional[float] = None,
389
+ foundation_type: FoundationType = "pad",
390
+ shape: Annotated[Shape | str, MustBeMemberOf(Shape)] = "square",
391
+ ) -> Foundation:
392
+ r"""A factory function that encapsulate the creation of a foundation.
343
393
 
344
394
  :param depth: Depth of foundation (m).
345
- :type depth: float
346
-
347
395
  :param width: Width of foundation footing. In the case of a circular
348
396
  footing, it refers to the footing diameter (m).
349
- :type width: float
350
-
351
397
  :param length: Length of foundation footing (m), defaults to None.
352
- :type length: float, optional
353
-
354
398
  :param eccentricity: The deviation of the foundation load from the
355
399
  center of gravity of the foundation footing (m),
356
400
  defaults to 0.0. This means that the foundation
357
401
  load aligns with the center of gravity of the
358
402
  foundation footing .
359
- :type eccentricity: float, optional
360
-
403
+ :param load_angle: Inclination of the applied load with the vertical
404
+ (:math:`\alpha^{\circ}`), defaults to 0.0.
361
405
  :param ground_water_level: Depth of the water below ground level (m),
362
406
  defaults to None.
363
- :type ground_water_level: float, optional
364
-
365
407
  :param foundation_type: Type of foundation footing, defaults to
366
408
  :py:enum:mem:`~FoundationType.PAD`.
367
- :type foundation_type: FoundationType, optional
368
-
369
- :param shape: Shape of foundation footing, defaults to
409
+ :param shape: Shape of foundation footing, defaults to
370
410
  :py:enum:mem:`~Shape.SQUARE`
371
- :type shape: Shape | str, optional
372
-
373
- :raises ValueError: Raised when length is not provided for a rectangular
374
- footing.
375
- :raises ValueError: Raised if an invalid footing shape is provided.
411
+ :raises ValueError: Raised when length is not provided for a
412
+ rectangular footing.
413
+ :raises ValidationError: Raised if an invalid footing shape is
414
+ provided.
376
415
  """
377
416
 
378
- try:
379
- shape = Shape(str(shape).casefold())
380
- except ValueError as e:
381
- msg = ErrorMsg(param_name="shape",
382
- param_value=shape,
383
- symbol="in",
384
- param_value_bound=list(Shape))
385
- raise ValidationError(msg) from e
417
+ shape = Shape(str(shape).casefold())
386
418
 
387
419
  if shape is Shape.STRIP:
388
420
  footing_size = StripFooting(width=width)
@@ -392,14 +424,15 @@ def create_foundation(depth: float,
392
424
  footing_size = CircularFooting(diameter=width)
393
425
  else: # RECTANGLE
394
426
  if not length:
395
- msg = ErrorMsg(param_name="length",
396
- param_value=length,
397
- msg="Length of footing must be provided.")
398
- raise ValidationError(msg)
427
+ msg = "Length of rectangular footing must be provided."
428
+ raise ValueError(msg)
399
429
  footing_size = RectangularFooting(width=width, length=length)
400
430
 
401
- return FoundationSize(depth=depth,
402
- eccentricity=eccentricity,
403
- ground_water_level=ground_water_level,
404
- foundation_type=foundation_type,
405
- footing_size=footing_size)
431
+ return Foundation(
432
+ depth=depth,
433
+ eccentricity=eccentricity,
434
+ load_angle=load_angle,
435
+ ground_water_level=ground_water_level,
436
+ foundation_type=foundation_type,
437
+ footing_size=footing_size,
438
+ )