geolysis 0.9.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 +19 -8
  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 +65 -52
  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 +146 -136
  14. geolysis/soil_classifier.py +379 -283
  15. geolysis/spt.py +323 -257
  16. geolysis/{utils/__init__.py → utils.py} +44 -33
  17. geolysis-0.10.0.dist-info/METADATA +181 -0
  18. geolysis-0.10.0.dist-info/RECORD +22 -0
  19. {geolysis-0.9.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 -65
  28. geolysis/utils/validators.py +0 -119
  29. geolysis-0.9.0.dist-info/METADATA +0 -206
  30. geolysis-0.9.0.dist-info/RECORD +0 -24
  31. {geolysis-0.9.0.dist-info → geolysis-0.10.0.dist-info}/licenses/LICENSE.txt +0 -0
  32. {geolysis-0.9.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
- "Foundation",
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,45 +242,34 @@ 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
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
- load_angle: float = 0.0,
226
- ground_water_level: Optional[float] = None,
227
- foundation_type: FoundationType = FoundationType.PAD) -> None:
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:
228
262
  r"""
229
263
  :param depth: Depth of foundation (m).
230
- :type depth: float
231
-
232
264
  :param footing_size: Represents the size of the foundation footing.
233
- :type footing_size: FootingSize
234
-
235
- :param eccentricity: The deviation of the foundation load from the
236
- center of gravity of the foundation footing (m),
237
- defaults to 0.0. This means that the foundation
238
- load aligns with the center of gravity of the
239
- foundation footing.
240
- :type eccentricity: float, optional
241
-
242
- :param load_angle: Inclination of the applied load with the vertical
243
- (:math:`\alpha^{\circ}`), defaults to 0.0.
244
- :type load_angle: float, optional
245
-
246
- :param ground_water_level: Depth of the water below ground level (m),
247
- defaults to None.
248
- :type ground_water_level: float, optional
249
-
250
- :param foundation_type: Type of foundation, defaults to
251
- :py:enum:mem:`~FoundationType.PAD`
252
- :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.
253
273
  """
254
274
  self.depth = depth
255
275
  self.footing_size = footing_size
@@ -257,7 +277,7 @@ class Foundation:
257
277
  self.load_angle = load_angle
258
278
 
259
279
  self._ground_water_level = ground_water_level
260
- self._foundation_type = foundation_type
280
+ self.foundation_type = foundation_type
261
281
 
262
282
  @property
263
283
  def depth(self) -> float:
@@ -265,8 +285,8 @@ class Foundation:
265
285
  return self._depth
266
286
 
267
287
  @depth.setter
268
- @validators.gt(0.0)
269
- def depth(self, val: float) -> None:
288
+ @validate_func_args
289
+ def depth(self, val: Annotated[float, MustBePositive]) -> None:
270
290
  self._depth = val
271
291
 
272
292
  @property
@@ -275,7 +295,7 @@ class Foundation:
275
295
  return self.footing_size.width
276
296
 
277
297
  @width.setter
278
- def width(self, val: float):
298
+ def width(self, val: Annotated[float, MustBePositive]):
279
299
  self.footing_size.width = val
280
300
 
281
301
  @property
@@ -284,7 +304,7 @@ class Foundation:
284
304
  return self.footing_size.length
285
305
 
286
306
  @length.setter
287
- def length(self, val: float):
307
+ def length(self, val: Annotated[float, MustBePositive]):
288
308
  self.footing_size.length = val
289
309
 
290
310
  @property
@@ -294,14 +314,14 @@ class Foundation:
294
314
 
295
315
  @property
296
316
  def eccentricity(self) -> float:
297
- """The deviation of the foundation load from the center of gravity of
298
- the foundation footing (m).
317
+ """The deviation of the foundation load from the center of
318
+ gravity of the foundation footing (m).
299
319
  """
300
320
  return self._eccentricity
301
321
 
302
322
  @eccentricity.setter
303
- @validators.ge(0.0)
304
- def eccentricity(self, val: float) -> None:
323
+ @validate_func_args
324
+ def eccentricity(self, val: Annotated[float, MustBeNonNegative]) -> None:
305
325
  self._eccentricity = val
306
326
 
307
327
  @property
@@ -310,9 +330,11 @@ class Foundation:
310
330
  return self._load_angle
311
331
 
312
332
  @load_angle.setter
313
- @validators.le(90.0)
314
- @validators.ge(0.0)
315
- def load_angle(self, val: float):
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:
316
338
  self._load_angle = val
317
339
 
318
340
  @property
@@ -321,8 +343,8 @@ class Foundation:
321
343
  return self._ground_water_level
322
344
 
323
345
  @ground_water_level.setter
324
- @validators.ge(0.0)
325
- def ground_water_level(self, val: float) -> None:
346
+ @validate_func_args
347
+ def ground_water_level(self, val: Annotated[float, MustBePositive]):
326
348
  self._ground_water_level = val
327
349
 
328
350
  @property
@@ -330,18 +352,25 @@ class Foundation:
330
352
  """Type of foundation."""
331
353
  return self._foundation_type
332
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
+
333
363
  @property
334
364
  def effective_width(self) -> float:
335
365
  """Returns the effective width of the foundation footing (m)."""
336
366
  return self.width - 2.0 * self.eccentricity
337
367
 
338
368
  def footing_params(self) -> tuple[float, float, Shape]:
339
- """Returns the :attr:`effective_width`, :attr:`length`, and
340
- :attr:`footing_shape` of the foundation footing.
369
+ """Returns the `effective_width`, `length`, and `footing_shape`
370
+ of the foundation footing.
341
371
  """
342
- width, length, shape = (self.effective_width,
343
- self.length,
344
- self.footing_shape)
372
+ width, length, shape = (
373
+ self.effective_width, self.length, self.footing_shape)
345
374
 
346
375
  if not isclose(width, length) and shape != Shape.STRIP:
347
376
  shape = Shape.RECTANGLE
@@ -349,62 +378,43 @@ class Foundation:
349
378
  return width, length, shape
350
379
 
351
380
 
352
- def create_foundation(depth: float,
353
- width: float,
354
- length: Optional[float] = None,
355
- eccentricity: float = 0.0,
356
- load_angle: float = 0.0,
357
- ground_water_level: Optional[float] = None,
358
- foundation_type: FoundationType = FoundationType.PAD,
359
- shape: Shape | str = Shape.SQUARE) -> 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:
360
392
  r"""A factory function that encapsulate the creation of a foundation.
361
393
 
362
394
  :param depth: Depth of foundation (m).
363
- :type depth: float
364
-
365
395
  :param width: Width of foundation footing. In the case of a circular
366
396
  footing, it refers to the footing diameter (m).
367
- :type width: float
368
-
369
397
  :param length: Length of foundation footing (m), defaults to None.
370
- :type length: float, optional
371
-
372
398
  :param eccentricity: The deviation of the foundation load from the
373
399
  center of gravity of the foundation footing (m),
374
400
  defaults to 0.0. This means that the foundation
375
401
  load aligns with the center of gravity of the
376
402
  foundation footing .
377
- :type eccentricity: float, optional
378
-
379
403
  :param load_angle: Inclination of the applied load with the vertical
380
404
  (:math:`\alpha^{\circ}`), defaults to 0.0.
381
- :type load_angle: float, optional
382
-
383
405
  :param ground_water_level: Depth of the water below ground level (m),
384
406
  defaults to None.
385
- :type ground_water_level: float, optional
386
-
387
407
  :param foundation_type: Type of foundation footing, defaults to
388
408
  :py:enum:mem:`~FoundationType.PAD`.
389
- :type foundation_type: FoundationType, optional
390
-
391
- :param shape: Shape of foundation footing, defaults to
409
+ :param shape: Shape of foundation footing, defaults to
392
410
  :py:enum:mem:`~Shape.SQUARE`
393
- :type shape: Shape | str, optional
394
-
395
- :raises ValueError: Raised when length is not provided for a rectangular
396
- footing.
397
- :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.
398
415
  """
399
416
 
400
- try:
401
- shape = Shape(str(shape).casefold())
402
- except ValueError as e:
403
- msg = ErrorMsg(param_name="shape",
404
- param_value=shape,
405
- symbol="in",
406
- param_value_bound=list(Shape))
407
- raise ValidationError(msg) from e
417
+ shape = Shape(str(shape).casefold())
408
418
 
409
419
  if shape is Shape.STRIP:
410
420
  footing_size = StripFooting(width=width)
@@ -414,15 +424,15 @@ def create_foundation(depth: float,
414
424
  footing_size = CircularFooting(diameter=width)
415
425
  else: # RECTANGLE
416
426
  if not length:
417
- msg = ErrorMsg(param_name="length",
418
- param_value=length,
419
- msg="Length of footing must be provided.")
420
- raise ValidationError(msg)
427
+ msg = "Length of rectangular footing must be provided."
428
+ raise ValueError(msg)
421
429
  footing_size = RectangularFooting(width=width, length=length)
422
430
 
423
- return Foundation(depth=depth,
424
- eccentricity=eccentricity,
425
- load_angle=load_angle,
426
- ground_water_level=ground_water_level,
427
- foundation_type=foundation_type,
428
- 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
+ )