geolysis 0.10.3__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,124 +26,77 @@ 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
-
56
- - $q_u$ (kPa): Ultimate bearing capacity
57
- - $c$ (kPa): Cohesion of soil
58
- - $q$ (kPa): Overburden pressure of soil
59
- - $\gamma$ (kN/m³): Unit weight of soil
60
- - $B$ (m): Width of foundation footing
61
- - $L$ (m): Length of foundation footing
62
- - $N_c$, $N_q$, $N_{\gamma}$: Bearing capacity factors
63
-
64
-
65
- :param friction_angle: Internal angle of friction for general
66
- shear failure (degrees).
67
- :param cohesion: Cohesion of soil ($kPa$).
68
- :param moist_unit_wgt: Moist unit weight of soil ($kN/m^3$).
69
- :param foundation_size: Size of the foundation.
70
- :param apply_local_shear: Indicate whether bearing capacity
71
- failure is general shear or local
72
- shear failure.
73
- """
74
- super().__init__(
75
- friction_angle=friction_angle,
76
- cohesion=cohesion,
77
- moist_unit_wgt=moist_unit_wgt,
78
- foundation_size=foundation_size,
79
- apply_local_shear=apply_local_shear,
80
- )
48
+ @add_repr
49
+ class TerzaghiUltimateBearingCapacity(UltimateBearingCapacity):
81
50
 
82
51
  @property
83
52
  def n_c(self) -> float:
84
- r"""Bearing capacity factor $N_c$.
85
-
86
- $$N_c = \cot(\phi) \cdot (N_q - 1)$$
87
- """
53
+ r"""Bearing capacity factor $N_c$."""
88
54
  return TerzaghiBearingCapacityFactors.n_c(self.friction_angle)
89
55
 
90
56
  @property
91
57
  def n_q(self) -> float:
92
- r"""Bearing capacity factor $N_q$.
93
-
94
- $$
95
- N_q = \dfrac{e^{(\frac{3\pi}{2} - \phi)\tan\phi}}
96
- {2\cos^2(45 + \frac{\phi}{2})}
97
- $$
98
- """
58
+ r"""Bearing capacity factor $N_q$."""
99
59
  return TerzaghiBearingCapacityFactors.n_q(self.friction_angle)
100
60
 
101
61
  @property
102
62
  def n_gamma(self) -> float:
103
- r"""Bearing capacity factor $N_{\gamma}$.
104
-
105
- $$N_{\gamma} = (N_q - 1) \cdot \tan(1.4\phi)$$
106
- """
63
+ r"""Bearing capacity factor $N_{\gamma}$."""
107
64
  return TerzaghiBearingCapacityFactors.n_gamma(self.friction_angle)
108
65
 
109
66
 
110
67
  class TerzaghiUBC4StripFooting(TerzaghiUltimateBearingCapacity):
111
- r"""Ultimate bearing capacity for strip footing according to
68
+ """Ultimate bearing capacity for strip footing according to
112
69
  `Terzaghi 1943`.
113
70
 
114
- $$q_u = cN_c + qN_q + 0.5 \gamma BN_{\gamma}$$
71
+ See [implementation](../formulas/ultimate-bearing-capacity.md/#terzaghi-bearing-capacity-for-strip-footing)
72
+ for more details on bearing capacity equation used.
115
73
  """
116
74
 
117
75
  @round_(ndigits=2)
118
- def bearing_capacity(self) -> float:
76
+ def _bearing_capacity(self) -> float:
119
77
  """Calculates ultimate bearing capacity for strip footing."""
120
78
  return (
121
- self._cohesion_term(1.0)
122
- + self._surcharge_term()
123
- + self._embedment_term(0.5)
79
+ self._cohesion_term(1.0)
80
+ + self._surcharge_term()
81
+ + self._embedment_term(0.5)
124
82
  )
125
83
 
126
84
 
127
85
  class TerzaghiUBC4CircularFooting(TerzaghiUltimateBearingCapacity):
128
- r"""Ultimate bearing capacity for circular footing according to
86
+ """Ultimate bearing capacity for circular footing according to
129
87
  `Terzaghi 1943`.
130
88
 
131
- $$q_u = 1.3cN_c + qN_q + 0.3 \gamma BN_{\gamma}$$
89
+ See [implementation](../formulas/ultimate-bearing-capacity.md/#terzaghi-bearing-capacity-for-circular-footing)
90
+ for more details on bearing capacity equation used.
132
91
  """
133
92
 
134
93
  @round_(ndigits=2)
135
- def bearing_capacity(self) -> float:
94
+ def _bearing_capacity(self) -> float:
136
95
  """Calculates ultimate bearing capacity for circular footing."""
137
96
  return (
138
- self._cohesion_term(1.3)
139
- + self._surcharge_term()
140
- + self._embedment_term(0.3)
97
+ self._cohesion_term(1.3)
98
+ + self._surcharge_term()
99
+ + self._embedment_term(0.3)
141
100
  )
142
101
 
143
102
 
@@ -145,14 +104,12 @@ class TerzaghiUBC4RectangularFooting(TerzaghiUltimateBearingCapacity):
145
104
  r"""Ultimate bearing capacity for rectangular footing according to
146
105
  `Terzaghi 1943`.
147
106
 
148
- $$
149
- q_u = \left(1 + 0.3 \dfrac{B}{L} \right) c N_c + qN_q
150
- + \left(1 - 0.2 \dfrac{B}{L} \right) 0.5 B \gamma N_{\gamma}
151
- $$
107
+ See [implementation](../formulas/ultimate-bearing-capacity.md/#terzaghi-bearing-capacity-for-rectangular-footing)
108
+ for more details on bearing capacity equation used.
152
109
  """
153
110
 
154
111
  @round_(ndigits=2)
155
- def bearing_capacity(self) -> float:
112
+ def _bearing_capacity(self) -> float:
156
113
  """Calculates ultimate bearing capacity for rectangular footing."""
157
114
  width = self.foundation_size.width
158
115
  length = self.foundation_size.length
@@ -160,19 +117,20 @@ class TerzaghiUBC4RectangularFooting(TerzaghiUltimateBearingCapacity):
160
117
  emb_coef = (1.0 - 0.2 * (width / length)) / 2.0
161
118
 
162
119
  return (
163
- self._cohesion_term(coh_coef)
164
- + self._surcharge_term()
165
- + self._embedment_term(emb_coef)
120
+ self._cohesion_term(coh_coef)
121
+ + self._surcharge_term()
122
+ + self._embedment_term(emb_coef)
166
123
  )
167
124
 
168
125
 
169
126
  class TerzaghiUBC4SquareFooting(TerzaghiUBC4RectangularFooting):
170
- r"""Ultimate bearing capacity for square footing according to
127
+ """Ultimate bearing capacity for square footing according to
171
128
  `Terzaghi 1943``.
172
129
 
173
- $$q_u = 1.3cN_c + qN_q + 0.4 \gamma BN_{\gamma}$$
130
+ See [implementation](../formulas/ultimate-bearing-capacity.md/#terzaghi-bearing-capacity-for-square-footing)
131
+ for more details on bearing capacity equation used.
174
132
  """
175
133
 
176
- def bearing_capacity(self):
134
+ def _bearing_capacity(self):
177
135
  """Calcalates ultimate bearing capacity for square footing."""
178
- 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
 
@@ -24,31 +24,29 @@ class VesicBearingCapacityFactors:
24
24
  return (
25
25
  2.0
26
26
  * (VesicBearingCapacityFactors.n_q(friction_angle) + 1.0)
27
- * tan(friction_angle)
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
35
  friction_angle: float,
36
36
  f_width: float,
37
37
  f_length: float,
38
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
51
  friction_angle: float,
54
52
  f_width: float,
@@ -57,38 +55,70 @@ class VesicShapeFactors:
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) * (1.0 - sin(friction_angle)) ** 2.0 * (
87
- f_depth / f_width
88
- )
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
89
120
 
90
121
  @staticmethod
91
- @round_(ndigits=2)
92
122
  def d_gamma() -> float:
93
123
  return 1.0
94
124
 
@@ -96,158 +126,92 @@ class VesicDepthFactors:
96
126
  class VesicInclinationFactors:
97
127
 
98
128
  @staticmethod
99
- @round_(ndigits=2)
129
+ @round_(ndigits=3)
100
130
  def i_c(load_angle: float) -> float:
101
131
  return (1.0 - load_angle / 90.0) ** 2.0
102
132
 
103
133
  @staticmethod
104
- @round_(ndigits=2)
134
+ @round_(ndigits=3)
105
135
  def i_q(load_angle: float) -> float:
106
136
  return VesicInclinationFactors.i_c(load_angle)
107
137
 
108
138
  @staticmethod
109
- @round_(ndigits=2)
139
+ @round_(ndigits=3)
110
140
  def i_gamma(friction_angle: float, load_angle: float) -> float:
111
141
  if isclose(friction_angle, 0.0):
112
142
  return 1.0
113
143
  return (1.0 - load_angle / friction_angle) ** 2.0
114
144
 
115
145
 
146
+ @add_repr
116
147
  class VesicUltimateBearingCapacity(UltimateBearingCapacity):
117
- """Ultimate bearing capacity for soils according to `Vesic (1973)`."""
148
+ """Ultimate bearing capacity for soils according to `Vesic (1973)`.
149
+
150
+ See [implementation](../formulas/ultimate-bearing-capacity.md/#vesic-bearing-capacity)
151
+ for more details on bearing capacity equation used.
152
+ """
118
153
 
119
154
  @property
120
155
  def n_c(self) -> float:
121
- r"""Bearing capacity factor $N_c$.
122
-
123
- $$N_c = \cot(\phi) \left(N_q - 1\right)$$
124
- """
156
+ r"""Bearing capacity factor $N_c$."""
125
157
  return VesicBearingCapacityFactors.n_c(self.friction_angle)
126
158
 
127
159
  @property
128
160
  def n_q(self) -> float:
129
- r"""Bearing capacity factor $N_q$.
130
-
131
- $$
132
- N_q = \tan^2\left(45 + \frac{\phi}{2}\right) \cdot
133
- e^{\pi \tan(\phi)}
134
- $$
135
- """
161
+ r"""Bearing capacity factor $N_q$."""
136
162
  return VesicBearingCapacityFactors.n_q(self.friction_angle)
137
163
 
138
164
  @property
139
165
  def n_gamma(self) -> float:
140
- r"""Bearing capacity factor $N_{\gamma}$.
141
-
142
- $$N_{\gamma} = 2(N_q + 1) \tan(\phi)$$
143
- """
166
+ r"""Bearing capacity factor $N_{\gamma}$."""
144
167
  return VesicBearingCapacityFactors.n_gamma(self.friction_angle)
145
168
 
146
169
  @property
147
170
  def s_c(self) -> float:
148
- r"""Shape factor $S_c$.
149
-
150
- $$s_c = 1.0 \rightarrow \text{Strip footing}$$
151
-
152
- $$
153
- s_c = 1 + \dfrac{B}{L} \cdot \dfrac{N_q}{N_c} \rightarrow
154
- \text{Rectangular footing}
155
- $$
156
-
157
- $$
158
- s_c &= 1 + \dfrac{N_q}{N_c} \rightarrow
159
- \text{Square or circular footing}
160
- $$
161
- """
171
+ r"""Shape factor $S_c$."""
162
172
  width, length, shape = self.foundation_size.footing_params()
163
173
  return VesicShapeFactors.s_c(self.friction_angle, width, length, shape)
164
174
 
165
175
  @property
166
176
  def s_q(self) -> float:
167
- r"""Shape factor $S_q$.
168
-
169
-
170
- $$s_q = 1.0 \rightarrow \text{Strip footing}$$
171
-
172
- $$
173
- s_q = 1 + \dfrac{B}{L} \cdot \tan(\phi) \rightarrow
174
- \text{Rectangular footing}
175
- $$
176
-
177
- $$
178
- s_q = 1 + \tan(\phi) \rightarrow \text{Square or circular footing}
179
- $$
180
- """
177
+ r"""Shape factor $S_q$."""
181
178
  width, length, shape = self.foundation_size.footing_params()
182
179
  return VesicShapeFactors.s_q(self.friction_angle, width, length, shape)
183
180
 
184
181
  @property
185
182
  def s_gamma(self) -> float:
186
- r"""Shape factor $S_{\gamma}$.
187
-
188
- $$s_{\gamma} = 1.0 \rightarrow \text{Strip footing}$$
189
-
190
- $$
191
- s_{\gamma} = 1.0 - 0.4 \dfrac{B}{L} \rightarrow
192
- \text{Rectangular footing}
193
- $$
194
-
195
- $$
196
- s_{\gamma} = 0.6 \rightarrow \text{Square or circular footing}
197
- $$
198
- """
183
+ r"""Shape factor $S_{\gamma}$."""
199
184
  width, length, shape = self.foundation_size.footing_params()
200
185
  return VesicShapeFactors.s_gamma(width, length, shape)
201
186
 
202
187
  @property
203
188
  def d_c(self) -> float:
204
- r"""Depth factor $D_c$.
205
-
206
- $$d_c = 1 + 0.4 \dfrac{D_f}{B}$$
207
- """
189
+ r"""Depth factor $D_c$."""
208
190
  depth, width = self.foundation_size.depth, self.foundation_size.width
209
- return VesicDepthFactors.d_c(depth, width)
191
+ return VesicDepthFactors.d_c(self.friction_angle, depth, width)
210
192
 
211
193
  @property
212
194
  def d_q(self) -> float:
213
- r"""Depth factor $D_q$.
214
-
215
- $$
216
- d_q = 1 + 2 \tan(\phi) \cdot (1 - \sin(\phi))^2
217
- \cdot \dfrac{D_f}{B}
218
- $$
219
- """
195
+ r"""Depth factor $D_q$."""
220
196
  depth, width = self.foundation_size.depth, self.foundation_size.width
221
197
  return VesicDepthFactors.d_q(self.friction_angle, depth, width)
222
198
 
223
199
  @property
224
200
  def d_gamma(self) -> float:
225
- r"""Depth factor $D_{\gamma}$.
226
-
227
- $$d_{\gamma} = 1.0$$
228
- """
201
+ r"""Depth factor $D_{\gamma}$."""
229
202
  return VesicDepthFactors.d_gamma()
230
203
 
231
204
  @property
232
205
  def i_c(self) -> float:
233
- r"""Inclination factor $I_c$.
234
-
235
- $$i_c = (1 - \dfrac{\alpha}{90})^2$$
236
- """
206
+ r"""Inclination factor $I_c$."""
237
207
  return VesicInclinationFactors.i_c(self.load_angle)
238
208
 
239
209
  @property
240
210
  def i_q(self) -> float:
241
- r"""Inclination factor $I_q$.
242
-
243
- $$i_q = (1 - \dfrac{\alpha}{90})^2$$
244
- """
211
+ r"""Inclination factor $I_q$."""
245
212
  return VesicInclinationFactors.i_q(self.load_angle)
246
213
 
247
214
  @property
248
215
  def i_gamma(self) -> float:
249
- r"""Inclination factor $I_{\gamma}$.
250
-
251
- $$i_{\gamma} = \left(1 - \dfrac{\alpha}{\phi} \right)^2$$
252
- """
216
+ r"""Inclination factor $I_{\gamma}$."""
253
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)