geolysis 0.4.3__py3-none-any.whl → 0.4.5__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 +5 -1
- geolysis/bearing_capacity/__init__.py +0 -0
- geolysis/bearing_capacity/abc/__init__.py +0 -0
- geolysis/bearing_capacity/abc/cohl/__init__.py +146 -0
- geolysis/bearing_capacity/abc/cohl/_core.py +55 -0
- geolysis/bearing_capacity/abc/cohl/bowles_abc.py +107 -0
- geolysis/bearing_capacity/abc/cohl/meyerhof_abc.py +107 -0
- geolysis/bearing_capacity/abc/cohl/terzaghi_abc.py +142 -0
- geolysis/bearing_capacity/ubc/__init__.py +160 -0
- geolysis/bearing_capacity/ubc/_core.py +192 -0
- geolysis/bearing_capacity/ubc/hansen_ubc.py +297 -0
- geolysis/bearing_capacity/ubc/terzaghi_ubc.py +259 -0
- geolysis/bearing_capacity/ubc/vesic_ubc.py +303 -0
- geolysis/foundation.py +51 -17
- geolysis/soil_classifier.py +26 -25
- geolysis/spt.py +196 -75
- geolysis/utils/__init__.py +100 -0
- geolysis/utils/validators.py +80 -0
- {geolysis-0.4.3.dist-info → geolysis-0.4.5.dist-info}/METADATA +40 -13
- geolysis-0.4.5.dist-info/RECORD +23 -0
- {geolysis-0.4.3.dist-info → geolysis-0.4.5.dist-info}/WHEEL +1 -1
- geolysis-0.4.3.dist-info/RECORD +0 -9
- {geolysis-0.4.3.dist-info → geolysis-0.4.5.dist-info/licenses}/LICENSE.txt +0 -0
- {geolysis-0.4.3.dist-info → geolysis-0.4.5.dist-info}/top_level.txt +0 -0
geolysis/spt.py
CHANGED
@@ -9,6 +9,7 @@ Enums
|
|
9
9
|
|
10
10
|
HammerType
|
11
11
|
SamplerType
|
12
|
+
OPCType
|
12
13
|
|
13
14
|
Classes
|
14
15
|
=======
|
@@ -24,13 +25,20 @@ Classes
|
|
24
25
|
LiaoWhitmanOPC
|
25
26
|
SkemptonOPC
|
26
27
|
DilatancyCorrection
|
28
|
+
|
29
|
+
Functions
|
30
|
+
=========
|
31
|
+
|
32
|
+
.. autosummary::
|
33
|
+
:toctree: _autosummary
|
34
|
+
|
35
|
+
create_spt_correction
|
27
36
|
"""
|
28
37
|
import enum
|
29
38
|
from abc import abstractmethod
|
30
39
|
from typing import Final, Sequence
|
31
40
|
|
32
|
-
from
|
33
|
-
enum_repr
|
41
|
+
from .utils import enum_repr, isclose, log10, mean, round_, sqrt, validators
|
34
42
|
|
35
43
|
__all__ = ["SPTNDesign",
|
36
44
|
"HammerType",
|
@@ -66,6 +74,7 @@ class SPTNDesign:
|
|
66
74
|
|
67
75
|
@property
|
68
76
|
def corrected_spt_n_values(self) -> Sequence[float]:
|
77
|
+
"""Corrected SPT N-values within the foundation influence zone."""
|
69
78
|
return self._corrected_spt_n_values
|
70
79
|
|
71
80
|
@corrected_spt_n_values.setter
|
@@ -148,17 +157,15 @@ class EnergyCorrection:
|
|
148
157
|
``ENERGY``: 0.6, 0.55, etc
|
149
158
|
"""
|
150
159
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
HammerType.PIN: 0.45}
|
160
|
+
_HAMMER_EFFICIENCY_FACTORS = {HammerType.AUTOMATIC: 0.70,
|
161
|
+
HammerType.DONUT_1: 0.60,
|
162
|
+
HammerType.DONUT_2: 0.50,
|
163
|
+
HammerType.SAFETY: 0.55,
|
164
|
+
HammerType.DROP: 0.45,
|
165
|
+
HammerType.PIN: 0.45}
|
158
166
|
|
159
|
-
|
160
|
-
|
161
|
-
SamplerType.NON_STANDARD: 1.20}
|
167
|
+
_SAMPLER_CORRECTION_FACTORS = {SamplerType.STANDARD: 1.00,
|
168
|
+
SamplerType.NON_STANDARD: 1.20}
|
162
169
|
|
163
170
|
def __init__(self, recorded_spt_n_value: int, *,
|
164
171
|
energy_percentage=0.6,
|
@@ -174,10 +181,10 @@ class EnergyCorrection:
|
|
174
181
|
sampler, defaults to 0.6
|
175
182
|
:type energy_percentage: float, optional
|
176
183
|
|
177
|
-
:param borehole_diameter: Borehole diameter, defaults to 65.0.
|
184
|
+
:param borehole_diameter: Borehole diameter (mm), defaults to 65.0.
|
178
185
|
:type borehole_diameter: float, optional
|
179
186
|
|
180
|
-
:param rod_length:
|
187
|
+
:param rod_length: Length of SPT rod, defaults to 3.0. (m)
|
181
188
|
:type rod_length: float, optional
|
182
189
|
|
183
190
|
:param hammer_type: Hammer type, defaults to :attr:`HammerType.DONUT_1`
|
@@ -195,6 +202,7 @@ class EnergyCorrection:
|
|
195
202
|
|
196
203
|
@property
|
197
204
|
def recorded_spt_n_value(self) -> int:
|
205
|
+
"""Recorded SPT N-value from field."""
|
198
206
|
return self._recorded_spt_value
|
199
207
|
|
200
208
|
@recorded_spt_n_value.setter
|
@@ -205,6 +213,7 @@ class EnergyCorrection:
|
|
205
213
|
|
206
214
|
@property
|
207
215
|
def energy_percentage(self) -> float:
|
216
|
+
"""Energy percentage reaching the tip of the sampler."""
|
208
217
|
return self._energy_percentage
|
209
218
|
|
210
219
|
@energy_percentage.setter
|
@@ -215,6 +224,7 @@ class EnergyCorrection:
|
|
215
224
|
|
216
225
|
@property
|
217
226
|
def borehole_diameter(self) -> float:
|
227
|
+
"""Borehole diameter (mm)."""
|
218
228
|
return self._borehole_diameter
|
219
229
|
|
220
230
|
@borehole_diameter.setter
|
@@ -225,6 +235,7 @@ class EnergyCorrection:
|
|
225
235
|
|
226
236
|
@property
|
227
237
|
def rod_length(self) -> float:
|
238
|
+
"""Length of SPT rod."""
|
228
239
|
return self._rod_length
|
229
240
|
|
230
241
|
@rod_length.setter
|
@@ -235,7 +246,7 @@ class EnergyCorrection:
|
|
235
246
|
@property
|
236
247
|
def hammer_efficiency(self) -> float:
|
237
248
|
"""Hammer efficiency correction factor."""
|
238
|
-
return self.
|
249
|
+
return self._HAMMER_EFFICIENCY_FACTORS[self.hammer_type]
|
239
250
|
|
240
251
|
@property
|
241
252
|
def borehole_diameter_correction(self) -> float:
|
@@ -251,7 +262,7 @@ class EnergyCorrection:
|
|
251
262
|
@property
|
252
263
|
def sampler_correction(self) -> float:
|
253
264
|
"""Sampler correction factor."""
|
254
|
-
return self.
|
265
|
+
return self._SAMPLER_CORRECTION_FACTORS[self.sampler_type]
|
255
266
|
|
256
267
|
@property
|
257
268
|
def rod_length_correction(self) -> float:
|
@@ -275,8 +286,8 @@ class EnergyCorrection:
|
|
275
286
|
return numerator / self.energy_percentage
|
276
287
|
|
277
288
|
@round_(ndigits=1)
|
278
|
-
def
|
279
|
-
"""
|
289
|
+
def standardized_spt_n_value(self) -> float:
|
290
|
+
"""Standardized SPT N-value."""
|
280
291
|
return self.correction() * self.recorded_spt_n_value
|
281
292
|
|
282
293
|
|
@@ -296,6 +307,7 @@ class OPC:
|
|
296
307
|
|
297
308
|
@property
|
298
309
|
def std_spt_n_value(self) -> float:
|
310
|
+
"""SPT N-value standardized for field procedures."""
|
299
311
|
return self._std_spt_n_value
|
300
312
|
|
301
313
|
@std_spt_n_value.setter
|
@@ -305,7 +317,18 @@ class OPC:
|
|
305
317
|
|
306
318
|
@round_(ndigits=1)
|
307
319
|
def corrected_spt_n_value(self) -> float:
|
308
|
-
"""Corrected SPT N-value.
|
320
|
+
r"""Corrected SPT N-value.
|
321
|
+
|
322
|
+
:Equation:
|
323
|
+
|
324
|
+
.. math:: (N_1)_{60} = C_N \cdot N_{60}
|
325
|
+
|
326
|
+
.. note::
|
327
|
+
|
328
|
+
``60`` is used in this case to represent ``60%`` hammer efficiency
|
329
|
+
and can be any percentage of hammer efficiency e.g :math:`N_{55}`
|
330
|
+
for ``55%`` hammer efficiency.
|
331
|
+
"""
|
309
332
|
corrected_spt = self.correction() * self.std_spt_n_value
|
310
333
|
# Corrected SPT should not be more
|
311
334
|
# than 2 times the Standardized SPT
|
@@ -317,20 +340,11 @@ class OPC:
|
|
317
340
|
|
318
341
|
|
319
342
|
class GibbsHoltzOPC(OPC):
|
320
|
-
|
321
|
-
|
322
|
-
:Equation:
|
323
|
-
|
324
|
-
.. math:: C_N = \dfrac{350}{\sigma_o + 70} \, \sigma_o \le 280kN/m^2
|
325
|
-
|
326
|
-
:math:`\frac{N_c}{N_{60}}` should lie between 0.45 and 2.0, if
|
327
|
-
:math:`\frac{N_c}{N_{60}}` is greater than 2.0, :math:`N_c` should be
|
328
|
-
divided by 2.0 to obtain the design value used in finding the bearing
|
329
|
-
capacity of the soil.
|
330
|
-
"""
|
343
|
+
"""Overburden Pressure Correction according to ``Gibbs & Holtz (1957)``."""
|
331
344
|
|
332
345
|
@property
|
333
346
|
def eop(self) -> float:
|
347
|
+
"""Effective overburden pressure (:math:`kpa`)."""
|
334
348
|
return self._eop
|
335
349
|
|
336
350
|
@eop.setter
|
@@ -340,25 +354,24 @@ class GibbsHoltzOPC(OPC):
|
|
340
354
|
self._eop = val
|
341
355
|
|
342
356
|
def correction(self) -> float:
|
343
|
-
"""SPT Correction.
|
357
|
+
r"""SPT Correction.
|
358
|
+
|
359
|
+
:Equation:
|
360
|
+
|
361
|
+
.. math:: C_N = \dfrac{350}{\sigma_o + 70} \, \sigma_o \le 280kN/m^2
|
362
|
+
|
363
|
+
:math:`\frac{N_c}{N_{60}}` should lie between 0.45 and 2.0, if
|
364
|
+
:math:`\frac{N_c}{N_{60}}` is greater than 2.0, :math:`N_c` should be
|
365
|
+
divided by 2.0 to obtain the design value used in finding the bearing
|
366
|
+
capacity of the soil.
|
367
|
+
"""
|
344
368
|
corr = 350.0 / (self.eop + 70.0)
|
345
369
|
return corr / 2.0 if corr > 2.0 else corr
|
346
370
|
|
347
371
|
|
348
372
|
class BazaraaPeckOPC(OPC):
|
349
|
-
|
373
|
+
"""Overburden Pressure Correction according to ``Bazaraa (1967)``, and
|
350
374
|
also by ``Peck and Bazaraa (1969)``.
|
351
|
-
|
352
|
-
:Equation:
|
353
|
-
|
354
|
-
.. math::
|
355
|
-
|
356
|
-
C_N &= \dfrac{4}{1 + 0.0418 \cdot \sigma_o}, \, \sigma_o \lt 71.8kN/m^2
|
357
|
-
|
358
|
-
C_N &= \dfrac{4}{3.25 + 0.0104 \cdot \sigma_o},
|
359
|
-
\, \sigma_o \gt 71.8kN/m^2
|
360
|
-
|
361
|
-
C_N &= 1 \, , \, \sigma_o = 71.8kN/m^2
|
362
375
|
"""
|
363
376
|
|
364
377
|
#: Maximum effective overburden pressure (:math:`kPa`).
|
@@ -366,15 +379,29 @@ class BazaraaPeckOPC(OPC):
|
|
366
379
|
|
367
380
|
@property
|
368
381
|
def eop(self) -> float:
|
382
|
+
"""Effective overburden pressure (:math:`kPa`)."""
|
369
383
|
return self._eop
|
370
384
|
|
371
385
|
@eop.setter
|
372
386
|
@validators.ge(0.0)
|
373
387
|
def eop(self, val: float) -> None:
|
388
|
+
"""Effective overburden pressure (:math:`kPa`)."""
|
374
389
|
self._eop = val
|
375
390
|
|
376
391
|
def correction(self) -> float:
|
377
|
-
"""SPT Correction.
|
392
|
+
r"""SPT Correction.
|
393
|
+
|
394
|
+
:Equation:
|
395
|
+
|
396
|
+
.. math::
|
397
|
+
|
398
|
+
C_N &= \dfrac{4}{1 + 0.0418 \cdot \sigma_o}, \, \sigma_o \lt 71.8kN/m^2
|
399
|
+
|
400
|
+
C_N &= \dfrac{4}{3.25 + 0.0104 \cdot \sigma_o},
|
401
|
+
\, \sigma_o \gt 71.8kN/m^2
|
402
|
+
|
403
|
+
C_N &= 1 \, , \, \sigma_o = 71.8kN/m^2
|
404
|
+
"""
|
378
405
|
if isclose(self.eop, self.STD_PRESSURE, rel_tol=0.01):
|
379
406
|
corr = 1.0
|
380
407
|
elif self.eop < self.STD_PRESSURE:
|
@@ -385,15 +412,11 @@ class BazaraaPeckOPC(OPC):
|
|
385
412
|
|
386
413
|
|
387
414
|
class PeckOPC(OPC):
|
388
|
-
|
389
|
-
|
390
|
-
:Equation:
|
391
|
-
|
392
|
-
.. math:: C_N = 0.77 \log \left(\dfrac{2000}{\sigma_o} \right)
|
393
|
-
"""
|
415
|
+
"""Overburden Pressure Correction according to ``Peck et al. (1974)``."""
|
394
416
|
|
395
417
|
@property
|
396
418
|
def eop(self) -> float:
|
419
|
+
"""Effective overburden pressure (:math:`kPa`)."""
|
397
420
|
return self._eop
|
398
421
|
|
399
422
|
@eop.setter
|
@@ -402,20 +425,22 @@ class PeckOPC(OPC):
|
|
402
425
|
self._eop = val
|
403
426
|
|
404
427
|
def correction(self) -> float:
|
405
|
-
"""SPT Correction.
|
406
|
-
return 0.77 * log10(2000.0 / self.eop)
|
428
|
+
r"""SPT Correction.
|
407
429
|
|
430
|
+
:Equation:
|
408
431
|
|
409
|
-
|
410
|
-
|
432
|
+
.. math:: C_N = 0.77 \log \left(\dfrac{2000}{\sigma_o} \right)
|
433
|
+
"""
|
434
|
+
return 0.77 * log10(2000.0 / self.eop)
|
411
435
|
|
412
|
-
:Equation:
|
413
436
|
|
414
|
-
|
437
|
+
class LiaoWhitmanOPC(OPC):
|
438
|
+
"""Overburden Pressure Correction according to ``Liao & Whitman (1986)``.
|
415
439
|
"""
|
416
440
|
|
417
441
|
@property
|
418
442
|
def eop(self) -> float:
|
443
|
+
"""Effective overburden pressure (:math:`kPa`)."""
|
419
444
|
return self._eop
|
420
445
|
|
421
446
|
@eop.setter
|
@@ -424,20 +449,21 @@ class LiaoWhitmanOPC(OPC):
|
|
424
449
|
self._eop = val
|
425
450
|
|
426
451
|
def correction(self) -> float:
|
427
|
-
"""SPT Correction.
|
428
|
-
return sqrt(100.0 / self.eop)
|
452
|
+
r"""SPT Correction.
|
429
453
|
|
454
|
+
:Equation:
|
430
455
|
|
431
|
-
|
432
|
-
|
456
|
+
.. math:: C_N = \sqrt{\dfrac{100}{\sigma_o}}
|
457
|
+
"""
|
458
|
+
return sqrt(100.0 / self.eop)
|
433
459
|
|
434
|
-
:Equation:
|
435
460
|
|
436
|
-
|
437
|
-
"""
|
461
|
+
class SkemptonOPC(OPC):
|
462
|
+
"""Overburden Pressure Correction according to ``Skempton (1986)``."""
|
438
463
|
|
439
464
|
@property
|
440
465
|
def eop(self) -> float:
|
466
|
+
"""Effective overburden pressure (:math:`kPa`)."""
|
441
467
|
return self._eop
|
442
468
|
|
443
469
|
@eop.setter
|
@@ -446,25 +472,21 @@ class SkemptonOPC(OPC):
|
|
446
472
|
self._eop = val
|
447
473
|
|
448
474
|
def correction(self) -> float:
|
449
|
-
"""SPT Correction.
|
475
|
+
r"""SPT Correction.
|
476
|
+
|
477
|
+
:Equation:
|
478
|
+
|
479
|
+
.. math:: C_N = \dfrac{2}{1 + 0.01044 \cdot \sigma_o}
|
480
|
+
"""
|
450
481
|
return 2.0 / (1.0 + 0.01044 * self.eop)
|
451
482
|
|
452
483
|
|
453
484
|
class DilatancyCorrection:
|
454
|
-
|
485
|
+
"""Dilatancy SPT Correction according to ``Terzaghi & Peck (1948)``.
|
455
486
|
|
456
487
|
For coarse sand, this correction is not required. In applying this
|
457
488
|
correction, overburden pressure correction is applied first and then
|
458
489
|
dilatancy correction is applied.
|
459
|
-
|
460
|
-
:Equation:
|
461
|
-
|
462
|
-
.. math::
|
463
|
-
|
464
|
-
(N_1)_{60} &= 15 + \dfrac{1}{2}((N_1)_{60} - 15) \, , \,
|
465
|
-
(N_1)_{60} \gt 15
|
466
|
-
|
467
|
-
(N_1)_{60} &= (N_1)_{60} \, , \, (N_1)_{60} \le 15
|
468
490
|
"""
|
469
491
|
|
470
492
|
def __init__(self, corr_spt_n_value: float) -> None:
|
@@ -477,6 +499,9 @@ class DilatancyCorrection:
|
|
477
499
|
|
478
500
|
@property
|
479
501
|
def corr_spt_n_value(self) -> float:
|
502
|
+
"""SPT N-value standardized for field procedures and/or corrected for
|
503
|
+
overburden pressure.
|
504
|
+
"""
|
480
505
|
return self._std_spt_n_value
|
481
506
|
|
482
507
|
@corr_spt_n_value.setter
|
@@ -486,7 +511,103 @@ class DilatancyCorrection:
|
|
486
511
|
|
487
512
|
@round_(ndigits=1)
|
488
513
|
def corrected_spt_n_value(self) -> float:
|
489
|
-
"""Corrected SPT N-value.
|
514
|
+
r"""Corrected SPT N-value.
|
515
|
+
|
516
|
+
:Equation:
|
517
|
+
|
518
|
+
.. math::
|
519
|
+
|
520
|
+
(N_1)_{60} &= 15 + \dfrac{1}{2}((N_1)_{60} - 15) \, , \,
|
521
|
+
(N_1)_{60} \gt 15
|
522
|
+
|
523
|
+
(N_1)_{60} &= (N_1)_{60} \, , \, (N_1)_{60} \le 15
|
524
|
+
"""
|
490
525
|
if self.corr_spt_n_value <= 15.0:
|
491
526
|
return self.corr_spt_n_value
|
492
527
|
return 15.0 + 0.5 * (self.corr_spt_n_value - 15.0)
|
528
|
+
|
529
|
+
|
530
|
+
@enum_repr
|
531
|
+
class OPCType(enum.StrEnum):
|
532
|
+
"""Enumeration of overburden pressure correction types."""
|
533
|
+
GIBBS = enum.auto()
|
534
|
+
BAZARAA = enum.auto()
|
535
|
+
PECK = enum.auto()
|
536
|
+
LIAO = enum.auto()
|
537
|
+
SKEMPTON = enum.auto()
|
538
|
+
|
539
|
+
|
540
|
+
def create_spt_correction(recorded_spt_n_value: int,
|
541
|
+
eop: float,
|
542
|
+
energy_percentage=0.6,
|
543
|
+
borehole_diameter=65.0,
|
544
|
+
rod_length=3.0,
|
545
|
+
hammer_type=HammerType.DONUT_1,
|
546
|
+
sampler_type=SamplerType.STANDARD,
|
547
|
+
opc_type: OPCType | str = OPCType.GIBBS,
|
548
|
+
apply_dilatancy_correction: bool = False
|
549
|
+
) -> OPC | DilatancyCorrection:
|
550
|
+
"""A factory function that encapsulates the creation of spt correction.
|
551
|
+
|
552
|
+
:param recorded_spt_n_value: Recorded SPT N-value from field.
|
553
|
+
:type recorded_spt_n_value: int
|
554
|
+
|
555
|
+
:param eop: Effective overburden pressure (:math:`kPa`).
|
556
|
+
:type eop: float
|
557
|
+
|
558
|
+
:param energy_percentage: Energy percentage reaching the tip of the
|
559
|
+
sampler, defaults to 0.6
|
560
|
+
:type energy_percentage: float, optional
|
561
|
+
|
562
|
+
:param borehole_diameter: Borehole diameter, defaults to 65.0 (mm).
|
563
|
+
:type borehole_diameter: float, optional
|
564
|
+
|
565
|
+
:param rod_length: Rod length, defaults to 3.0 (m).
|
566
|
+
:type rod_length: float, optional
|
567
|
+
|
568
|
+
:param hammer_type: Hammer type, defaults to :attr:`HammerType.DONUT_1`
|
569
|
+
:type hammer_type: HammerType, optional
|
570
|
+
|
571
|
+
:param sampler_type: Sampler type, defaults to :attr:`SamplerType.STANDARD`
|
572
|
+
:type sampler_type: SamplerType, optional
|
573
|
+
|
574
|
+
:param opc_type: Overburden Pressure Correction type to apply,
|
575
|
+
defaults to :attr:`OPCType.GIBBS`
|
576
|
+
:type opc_type: OPCType, optional
|
577
|
+
|
578
|
+
:param apply_dilatancy_correction: Indicates whether to apply dilatancy
|
579
|
+
correction, defaults to False.
|
580
|
+
:type apply_dilatancy_correction: bool, optional
|
581
|
+
"""
|
582
|
+
|
583
|
+
try:
|
584
|
+
opc_type = OPCType(str(opc_type).casefold())
|
585
|
+
except ValueError as e:
|
586
|
+
msg = (f"{opc_type=} is not supported, Supported "
|
587
|
+
f"types are: {list(OPCType)}")
|
588
|
+
raise ValueError(msg) from e
|
589
|
+
|
590
|
+
energy_correction = EnergyCorrection(
|
591
|
+
recorded_spt_n_value=recorded_spt_n_value,
|
592
|
+
energy_percentage=energy_percentage,
|
593
|
+
borehole_diameter=borehole_diameter,
|
594
|
+
rod_length=rod_length,
|
595
|
+
hammer_type=hammer_type,
|
596
|
+
sampler_type=sampler_type)
|
597
|
+
|
598
|
+
std_spt_n_value = energy_correction.standardized_spt_n_value()
|
599
|
+
|
600
|
+
opc_types = {OPCType.GIBBS: GibbsHoltzOPC,
|
601
|
+
OPCType.BAZARAA: BazaraaPeckOPC,
|
602
|
+
OPCType.PECK: PeckOPC,
|
603
|
+
OPCType.LIAO: LiaoWhitmanOPC,
|
604
|
+
OPCType.SKEMPTON: SkemptonOPC}
|
605
|
+
|
606
|
+
opc_class = opc_types[opc_type]
|
607
|
+
opc_corr = opc_class(std_spt_n_value=std_spt_n_value, eop=eop)
|
608
|
+
|
609
|
+
if apply_dilatancy_correction:
|
610
|
+
corr_spt_n_value = opc_corr.corrected_spt_n_value()
|
611
|
+
return DilatancyCorrection(corr_spt_n_value=corr_spt_n_value)
|
612
|
+
|
613
|
+
return opc_corr
|
@@ -0,0 +1,100 @@
|
|
1
|
+
import functools
|
2
|
+
import math
|
3
|
+
from math import exp, inf, isclose, log10, pi, sqrt
|
4
|
+
from statistics import fmean as mean
|
5
|
+
from typing import Callable, SupportsRound
|
6
|
+
|
7
|
+
from . import validators
|
8
|
+
|
9
|
+
__all__ = ["enum_repr",
|
10
|
+
"inf",
|
11
|
+
"pi",
|
12
|
+
"deg2rad",
|
13
|
+
"rad2deg",
|
14
|
+
"tan",
|
15
|
+
"cot",
|
16
|
+
"sin",
|
17
|
+
"cos",
|
18
|
+
"arctan",
|
19
|
+
"round_",
|
20
|
+
"mean",
|
21
|
+
"exp",
|
22
|
+
"isclose",
|
23
|
+
"log10",
|
24
|
+
"sqrt",
|
25
|
+
"validators"]
|
26
|
+
|
27
|
+
|
28
|
+
def deg2rad(x: float, /) -> float:
|
29
|
+
"""Convert angle x from degrees to radians."""
|
30
|
+
return math.radians(x)
|
31
|
+
|
32
|
+
|
33
|
+
def rad2deg(x: float, /) -> float:
|
34
|
+
"""Convert angle x from radians to degrees."""
|
35
|
+
return math.degrees(x)
|
36
|
+
|
37
|
+
|
38
|
+
def tan(x: float, /) -> float:
|
39
|
+
"""Return the tangent of x (measured in degrees)."""
|
40
|
+
return math.tan(deg2rad(x))
|
41
|
+
|
42
|
+
|
43
|
+
def cot(x: float, /) -> float:
|
44
|
+
"""Return the cotangent of x (measured in degrees)."""
|
45
|
+
return 1 / tan(x)
|
46
|
+
|
47
|
+
|
48
|
+
def sin(x: float, /) -> float:
|
49
|
+
"""Return the sine of x (measured in degrees)."""
|
50
|
+
return math.sin(deg2rad(x))
|
51
|
+
|
52
|
+
|
53
|
+
def cos(x: float, /) -> float:
|
54
|
+
"""Return the cosine of x (measured in degrees)."""
|
55
|
+
return math.cos(deg2rad(x))
|
56
|
+
|
57
|
+
|
58
|
+
def arctan(x: float, /) -> float:
|
59
|
+
"""Return the arc tangent (measured in degrees) of x."""
|
60
|
+
return rad2deg(math.atan(x))
|
61
|
+
|
62
|
+
|
63
|
+
def enum_repr(cls):
|
64
|
+
cls.__repr__ = lambda self: f"{self.value}"
|
65
|
+
return cls
|
66
|
+
|
67
|
+
|
68
|
+
def round_(ndigits: int | Callable[..., SupportsRound]) -> Callable:
|
69
|
+
"""A decorator that rounds the result of a callable to a specified number
|
70
|
+
of decimal places.
|
71
|
+
|
72
|
+
The returned value of the callable should support the ``__round__`` dunder
|
73
|
+
method and should be a numeric value. ``ndigits`` can either be an int
|
74
|
+
which will indicate the number of decimal places to round to or a
|
75
|
+
callable. If ``ndigits`` is callable the default decimal places is 2.
|
76
|
+
|
77
|
+
TypeError is raised when ``ndigits`` is neither an int nor a callable.
|
78
|
+
"""
|
79
|
+
|
80
|
+
default_dp = 2
|
81
|
+
|
82
|
+
def dec(fn) -> Callable[..., float]:
|
83
|
+
@functools.wraps(fn)
|
84
|
+
def wrapper(*args, **kwargs) -> float:
|
85
|
+
dp = ndigits if not callable(ndigits) else default_dp
|
86
|
+
res = fn(*args, **kwargs)
|
87
|
+
return round(res, ndigits=dp)
|
88
|
+
|
89
|
+
return wrapper
|
90
|
+
|
91
|
+
# See if we're being called as @round_ or @round_().
|
92
|
+
# We're called with parens.
|
93
|
+
if isinstance(ndigits, int):
|
94
|
+
return dec
|
95
|
+
|
96
|
+
# We're called as @round_ without parens.
|
97
|
+
if callable(ndigits):
|
98
|
+
return dec(ndigits)
|
99
|
+
|
100
|
+
raise TypeError("ndigits must be an int or a callable")
|
@@ -0,0 +1,80 @@
|
|
1
|
+
"""validators"""
|
2
|
+
import operator
|
3
|
+
from typing import Callable, TypeAlias
|
4
|
+
|
5
|
+
Number: TypeAlias = int | float
|
6
|
+
|
7
|
+
|
8
|
+
def _num_validator(bound: float, /, *,
|
9
|
+
compare_symbol: str,
|
10
|
+
compare_fn: Callable,
|
11
|
+
err_msg: str,
|
12
|
+
exc_type: Callable):
|
13
|
+
def dec(fn):
|
14
|
+
def wrapper(obj, val):
|
15
|
+
if not compare_fn(val, bound):
|
16
|
+
msg = f"{fn.__name__} must be {compare_symbol} {bound}"
|
17
|
+
raise exc_type(err_msg if err_msg else msg)
|
18
|
+
fn(obj, val)
|
19
|
+
|
20
|
+
return wrapper
|
21
|
+
|
22
|
+
return dec
|
23
|
+
|
24
|
+
|
25
|
+
def _len_validator(bound: float, /, *,
|
26
|
+
compare_symbol: str,
|
27
|
+
compare_fn: Callable,
|
28
|
+
err_msg: str,
|
29
|
+
exc_type: Callable):
|
30
|
+
def dec(fn):
|
31
|
+
def wrapper(obj, val):
|
32
|
+
_len = len(val)
|
33
|
+
if not compare_fn(_len, bound):
|
34
|
+
msg = f"Length of '{fn.__name__}' must be {compare_symbol} {bound}"
|
35
|
+
raise exc_type(err_msg if err_msg else msg)
|
36
|
+
return fn(obj, val)
|
37
|
+
|
38
|
+
return wrapper
|
39
|
+
|
40
|
+
return dec
|
41
|
+
|
42
|
+
|
43
|
+
def min_len(m_len: int, /, *, exc_type=ValueError, err_msg=None):
|
44
|
+
return _len_validator(m_len, compare_symbol=">=",
|
45
|
+
compare_fn=operator.ge,
|
46
|
+
err_msg=err_msg,
|
47
|
+
exc_type=exc_type)
|
48
|
+
|
49
|
+
|
50
|
+
# def lt(val: Number, /, *, exc_type=ValueError, err_msg=None):
|
51
|
+
# return _NumberValidator(val, "<", operator.lt, exc_type, err_msg)
|
52
|
+
|
53
|
+
|
54
|
+
def le(val: Number, /, *, exc_type=ValueError, err_msg=None):
|
55
|
+
return _num_validator(val, compare_symbol="<=",
|
56
|
+
compare_fn=operator.le,
|
57
|
+
err_msg=err_msg,
|
58
|
+
exc_type=exc_type)
|
59
|
+
|
60
|
+
|
61
|
+
# def eq(val: Number, /, *, exc_type=ValueError, err_msg=None):
|
62
|
+
# return _NumberValidator(val, "==", operator.eq, exc_type, err_msg)
|
63
|
+
|
64
|
+
|
65
|
+
# def ne(val: Number, /, *, exc_type=ValueError, err_msg=None):
|
66
|
+
# return _NumberValidator(val, "!=", operator.ne, exc_type, err_msg)
|
67
|
+
|
68
|
+
|
69
|
+
def ge(val: Number, /, *, exc_type=ValueError, err_msg=None):
|
70
|
+
return _num_validator(val, compare_symbol=">=",
|
71
|
+
compare_fn=operator.ge,
|
72
|
+
err_msg=err_msg,
|
73
|
+
exc_type=exc_type)
|
74
|
+
|
75
|
+
|
76
|
+
def gt(val: Number, /, *, exc_type=ValueError, err_msg=None):
|
77
|
+
return _num_validator(val, compare_symbol=">",
|
78
|
+
compare_fn=operator.gt,
|
79
|
+
err_msg=err_msg,
|
80
|
+
exc_type=exc_type)
|