geolysis 0.2.0__py3-none-any.whl → 0.3.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.
geolysis/spt.py DELETED
@@ -1,424 +0,0 @@
1
- import functools
2
- from statistics import StatisticsError
3
- from typing import Callable, Iterable, Sequence
4
-
5
- from geolysis.constants import ERROR_TOL, UNITS
6
- from geolysis.utils import FloatOrInt, isclose, log10, mean, round_, sqrt
7
-
8
- __all__ = [
9
- "weighted_avg_spt_n_val",
10
- "avg_uncorrected_spt_n_val",
11
- "SPTCorrections",
12
- ]
13
-
14
-
15
- class OverburdenPressureError(ValueError):
16
- """
17
- Exception raised for overburden pressure related errors.
18
- """
19
-
20
-
21
- @round_(ndigits=0)
22
- def weighted_avg_spt_n_val(corrected_spt_vals: Sequence[float]) -> float:
23
- r"""
24
- Calculates the weighted average of the corrected SPT N-values in the foundation
25
- influence zone. (:math:`N_{design}`)
26
-
27
- Due to uncertainty in field procedure in standard penetration test and also
28
- to consider all the N-value in the influence zone of a foundation, a method
29
- was suggested to calculate the design N-value which should be used in
30
- calculating the allowable bearing capacity of shallow foundation rather than
31
- using a particular N-value. All the N-value from the influence zone is taken
32
- under consideration by giving the highest weightage to the closest N-value
33
- from the base.
34
-
35
- The determination of :math:`N_{design}` is given by:
36
-
37
- .. math::
38
-
39
- N_{design} = \dfrac{\sum_{i=1}^{n} \frac{N_i}{i^2}}{\sum_{i=1}^{n} \frac{1}{i^2}}
40
-
41
- - influence zone = :math:`D_f + 2B` or to a depth up to which soil
42
- types are approximately the same.
43
- - B = width of footing
44
- - :math:`n` = number of layers in the influence zone.
45
- - :math:`N_i` = corrected N-value at ith layer from the footing base.
46
-
47
- .. note::
48
-
49
- Alternatively, for ease in calculation, the lowest N-value from the influence zone
50
- can be taken as the :math:`N_{design}` as suggested by ``Terzaghi & Peck (1948)``.
51
-
52
- :param Sequence[float] corrected_spt_vals: Corrected SPT N-values within the
53
- foundation influence zone i.e. :math:`D_f` to :math:`D_f + 2B`
54
-
55
- :return: Weighted average of corrected SPT N-values
56
- :rtype: float
57
-
58
- :raises StatisticError: If ``corrected_spt_vals`` is empty, StatisticError is raised.
59
- """
60
- if not corrected_spt_vals:
61
- err_msg = "spt_n_design requires at least one corrected spt n-value"
62
- raise StatisticsError(err_msg)
63
-
64
- total_num = 0.0
65
- total_den = 0.0
66
-
67
- for i, corrected_spt in enumerate(corrected_spt_vals, start=1):
68
- idx_weight = 1 / i**2
69
- total_num += idx_weight * corrected_spt
70
- total_den += idx_weight
71
-
72
- return total_num / total_den
73
-
74
-
75
- @round_(ndigits=0)
76
- def avg_uncorrected_spt_n_val(uncorrected_spt_vals: Sequence[float]) -> float:
77
- """
78
- Calculates the average of the uncorrected SPT N-values in the foundation
79
- influence zone.
80
-
81
- :param Sequence[float] uncorrected_spt_vals: Uncorrected SPT N-values within the
82
- foundation influence zone i.e. :math:`D_f` |rarr| :math:`D_f + 2B`. Only water
83
- table correction suggested.
84
-
85
- :return: Average of corrected SPT N-values
86
- :rtype: float
87
-
88
- :raises StatisticError: If ``uncorrected_spt_vals`` is empty, StatisticError is raised.
89
- """
90
- if not uncorrected_spt_vals:
91
- msg = "spt_n_val requires at least one corrected spt n-value"
92
- raise StatisticsError(msg)
93
-
94
- return mean(uncorrected_spt_vals)
95
-
96
-
97
- class SPTCorrections:
98
- r"""
99
- SPT N-value correction for **Overburden Pressure** and **Dilatancy**.
100
-
101
- There are three (3) different SPT corrections namely:
102
-
103
- - Energy Correction / Correction for Field Procedures
104
- - Overburden Pressure Corrections
105
- - Dilatancy Correction
106
-
107
- Energy correction is used to standardized the SPT N-values for field procedures.
108
-
109
- In cohesionless soils, penetration resistance is affected by overburden pressure.
110
- Soils with the same density but different confining pressures have varying penetration
111
- numbers, with higher confining pressures leading to higher penetration numbers. As depth
112
- increases, confining pressure rises, causing underestimation of penetration numbers
113
- at shallow depths and overestimation at deeper depths. The need for corrections in
114
- Standard Penetration Test (SPT) values was acknowledged only in 1957 by Gibbs & Holtz,
115
- meaning data published before this, like Terzaghi's, are based on uncorrected values.
116
-
117
- The general formula for overburden pressure correction is:
118
-
119
- .. math::
120
-
121
- (N_1)_{60} = C_N \cdot N_{60} \le 2 \cdot N_{60}
122
-
123
- Where:
124
-
125
- - :math:`C_N` = Overburden Pressure Correction Factor
126
-
127
- Available overburden pressure corrections are given by the following authors:
128
-
129
- - Gibbs & Holtz (1957)
130
- - Peck et al (1974)
131
- - Liao & Whitman (1986)
132
- - Skempton (1986)
133
- - Bazaraa & Peck (1969)
134
-
135
- **Dilatancy Correction** is a correction for silty fine sands and fine sands below the
136
- water table that develop pore pressure which is not easily dissipated. The pore pressure
137
- increases the resistance of the soil hence the standard penetration number (N).
138
- Correction of silty fine sands recommended by ``Terzaghi and Peck (1948)`` if :math:`N_{60}`
139
- exceeds 15.
140
- """
141
-
142
- unit = UNITS.unitless
143
-
144
- @staticmethod
145
- def map(
146
- opc_func: Callable[..., FloatOrInt],
147
- standardized_spt_vals: Iterable[float],
148
- dc_func: Callable[..., FloatOrInt] | None = None,
149
- **kwargs,
150
- ):
151
- """
152
- Returns an iterator from computing functions (``opc_func``, "dc_func") using
153
- arguments from the iterable (``standard_spt_vals``).
154
-
155
- :param Callable opc_func: Overburden pressure correction function to use.
156
- :param Callable | None dc_func: Dilatancy correction function to use.
157
- :param dict kwargs: Keyword arguments to pass to ```opc_func`.
158
- """
159
- opc_func = functools.partial(opc_func, **kwargs)
160
- corrected_spt_vals = map(opc_func, standardized_spt_vals)
161
-
162
- if dc_func:
163
- corrected_spt_vals = map(dc_func, corrected_spt_vals)
164
-
165
- return corrected_spt_vals
166
-
167
- @staticmethod
168
- @round_(ndigits=2)
169
- def energy_correction(
170
- recorded_spt_val: float,
171
- percentage_energy=0.6,
172
- *,
173
- hammer_efficiency=0.6,
174
- borehole_diameter_correction=1,
175
- sampler_correction=1,
176
- rod_length_correction=0.75,
177
- ) -> FloatOrInt:
178
- r"""
179
- Return SPT N-value standardized for field procedures.
180
-
181
- On the basis of field observations, it appears reasonable to standardize the field
182
- SPT N-value as a function of the input driving energy and its dissipation around
183
- the sampler around the surrounding soil. The variations in testing procedures may
184
- be at least partially compensated by converting the measured N-value to :math:`N_{60}`.
185
-
186
- .. math::
187
-
188
- N_{60} = \dfrac{E_H \cdot C_B \cdot C_S \cdot C_R \cdot N}{0.6}
189
-
190
- Where:
191
-
192
- - :math:`N_{60}` = Corrected SPT N-value for field procedures
193
- - :math:`E_{H}` = Hammer efficiency
194
- - :math:`C_{B}` = Borehole diameter correction
195
- - :math:`C_{S}` = Sampler correction
196
- - :math:`C_{R}` = Rod length correction
197
- - N = Recorded SPT N-value in field
198
-
199
- The values of :math:`E_H`, :math:`C_B`, :math:`C_S`, and :math:`C_R` can be found in
200
- the table below.
201
-
202
- .. table:: Correction table for field procedure of SPT N-value
203
-
204
- +--------------------+------------------------------+--------------------------------+
205
- | SPT Hammer Efficiencies |
206
- +====================+==============================+================================+
207
- | **Hammer Type** | **Hammer Release Mechanism** | **Efficiency**, :math:`E_H` |
208
- +--------------------+------------------------------+--------------------------------+
209
- | Automatic | Trip | 0.70 |
210
- +--------------------+------------------------------+--------------------------------+
211
- | Donut | Hand dropped | 0.60 |
212
- +--------------------+------------------------------+--------------------------------+
213
- | Donut | Cathead+2 turns | 0.50 |
214
- +--------------------+------------------------------+--------------------------------+
215
- | Safety | Cathead+2 turns | 0.55 - 0.60 |
216
- +--------------------+------------------------------+--------------------------------+
217
- | Drop/Pin | Hand dropped | 0.45 |
218
- +--------------------+------------------------------+--------------------------------+
219
- | Borehole, Sampler and Rod Correction |
220
- +--------------------+------------------------------+--------------------------------+
221
- | **Factor** | **Equipment Variables** | **Correction Factor** |
222
- +--------------------+------------------------------+--------------------------------+
223
- | Borehole Dia | 65 - 115 mm (2.5-4.5 in) | 1.00 |
224
- | Factor, | | |
225
- | :math:`C_B` | | |
226
- +--------------------+------------------------------+--------------------------------+
227
- | | 150 mm (6 in) | 1.05 |
228
- +--------------------+------------------------------+--------------------------------+
229
- | | 200 mm (8 in) | 1.15 |
230
- +--------------------+------------------------------+--------------------------------+
231
- | Sampler | Standard sampler | 1.00 |
232
- | Correction, | | |
233
- | :math:`C_S` | | |
234
- +--------------------+------------------------------+--------------------------------+
235
- | | Sampler without liner | 1.20 |
236
- | | (not recommended) | |
237
- +--------------------+------------------------------+--------------------------------+
238
- | Rod Length | 3 - 4 m (10-13 ft) | 0.75 |
239
- | Correction, | | |
240
- | :math:`C_R` | | |
241
- +--------------------+------------------------------+--------------------------------+
242
- | | 4 - 6 m (13-20 ft) | 0.85 |
243
- +--------------------+------------------------------+--------------------------------+
244
- | | 6 - 10 m (20-30 ft) | 0.95 |
245
- +--------------------+------------------------------+--------------------------------+
246
- | | >10 m (>30 ft) | 1.00 |
247
- +--------------------+------------------------------+--------------------------------+
248
-
249
- :param float percentage_energy: Percentage energy reaching the tip of the sampler.
250
- :param int recorded_spt_val: Recorded SPT N-value from field.
251
- :kwparam float hammer_efficiency: hammer efficiency, defaults to 0.6
252
- :kwparam float borehole_diameter_correction: borehole diameter correction,
253
- defaults to 1.0
254
- :kwparam float sampler_correction: sampler correction, defaults to 1.0
255
- :kwparam float rod_length_correction: rod Length correction, defaults to 0.75
256
-
257
- .. note::
258
-
259
- The ``energy correction`` is to be applied irrespective of the type of soil.
260
- """
261
- correction = (
262
- hammer_efficiency
263
- * borehole_diameter_correction
264
- * sampler_correction
265
- * rod_length_correction
266
- )
267
-
268
- return (correction * recorded_spt_val) / percentage_energy
269
-
270
- @staticmethod
271
- @round_(ndigits=2)
272
- def terzaghi_peck_dc_1948(corrected_spt_val: float) -> float:
273
- r"""
274
- Return the dilatancy spt correction.
275
-
276
- :param float corrected_spt_val: Corrected SPT N-value. This should be corrected
277
- using any of the overburden pressure corrections.
278
-
279
- .. math::
280
-
281
- (N_1)_{60} &= 15 + \dfrac{1}{2}((N_1)_{60} - 15) \, , \, (N_1)_{60} \gt 15
282
-
283
- (N_1)_{60} &= (N_1)_{60} \, , \, (N_1)_{60} \le 15
284
-
285
- .. note::
286
-
287
- For coarse sand, this correction is not required. In applying this correction,
288
- overburden pressure correction is applied first and then dilatancy correction
289
- is applied.
290
- """
291
-
292
- if corrected_spt_val <= 15:
293
- return corrected_spt_val
294
-
295
- return 15 + 0.5 * (corrected_spt_val - 15)
296
-
297
- @staticmethod
298
- @round_(ndigits=2)
299
- def gibbs_holtz_opc_1957(spt_n_60: float, eop: float) -> float:
300
- r"""
301
- Return the overburden pressure correction given by ``Gibbs and Holtz
302
- (1957)``.
303
-
304
- :param float spt_n_60: SPT N-value standardized for field procedures.
305
- :param float eop: Effective overburden pressure (:math:`kN/m^2`).
306
-
307
- .. math::
308
-
309
- C_N = \dfrac{350}{\sigma_o + 70} \, \sigma_o \le 280kN/m^2
310
-
311
- .. note::
312
-
313
- :math:`\frac{N_c}{N_{60}}` should lie between 0.45 and 2.0, if :math:`\frac{N_c}{N_{60}}`
314
- is greater than 2.0, :math:`N_c` should be divided by 2.0 to obtain the design value
315
- used in finding the bearing capacity of the soil.
316
- """
317
-
318
- std_pressure = 280
319
-
320
- if eop <= 0 or eop > std_pressure:
321
- err_msg = (
322
- f"eop: {eop} should be less than or equal to {std_pressure}"
323
- "but not less than or equal to 0"
324
- )
325
- raise OverburdenPressureError(err_msg)
326
-
327
- corrected_spt = spt_n_60 * (350 / (eop + 70))
328
- spt_ratio = corrected_spt / spt_n_60
329
-
330
- if 0.45 < spt_ratio < 2.0:
331
- return corrected_spt
332
-
333
- corrected_spt = corrected_spt / 2 if spt_ratio > 2.0 else corrected_spt
334
- return min(corrected_spt, 2 * spt_n_60)
335
-
336
- @staticmethod
337
- @round_(ndigits=2)
338
- def peck_et_al_opc_1974(spt_n_60: float, eop: float) -> float:
339
- r"""
340
- Return the overburden pressure given by ``Peck et al (1974)``.
341
-
342
- :param float spt_n_60: SPT N-value standardized for field procedures.
343
- :param float eop: Effective overburden pressure (:math:`kN/m^2`).
344
-
345
- .. math::
346
-
347
- C_N = 0.77 \log \left( \dfrac{2000}{\sigma_o} \right)
348
- """
349
- std_pressure = 24
350
-
351
- if eop <= 0 or eop < std_pressure:
352
- err_msg = f"eop: {eop} >= {std_pressure}"
353
- raise OverburdenPressureError(err_msg)
354
-
355
- corrected_spt = 0.77 * log10(2000 / eop) * spt_n_60
356
- return min(corrected_spt, 2 * spt_n_60)
357
-
358
- @staticmethod
359
- @round_(ndigits=2)
360
- def liao_whitman_opc_1986(spt_n_60: float, eop: float) -> float:
361
- r"""
362
- Return the overburden pressure given by ``Liao Whitman (1986)``.
363
-
364
- :param float spt_n_60: SPT N-value standardized for field procedures.
365
- :param float eop: Effective overburden pressure (:math:`kN/m^2`).
366
-
367
- .. math::
368
-
369
- C_N = \sqrt{\dfrac{100}{\sigma_o}}
370
- """
371
- if eop <= 0:
372
- err_msg = f"eop: {eop} > 0"
373
- raise OverburdenPressureError(err_msg)
374
-
375
- corrected_spt = sqrt(100 / eop) * spt_n_60
376
- return min(corrected_spt, 2 * spt_n_60)
377
-
378
- @staticmethod
379
- @round_(ndigits=2)
380
- def skempton_opc_1986(spt_n_60: float, eop: float) -> float:
381
- r"""
382
- Return the overburden pressure correction given by ``Skempton (1986).``
383
-
384
- :param float spt_n_60: SPT N-value standardized for field procedures.
385
- :param float eop: Effective overburden pressure (:math:`kN/m^2`).
386
-
387
- .. math::
388
-
389
- C_N = \dfrac{2}{1 + 0.01044 \cdot \sigma_o}
390
- """
391
- corrected_spt = (2 / (1 + 0.01044 * eop)) * spt_n_60
392
- return min(corrected_spt, 2 * spt_n_60)
393
-
394
- @staticmethod
395
- @round_(ndigits=2)
396
- def bazaraa_peck_opc_1969(spt_n_60: float, eop: float) -> float:
397
- r"""
398
- Return the overburden pressure correction given by ``Bazaraa (1967)``
399
- and also by ``Peck and Bazaraa (1969)``.
400
-
401
- :param float spt_n_60: SPT N-value standardized for field procedures.
402
- :param float eop: Effective overburden pressure (:math:`kN/m^2`).
403
-
404
- .. math::
405
-
406
- C_N &= \dfrac{4}{1 + 0.0418 \cdot \sigma_o}, \, \sigma_o \lt 71.8kN/m^2
407
-
408
- C_N &= \dfrac{4}{3.25 + 0.0104 \cdot \sigma_o}, \, \sigma_o \gt 71.8kN/m^2
409
-
410
- C_N &= 1 \, , \, \sigma_o = 71.8kN/m^2
411
- """
412
-
413
- std_pressure = 71.8
414
-
415
- if isclose(eop, std_pressure, rel_tol=ERROR_TOL):
416
- return spt_n_60
417
-
418
- if eop < std_pressure:
419
- corrected_spt = 4 * spt_n_60 / (1 + 0.0418 * eop)
420
-
421
- else:
422
- corrected_spt = 4 * spt_n_60 / (3.25 + 0.0104 * eop)
423
-
424
- return min(corrected_spt, 2 * spt_n_60)
geolysis/utils.py DELETED
@@ -1,106 +0,0 @@
1
- import functools
2
- import math
3
- from math import ceil, exp, isclose, log10
4
- from math import pi as PI
5
- from math import sqrt
6
- from statistics import fmean as mean
7
- from typing import Callable, TypeAlias
8
-
9
- __all__ = [
10
- "deg2rad",
11
- "rad2deg",
12
- "tan",
13
- "cot",
14
- "sin",
15
- "cos",
16
- "arctan",
17
- "round_",
18
- ]
19
-
20
- FloatOrInt: TypeAlias = float | int
21
-
22
-
23
- def deg2rad(__x: FloatOrInt, /) -> float:
24
- """
25
- Convert angle x from degrees to radians.
26
- """
27
- return math.radians(__x)
28
-
29
-
30
- def rad2deg(__x: FloatOrInt, /) -> float:
31
- """
32
- Convert angle x from radians to degrees.
33
- """
34
- return math.degrees(__x)
35
-
36
-
37
- def tan(__x: FloatOrInt, /) -> float:
38
- """
39
- Return the tangent of x (measured in degrees).
40
- """
41
- return math.tan(deg2rad(__x))
42
-
43
-
44
- def cot(__x: FloatOrInt, /) -> float:
45
- """
46
- Return the cotangent of x (measured in degrees).
47
- """
48
- return 1 / tan(__x)
49
-
50
-
51
- def sin(__x: FloatOrInt, /) -> float:
52
- """
53
- Return the sine of x (measured in degrees).
54
- """
55
- return math.sin(deg2rad(__x))
56
-
57
-
58
- def cos(__x: FloatOrInt, /) -> float:
59
- """
60
- Return the cosine of x (measured in degrees).
61
- """
62
- return math.cos(deg2rad(__x))
63
-
64
-
65
- def arctan(__x: FloatOrInt, /) -> float:
66
- """
67
- Return the arc tangent (measured in degrees) of x.
68
- """
69
- return rad2deg(math.atan(__x))
70
-
71
-
72
- def round_(ndigits: int) -> Callable:
73
- """
74
- A decorator that rounds the result of a function to a specified number of
75
- decimal places.
76
-
77
- :param int ndigits: The number of decimal places to round to.
78
-
79
- :return: A decorator that rounds the result of the wrapped function.
80
- :rtype: Callable[..., float]
81
-
82
- :raises TypeError: If precision is not an int.
83
-
84
- .. note::
85
-
86
- This decorator can only be used with functions that return a float or a
87
- datatype that implements ``__round__``.
88
- """
89
-
90
- def dec(
91
- func: Callable[..., float],
92
- /,
93
- *,
94
- ndigits: int,
95
- ) -> Callable[..., float]:
96
- @functools.wraps(func)
97
- def wrapper(*args, **kwargs) -> float:
98
- return round(func(*args, **kwargs), ndigits=ndigits)
99
-
100
- return wrapper
101
-
102
- if isinstance(ndigits, int):
103
- return functools.partial(dec, ndigits=ndigits) # return decorator
104
-
105
- err_msg = "ndigits should be an int."
106
- raise TypeError(err_msg)