geolysis 0.3.0__py3-none-any.whl → 0.4.3__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.
geolysis/__init__.py CHANGED
@@ -1,3 +1 @@
1
- from . import core
2
-
3
- __version__ = "0.3.0"
1
+ __version__ = "0.4.3"
geolysis/foundation.py ADDED
@@ -0,0 +1,393 @@
1
+ """ Basic foundation module.
2
+
3
+ Enums
4
+ =====
5
+
6
+ .. autosummary::
7
+ :toctree: _autosummary
8
+ :nosignatures:
9
+
10
+ Shape
11
+ FoundationType
12
+
13
+ Classes
14
+ =======
15
+
16
+ .. autosummary::
17
+ :toctree: _autosummary
18
+
19
+ StripFooting
20
+ CircularFooting
21
+ SquareFooting
22
+ RectangularFooting
23
+ FoundationSize
24
+
25
+ Functions
26
+ =========
27
+
28
+ .. autosummary::
29
+ :toctree: _autosummary
30
+
31
+ create_foundation
32
+ """
33
+
34
+ import enum
35
+ from abc import ABC, abstractmethod
36
+ from typing import Optional, TypeVar
37
+
38
+ from geolysis.utils import inf, enum_repr, isclose, validators
39
+
40
+ __all__ = ["create_foundation",
41
+ "FoundationSize",
42
+ "FoundationType",
43
+ "Shape",
44
+ "StripFooting",
45
+ "CircularFooting",
46
+ "SquareFooting",
47
+ "RectangularFooting"]
48
+
49
+ T = TypeVar("T")
50
+
51
+
52
+ @enum_repr
53
+ class Shape(enum.StrEnum):
54
+ """Enumeration of foundation shapes."""
55
+ STRIP = enum.auto()
56
+ CIRCLE = enum.auto()
57
+ SQUARE = enum.auto()
58
+ RECTANGLE = enum.auto()
59
+
60
+
61
+ @enum_repr
62
+ class FoundationType(enum.StrEnum):
63
+ """Enumeration of foundation types."""
64
+ PAD = ISOLATED = enum.auto()
65
+ MAT = RAFT = enum.auto()
66
+
67
+
68
+ class FootingSize(ABC):
69
+ SHAPE: Shape
70
+
71
+ @property
72
+ @abstractmethod
73
+ def width(self) -> float:
74
+ raise NotImplementedError
75
+
76
+ @width.setter
77
+ def width(self, value: float):
78
+ raise NotImplementedError
79
+
80
+ @property
81
+ @abstractmethod
82
+ def length(self) -> float:
83
+ raise NotImplementedError
84
+
85
+ @length.setter
86
+ def length(self, value: float):
87
+ raise NotImplementedError
88
+
89
+ @property
90
+ def shape(self) -> Shape:
91
+ return self.SHAPE
92
+
93
+
94
+ class StripFooting(FootingSize):
95
+ """A class representation of strip footing."""
96
+
97
+ SHAPE = Shape.STRIP
98
+
99
+ def __init__(self, width: float, length: float = inf) -> None:
100
+ """
101
+ :param width: Width of foundation footing (m).
102
+ :type width: float
103
+
104
+ :param float length: Length of foundation footing, defaults to inf (m).
105
+ :type length: float
106
+ """
107
+ self.width = width
108
+ self.length = length
109
+
110
+ @property
111
+ def width(self) -> float:
112
+ return self._width
113
+
114
+ @width.setter
115
+ @validators.gt(0.0)
116
+ def width(self, val: float):
117
+ self._width = val
118
+
119
+ @property
120
+ def length(self) -> float:
121
+ return self._length
122
+
123
+ @length.setter
124
+ @validators.ge(0.0)
125
+ def length(self, val: float):
126
+ self._length = val
127
+
128
+
129
+ class CircularFooting(FootingSize):
130
+ """A class representation of circular footing.
131
+
132
+ .. note::
133
+
134
+ The ``width`` and ``length`` properties refer to the diameter of the
135
+ circular footing. This is to make it compatible with the protocol
136
+ square and rectangular footing follow.
137
+ """
138
+
139
+ SHAPE = Shape.CIRCLE
140
+
141
+ def __init__(self, diameter: float):
142
+ """
143
+ :param float diameter: Diameter of foundation footing (m).
144
+ """
145
+ self.diameter = diameter
146
+
147
+ @property
148
+ def diameter(self) -> float:
149
+ return self._diameter
150
+
151
+ @diameter.setter
152
+ @validators.gt(0.0)
153
+ def diameter(self, val: float):
154
+ self._diameter = val
155
+
156
+ @property
157
+ def width(self):
158
+ return self.diameter
159
+
160
+ @width.setter
161
+ def width(self, val: float):
162
+ self.diameter = val
163
+
164
+ @property
165
+ def length(self):
166
+ return self.diameter
167
+
168
+ @length.setter
169
+ def length(self, val: float):
170
+ self.diameter = val
171
+
172
+
173
+ class SquareFooting(FootingSize):
174
+ """A class representation of square footing."""
175
+
176
+ SHAPE = Shape.SQUARE
177
+
178
+ def __init__(self, width: float):
179
+ """
180
+ :param float width: Width of foundation footing (m).
181
+ """
182
+ self.width = width
183
+
184
+ @property
185
+ def width(self):
186
+ return self._width
187
+
188
+ @width.setter
189
+ @validators.gt(0)
190
+ def width(self, val):
191
+ self._width = val
192
+
193
+ @property
194
+ def length(self):
195
+ return self.width
196
+
197
+ @length.setter
198
+ def length(self, val):
199
+ self.width = val
200
+
201
+
202
+ class RectangularFooting(FootingSize):
203
+ """A class representation of rectangular footing."""
204
+
205
+ SHAPE = Shape.RECTANGLE
206
+
207
+ def __init__(self, width: float, length: float):
208
+ """
209
+ :param width: Width of foundation footing (m).
210
+ :type width: float
211
+
212
+ :param length: Length of foundation footing (m).
213
+ :type length: float
214
+ """
215
+ self.width = width
216
+ self.length = length
217
+
218
+ @property
219
+ def width(self) -> float:
220
+ return self._width
221
+
222
+ @width.setter
223
+ @validators.gt(0.0)
224
+ def width(self, val):
225
+ self._width = val
226
+
227
+ @property
228
+ def length(self) -> float:
229
+ return self._length
230
+
231
+ @length.setter
232
+ @validators.gt(0.0)
233
+ def length(self, val):
234
+ self._length = val
235
+
236
+
237
+ class FoundationSize:
238
+ """A simple class representing a foundation structure."""
239
+
240
+ def __init__(self, depth: float,
241
+ footing_size: FootingSize,
242
+ eccentricity: float = 0.0,
243
+ ground_water_level: Optional[float] = None) -> None:
244
+ """
245
+ :param depth: Depth of foundation (m).
246
+ :type depth: float
247
+
248
+ :param footing_size: Represents the size of the foundation footing.
249
+ :type footing_size: FootingSize
250
+
251
+ :param eccentricity: The deviation of the foundation load from the
252
+ center of gravity of the foundation footing,
253
+ defaults to 0.0. This means that the foundation
254
+ load aligns with the center of gravity of the
255
+ foundation footing (m).
256
+ :type eccentricity: float, optional
257
+
258
+ :param ground_water_level: Depth of the water below ground level (m),
259
+ defaults to inf.
260
+ :type ground_water_level: float, optional
261
+ """
262
+ self.depth = depth
263
+ self.footing_size = footing_size
264
+ self.eccentricity = eccentricity
265
+ self._ground_water_level = ground_water_level
266
+
267
+ @property
268
+ def depth(self) -> float:
269
+ return self._depth
270
+
271
+ @depth.setter
272
+ @validators.gt(0.0)
273
+ def depth(self, val: float) -> None:
274
+ self._depth = val
275
+
276
+ @property
277
+ def width(self):
278
+ return self.footing_size.width
279
+
280
+ @width.setter
281
+ def width(self, val: float):
282
+ self.footing_size.width = val
283
+
284
+ @property
285
+ def length(self):
286
+ return self.footing_size.length
287
+
288
+ @length.setter
289
+ def length(self, val: float):
290
+ self.footing_size.length = val
291
+
292
+ @property
293
+ def footing_shape(self):
294
+ return self.footing_size.shape
295
+
296
+ @property
297
+ def eccentricity(self) -> float:
298
+ return self._eccentricity
299
+
300
+ @eccentricity.setter
301
+ @validators.ge(0.0)
302
+ def eccentricity(self, val: float) -> None:
303
+ self._eccentricity = val
304
+
305
+ @property
306
+ def ground_water_level(self) -> Optional[float]:
307
+ return self._ground_water_level
308
+
309
+ @ground_water_level.setter
310
+ @validators.ge(0.0)
311
+ def ground_water_level(self, val: float) -> None:
312
+ self._ground_water_level = val
313
+
314
+ @property
315
+ def effective_width(self) -> float:
316
+ """Returns the effective width of the foundation footing."""
317
+ return self.width - 2.0 * self.eccentricity
318
+
319
+ def footing_params(self) -> tuple[float, float, Shape]:
320
+ """Returns the ``width``, ``length``, and ``shape`` of the
321
+ foundation footing.
322
+
323
+ .. note:: "width" is the effective width of the foundation footing.
324
+ """
325
+ width, length, shape = self.effective_width, self.length, self.footing_shape
326
+
327
+ if not isclose(width, length) and shape != Shape.STRIP:
328
+ shape = Shape.RECTANGLE
329
+
330
+ return width, length, shape
331
+
332
+
333
+ def create_foundation(depth: float,
334
+ width: float,
335
+ length: Optional[float] = None,
336
+ eccentricity: float = 0.0,
337
+ ground_water_level: Optional[float] = None,
338
+ shape: Shape | str = Shape.SQUARE) -> FoundationSize:
339
+ """A factory function that encapsulate the creation of a foundation.
340
+
341
+ :param depth: Depth of foundation (m).
342
+ :type depth: float
343
+
344
+ :param width: Width of foundation footing. In the case of a circular
345
+ footing, it refers to the footing diameter (m).
346
+ :type width: float
347
+
348
+ :param length: Length of foundation footing (m), defaults to None.
349
+ :type length: float, optional
350
+
351
+ :param eccentricity: The deviation of the foundation load from the
352
+ center of gravity of the foundation footing (m),
353
+ defaults to 0.0. This means that the foundation
354
+ load aligns with the center of gravity of the
355
+ foundation footing .
356
+ :type eccentricity: float, optional
357
+
358
+ :param ground_water_level: Depth of the water below ground level (m),
359
+ defaults to None.
360
+ :type ground_water_level: float, optional
361
+
362
+ :param shape: Shape of foundation footing, defaults to :class:`Shape.SQUARE`
363
+ :type shape: Shape | str
364
+
365
+ :raises ValueError: Raised when length is not provided for a rectangular
366
+ footing.
367
+ :raises ValueError: Raised if an invalid footing shape is provided.
368
+ """
369
+ shape = str(shape).casefold()
370
+
371
+ try:
372
+ shape = Shape(shape)
373
+ except ValueError as e:
374
+ msg = (f"{shape = } is not supported, Supported "
375
+ f"types are: {list(Shape)}")
376
+
377
+ raise ValueError(msg) from e
378
+
379
+ if shape is Shape.STRIP:
380
+ footing_size = StripFooting(width=width)
381
+ elif shape is Shape.SQUARE:
382
+ footing_size = SquareFooting(width=width)
383
+ elif shape is Shape.CIRCLE:
384
+ footing_size = CircularFooting(diameter=width)
385
+ else: # RECTANGLE
386
+ if not length:
387
+ raise ValueError("Length of footing must be provided.")
388
+ footing_size = RectangularFooting(width=width, length=length)
389
+
390
+ return FoundationSize(depth=depth,
391
+ eccentricity=eccentricity,
392
+ ground_water_level=ground_water_level,
393
+ footing_size=footing_size)