geolysis 0.11.0__py3-none-any.whl → 0.12.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.
@@ -1,6 +1,14 @@
1
- from abc import ABC
2
-
3
- from geolysis.utils import cos, cot, deg2rad, exp, isclose, pi, round_, tan
1
+ from geolysis.utils import (
2
+ cosdeg,
3
+ cotdeg,
4
+ deg2rad,
5
+ exp,
6
+ isclose,
7
+ pi,
8
+ round_,
9
+ tandeg,
10
+ add_repr,
11
+ )
4
12
  from ._core import UltimateBearingCapacity
5
13
 
6
14
  __all__ = [
@@ -10,8 +18,6 @@ __all__ = [
10
18
  "TerzaghiUBC4RectangularFooting",
11
19
  ]
12
20
 
13
- from geolysis.foundation import Foundation
14
-
15
21
 
16
22
  class TerzaghiBearingCapacityFactors:
17
23
 
@@ -20,54 +26,27 @@ class TerzaghiBearingCapacityFactors:
20
26
  def n_c(friction_angle: float) -> float:
21
27
  if isclose(friction_angle, 0.0):
22
28
  return 5.7
23
- return cot(friction_angle) * (
24
- TerzaghiBearingCapacityFactors.n_q(friction_angle) - 1.0
29
+ return cotdeg(friction_angle) * (
30
+ TerzaghiBearingCapacityFactors.n_q(friction_angle) - 1.0
25
31
  )
26
32
 
27
33
  @staticmethod
28
34
  @round_(ndigits=2)
29
35
  def n_q(friction_angle: float) -> float:
30
- return exp((3.0 * pi / 2.0 - deg2rad(friction_angle)) * tan(
31
- friction_angle)) / (
32
- 2.0 * (cos(45.0 + friction_angle / 2.0)) ** 2.0
33
- )
36
+ return exp(
37
+ (3.0 * pi / 2.0 - deg2rad(friction_angle)) * tandeg(friction_angle)
38
+ ) / (2.0 * (cosdeg(45.0 + friction_angle / 2.0)) ** 2.0)
34
39
 
35
40
  @staticmethod
36
41
  @round_(ndigits=2)
37
42
  def n_gamma(friction_angle: float) -> float:
38
- return (TerzaghiBearingCapacityFactors.n_q(
39
- friction_angle) - 1.0) * tan(
43
+ return (TerzaghiBearingCapacityFactors.n_q(friction_angle) - 1.0) * tandeg(
40
44
  1.4 * friction_angle
41
45
  )
42
46
 
43
47
 
44
- class TerzaghiUltimateBearingCapacity(UltimateBearingCapacity, ABC):
45
-
46
- def __init__(
47
- self,
48
- friction_angle: float,
49
- cohesion: float,
50
- moist_unit_wgt: float,
51
- foundation_size: Foundation,
52
- apply_local_shear: bool = False,
53
- ) -> None:
54
- r"""
55
- :param friction_angle: Internal angle of friction for general
56
- shear failure (degrees).
57
- :param cohesion: Cohesion of soil ($kPa$).
58
- :param moist_unit_wgt: Moist unit weight of soil ($kN/m^3$).
59
- :param foundation_size: Size of the foundation.
60
- :param apply_local_shear: Indicate whether bearing capacity
61
- failure is general shear or local
62
- shear failure.
63
- """
64
- super().__init__(
65
- friction_angle=friction_angle,
66
- cohesion=cohesion,
67
- moist_unit_wgt=moist_unit_wgt,
68
- foundation_size=foundation_size,
69
- apply_local_shear=apply_local_shear,
70
- )
48
+ @add_repr
49
+ class TerzaghiUltimateBearingCapacity(UltimateBearingCapacity):
71
50
 
72
51
  @property
73
52
  def n_c(self) -> float:
@@ -94,12 +73,12 @@ class TerzaghiUBC4StripFooting(TerzaghiUltimateBearingCapacity):
94
73
  """
95
74
 
96
75
  @round_(ndigits=2)
97
- def bearing_capacity(self) -> float:
76
+ def _bearing_capacity(self) -> float:
98
77
  """Calculates ultimate bearing capacity for strip footing."""
99
78
  return (
100
- self._cohesion_term(1.0)
101
- + self._surcharge_term()
102
- + self._embedment_term(0.5)
79
+ self._cohesion_term(1.0)
80
+ + self._surcharge_term()
81
+ + self._embedment_term(0.5)
103
82
  )
104
83
 
105
84
 
@@ -112,12 +91,12 @@ class TerzaghiUBC4CircularFooting(TerzaghiUltimateBearingCapacity):
112
91
  """
113
92
 
114
93
  @round_(ndigits=2)
115
- def bearing_capacity(self) -> float:
94
+ def _bearing_capacity(self) -> float:
116
95
  """Calculates ultimate bearing capacity for circular footing."""
117
96
  return (
118
- self._cohesion_term(1.3)
119
- + self._surcharge_term()
120
- + self._embedment_term(0.3)
97
+ self._cohesion_term(1.3)
98
+ + self._surcharge_term()
99
+ + self._embedment_term(0.3)
121
100
  )
122
101
 
123
102
 
@@ -130,7 +109,7 @@ class TerzaghiUBC4RectangularFooting(TerzaghiUltimateBearingCapacity):
130
109
  """
131
110
 
132
111
  @round_(ndigits=2)
133
- def bearing_capacity(self) -> float:
112
+ def _bearing_capacity(self) -> float:
134
113
  """Calculates ultimate bearing capacity for rectangular footing."""
135
114
  width = self.foundation_size.width
136
115
  length = self.foundation_size.length
@@ -138,9 +117,9 @@ class TerzaghiUBC4RectangularFooting(TerzaghiUltimateBearingCapacity):
138
117
  emb_coef = (1.0 - 0.2 * (width / length)) / 2.0
139
118
 
140
119
  return (
141
- self._cohesion_term(coh_coef)
142
- + self._surcharge_term()
143
- + self._embedment_term(emb_coef)
120
+ self._cohesion_term(coh_coef)
121
+ + self._surcharge_term()
122
+ + self._embedment_term(emb_coef)
144
123
  )
145
124
 
146
125
 
@@ -152,6 +131,6 @@ class TerzaghiUBC4SquareFooting(TerzaghiUBC4RectangularFooting):
152
131
  for more details on bearing capacity equation used.
153
132
  """
154
133
 
155
- def bearing_capacity(self):
134
+ def _bearing_capacity(self):
156
135
  """Calcalates ultimate bearing capacity for square footing."""
157
- return super().bearing_capacity()
136
+ return super()._bearing_capacity()
@@ -1,5 +1,5 @@
1
1
  from geolysis.foundation import Shape
2
- from geolysis.utils import isclose, round_, sin, tan
2
+ from geolysis.utils import isclose, round_, sindeg, tandeg, atan, add_repr
3
3
  from ._core import UltimateBearingCapacity
4
4
  from ._hansen_ubc import HansenBearingCapacityFactors
5
5
 
@@ -22,74 +22,103 @@ class VesicBearingCapacityFactors:
22
22
  @round_(ndigits=2)
23
23
  def n_gamma(friction_angle: float) -> float:
24
24
  return (
25
- 2.0
26
- * (VesicBearingCapacityFactors.n_q(friction_angle) + 1.0)
27
- * tan(friction_angle)
25
+ 2.0
26
+ * (VesicBearingCapacityFactors.n_q(friction_angle) + 1.0)
27
+ * tandeg(friction_angle)
28
28
  )
29
29
 
30
30
 
31
31
  class VesicShapeFactors:
32
32
  @staticmethod
33
- @round_(ndigits=2)
33
+ @round_(ndigits=3)
34
34
  def s_c(
35
- friction_angle: float,
36
- f_width: float,
37
- f_length: float,
38
- f_shape: Shape,
35
+ friction_angle: float,
36
+ f_width: float,
37
+ f_length: float,
38
+ f_shape: Shape,
39
39
  ) -> float:
40
- _n_q = VesicBearingCapacityFactors.n_q(friction_angle)
41
- _n_c = VesicBearingCapacityFactors.n_c(friction_angle)
40
+ n_q = VesicBearingCapacityFactors.n_q(friction_angle)
41
+ n_c = VesicBearingCapacityFactors.n_c(friction_angle)
42
42
 
43
43
  if f_shape == Shape.STRIP:
44
44
  return 1.0
45
- elif f_shape == Shape.RECTANGLE:
46
- return 1.0 + (f_width / f_length) * (_n_q / _n_c)
47
- else: # SQUARE, CIRCLE
48
- return 1.0 + (_n_q / _n_c)
45
+ else:
46
+ return 1.0 + (f_width / f_length) * (n_q / n_c)
49
47
 
50
48
  @staticmethod
51
- @round_(ndigits=2)
49
+ @round_(ndigits=3)
52
50
  def s_q(
53
- friction_angle: float,
54
- f_width: float,
55
- f_length: float,
56
- f_shape: Shape,
51
+ friction_angle: float,
52
+ f_width: float,
53
+ f_length: float,
54
+ f_shape: Shape,
57
55
  ) -> float:
58
56
  if f_shape == Shape.STRIP:
59
57
  return 1.0
60
- elif f_shape == Shape.RECTANGLE:
61
- return 1.0 + (f_width / f_length) * tan(friction_angle)
62
- else: # SQUARE, CIRCLE
63
- return 1.0 + tan(friction_angle)
58
+ else:
59
+ return 1.0 + (f_width / f_length) * tandeg(friction_angle)
64
60
 
65
61
  @staticmethod
66
- @round_(ndigits=2)
62
+ @round_(ndigits=3)
67
63
  def s_gamma(f_width: float, f_length: float, f_shape: Shape) -> float:
68
64
  if f_shape == Shape.STRIP:
69
65
  return 1.0
70
- elif f_shape == Shape.RECTANGLE:
66
+ else:
71
67
  return 1.0 - 0.4 * (f_width / f_length)
72
- else: # SQUARE, CIRCLE
73
- return 0.6
74
68
 
75
69
 
76
70
  class VesicDepthFactors:
77
71
 
78
72
  @staticmethod
79
- @round_(ndigits=2)
80
- def d_c(f_depth: float, f_width: float) -> float:
81
- return 1.0 + 0.4 * f_depth / f_width
73
+ def _d_c(friction_angle: float, f_depth: float, f_width: float) -> float:
74
+ d_q = VesicDepthFactors.d_q(friction_angle, f_depth, f_width)
75
+ n_c = VesicBearingCapacityFactors.n_c(friction_angle)
76
+ return d_q - ((1.0 - d_q) / (n_c * tandeg(friction_angle)))
82
77
 
83
78
  @staticmethod
84
- @round_(ndigits=2)
79
+ @round_(ndigits=3)
80
+ def d_c(friction_angle: float, f_depth: float, f_width: float) -> float:
81
+ d2w = round(f_depth / f_width, 1)
82
+
83
+ if d2w <= 1.0:
84
+ if isclose(friction_angle, 0.0):
85
+ _d_c = 1.0 + 0.4 * d2w
86
+ else:
87
+ _d_c = VesicDepthFactors._d_c(friction_angle, f_depth, f_width)
88
+ else:
89
+ if isclose(friction_angle, 0.0):
90
+ _d_c = 1.0 + 0.4 * atan(d2w)
91
+ else:
92
+ _d_c = VesicDepthFactors._d_c(friction_angle, f_depth, f_width)
93
+
94
+ return _d_c
95
+
96
+ @staticmethod
97
+ @round_(ndigits=3)
85
98
  def d_q(friction_angle: float, f_depth: float, f_width: float) -> float:
86
- return 1.0 + 2.0 * tan(friction_angle) * (
87
- 1.0 - sin(friction_angle)) ** 2.0 * (
88
- f_depth / f_width
89
- )
99
+ d2w = f_depth / f_width
100
+
101
+ if d2w <= 1.0:
102
+ if isclose(friction_angle, 0.0):
103
+ _d_q = 1.0
104
+ else:
105
+ _d_q = (
106
+ 1.0
107
+ + 2
108
+ * tandeg(friction_angle)
109
+ * (1 - sindeg(friction_angle)) ** 2
110
+ * d2w
111
+ )
112
+ else:
113
+ if isclose(friction_angle, 0.0):
114
+ _d_q = 1.0
115
+ else:
116
+ _d_q = 1.0 + (
117
+ 2.0 * tandeg(friction_angle) * (1 - sindeg(friction_angle)) ** 2
118
+ ) * atan(d2w)
119
+ return _d_q
90
120
 
91
121
  @staticmethod
92
- @round_(ndigits=2)
93
122
  def d_gamma() -> float:
94
123
  return 1.0
95
124
 
@@ -97,23 +126,24 @@ class VesicDepthFactors:
97
126
  class VesicInclinationFactors:
98
127
 
99
128
  @staticmethod
100
- @round_(ndigits=2)
129
+ @round_(ndigits=3)
101
130
  def i_c(load_angle: float) -> float:
102
131
  return (1.0 - load_angle / 90.0) ** 2.0
103
132
 
104
133
  @staticmethod
105
- @round_(ndigits=2)
134
+ @round_(ndigits=3)
106
135
  def i_q(load_angle: float) -> float:
107
136
  return VesicInclinationFactors.i_c(load_angle)
108
137
 
109
138
  @staticmethod
110
- @round_(ndigits=2)
139
+ @round_(ndigits=3)
111
140
  def i_gamma(friction_angle: float, load_angle: float) -> float:
112
141
  if isclose(friction_angle, 0.0):
113
142
  return 1.0
114
143
  return (1.0 - load_angle / friction_angle) ** 2.0
115
144
 
116
145
 
146
+ @add_repr
117
147
  class VesicUltimateBearingCapacity(UltimateBearingCapacity):
118
148
  """Ultimate bearing capacity for soils according to `Vesic (1973)`.
119
149
 
@@ -158,7 +188,7 @@ class VesicUltimateBearingCapacity(UltimateBearingCapacity):
158
188
  def d_c(self) -> float:
159
189
  r"""Depth factor $D_c$."""
160
190
  depth, width = self.foundation_size.depth, self.foundation_size.width
161
- return VesicDepthFactors.d_c(depth, width)
191
+ return VesicDepthFactors.d_c(self.friction_angle, depth, width)
162
192
 
163
193
  @property
164
194
  def d_q(self) -> float:
@@ -184,5 +214,4 @@ class VesicUltimateBearingCapacity(UltimateBearingCapacity):
184
214
  @property
185
215
  def i_gamma(self) -> float:
186
216
  r"""Inclination factor $I_{\gamma}$."""
187
- return VesicInclinationFactors.i_gamma(self.friction_angle,
188
- self.load_angle)
217
+ return VesicInclinationFactors.i_gamma(self.friction_angle, self.load_angle)
geolysis/foundation.py CHANGED
@@ -1,5 +1,7 @@
1
1
  import enum
2
+ import math
2
3
  from abc import ABC, abstractmethod
4
+ from math import isinf
3
5
  from typing import Optional, TypeVar, Annotated
4
6
 
5
7
  from func_validator import (
@@ -10,7 +12,7 @@ from func_validator import (
10
12
  MustBeMemberOf,
11
13
  )
12
14
 
13
- from .utils import AbstractStrEnum, inf, isclose
15
+ from .utils import AbstractStrEnum, inf, isclose, pi, round_, add_repr
14
16
 
15
17
  __all__ = [
16
18
  "create_foundation",
@@ -29,10 +31,10 @@ T = TypeVar("T")
29
31
  class Shape(AbstractStrEnum):
30
32
  """Enumeration of foundation shapes.
31
33
 
32
- Each member represents a standard geometric shape commonly used
33
- in foundation design, which can affect bearing capacity and
34
- settlement calculations.
35
- """
34
+ Each member represents a standard geometric shape commonly used
35
+ in foundation design, which can affect bearing capacity and
36
+ settlement calculations.
37
+ """
36
38
 
37
39
  STRIP = enum.auto()
38
40
  """Strip (or continuous) foundation, typically long and narrow."""
@@ -92,12 +94,16 @@ class FootingSize(ABC):
92
94
  def length(self, value: float):
93
95
  raise NotImplementedError
94
96
 
97
+ def area(self) -> float:
98
+ raise NotImplementedError
99
+
95
100
  @property
96
101
  def shape(self) -> Shape:
97
102
  """Return the shape of the foundation footing."""
98
103
  return self._SHAPE
99
104
 
100
105
 
106
+ @add_repr
101
107
  class StripFooting(FootingSize):
102
108
  """A class representation of strip footing."""
103
109
 
@@ -131,7 +137,14 @@ class StripFooting(FootingSize):
131
137
  def length(self, val: Annotated[float, MustBePositive]) -> None:
132
138
  self._length = val
133
139
 
140
+ def area(self) -> float:
141
+ """Area of strip footing ($m \text{or} m^2$)."""
142
+ if math.isinf(self.length):
143
+ return self.width
144
+ return self.width * self.length
145
+
134
146
 
147
+ @add_repr
135
148
  class CircularFooting(FootingSize):
136
149
  """A class representation of circular footing.
137
150
 
@@ -180,7 +193,12 @@ class CircularFooting(FootingSize):
180
193
  def length(self, val: float):
181
194
  self.diameter = val
182
195
 
196
+ def area(self) -> float:
197
+ """Area of circular footing ($m^2$)."""
198
+ return pi * self.diameter ** 2 / 4
183
199
 
200
+
201
+ @add_repr
184
202
  class SquareFooting(FootingSize):
185
203
  """A class representation of square footing."""
186
204
 
@@ -212,7 +230,12 @@ class SquareFooting(FootingSize):
212
230
  def length(self, val):
213
231
  self.width = val
214
232
 
233
+ def area(self) -> float:
234
+ """Area of square footing ($m^2$)."""
235
+ return self.width ** 2
236
+
215
237
 
238
+ @add_repr
216
239
  class RectangularFooting(FootingSize):
217
240
  """A class representation of rectangular footing."""
218
241
 
@@ -246,7 +269,12 @@ class RectangularFooting(FootingSize):
246
269
  def length(self, val: Annotated[float, MustBePositive]) -> None:
247
270
  self._length = val
248
271
 
272
+ def area(self) -> float:
273
+ """Area of rectangular footing ($m^2$)."""
274
+ return self.width * self.length
249
275
 
276
+
277
+ @add_repr
250
278
  class Foundation:
251
279
  """A simple class representing a foundation structure."""
252
280
 
@@ -360,6 +388,11 @@ class Foundation:
360
388
  ):
361
389
  self._foundation_type = val
362
390
 
391
+ @round_(2)
392
+ def foundation_area(self) -> float:
393
+ """Returns the area of the foundation footing ($m^2$)."""
394
+ return self.footing_size.area()
395
+
363
396
  @property
364
397
  def effective_width(self) -> float:
365
398
  """Returns the effective width of the foundation footing (m)."""
@@ -370,7 +403,7 @@ class Foundation:
370
403
  of the foundation footing.
371
404
  """
372
405
  width, length, shape = (
373
- self.effective_width, self.length, self.footing_shape)
406
+ self.effective_width, self.length, self.footing_shape)
374
407
 
375
408
  if not isclose(width, length) and shape != Shape.STRIP:
376
409
  shape = Shape.RECTANGLE
@@ -382,10 +415,10 @@ class Foundation:
382
415
  def create_foundation(
383
416
  depth: float,
384
417
  width: float,
385
- length: Optional[float] = None,
418
+ length: float = inf,
386
419
  eccentricity: float = 0.0,
387
420
  load_angle: float = 0.0,
388
- ground_water_level: Optional[float] = None,
421
+ ground_water_level: Optional[float] = inf,
389
422
  foundation_type: FoundationType = "pad",
390
423
  shape: Annotated[Shape | str, MustBeMemberOf(Shape)] = "square",
391
424
  ) -> Foundation:
@@ -423,7 +456,7 @@ def create_foundation(
423
456
  elif shape is Shape.CIRCLE:
424
457
  footing_size = CircularFooting(diameter=width)
425
458
  else: # RECTANGLE
426
- if not length:
459
+ if isinf(length):
427
460
  msg = "Length of rectangular footing must be provided."
428
461
  raise ValueError(msg)
429
462
  footing_size = RectangularFooting(width=width, length=length)
@@ -353,8 +353,7 @@ class _SizeDistribution:
353
353
  Features obtained from the Particle Size Distribution graph.
354
354
  """
355
355
 
356
- def __init__(self, d_10: float = 0.0, d_30: float = 0.0,
357
- d_60: float = 0.0):
356
+ def __init__(self, d_10: float = 0.0, d_30: float = 0.0, d_60: float = 0.0):
358
357
  self.d_10 = d_10
359
358
  self.d_30 = d_30
360
359
  self.d_60 = d_60
@@ -364,7 +363,7 @@ class _SizeDistribution:
364
363
 
365
364
  @property
366
365
  def coeff_of_curvature(self) -> float:
367
- return (self.d_30 ** 2.0) / (self.d_60 * self.d_10)
366
+ return (self.d_30**2.0) / (self.d_60 * self.d_10)
368
367
 
369
368
  @property
370
369
  def coeff_of_uniformity(self) -> float:
@@ -397,12 +396,12 @@ class PSD:
397
396
  """
398
397
 
399
398
  def __init__(
400
- self,
401
- fines: float,
402
- sand: float,
403
- d_10: float = 0,
404
- d_30: float = 0,
405
- d_60: float = 0,
399
+ self,
400
+ fines: float,
401
+ sand: float,
402
+ d_10: float = 0,
403
+ d_30: float = 0,
404
+ d_60: float = 0,
406
405
  ):
407
406
  """
408
407
  :param fines: Percentage of fines in soil sample (%) i.e. The
@@ -649,10 +648,10 @@ class USCS:
649
648
  """
650
649
 
651
650
  def __init__(
652
- self,
653
- atterberg_limits: AtterbergLimits,
654
- psd: PSD,
655
- organic=False,
651
+ self,
652
+ atterberg_limits: AtterbergLimits,
653
+ psd: PSD,
654
+ organic=False,
656
655
  ):
657
656
  """
658
657
  :param atterberg_limits: Atterberg limits of the soil.
@@ -779,9 +778,9 @@ class USCS:
779
778
 
780
779
 
781
780
  def create_aashto_classifier(
782
- liquid_limit: float,
783
- plastic_limit: float,
784
- fines: float,
781
+ liquid_limit: float,
782
+ plastic_limit: float,
783
+ fines: float,
785
784
  ) -> AASHTO:
786
785
  """A helper function that encapsulates the creation of a AASHTO
787
786
  classifier.
@@ -806,14 +805,14 @@ def create_aashto_classifier(
806
805
 
807
806
 
808
807
  def create_uscs_classifier(
809
- liquid_limit: float,
810
- plastic_limit: float,
811
- fines: float,
812
- sand: float,
813
- d_10: float = 0,
814
- d_30: float = 0,
815
- d_60: float = 0,
816
- organic: bool = False,
808
+ liquid_limit: float,
809
+ plastic_limit: float,
810
+ fines: float,
811
+ sand: float,
812
+ d_10: float = 0,
813
+ d_30: float = 0,
814
+ d_60: float = 0,
815
+ organic: bool = False,
817
816
  ):
818
817
  """A helper function that encapsulates the creation of a USCS
819
818
  classifier.