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