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/__init__.py +2 -10
- geolysis/core/__init__.py +9 -0
- geolysis/core/abc_4_cohl_soils.py +495 -0
- geolysis/core/constants.py +47 -0
- geolysis/core/estimators.py +549 -0
- geolysis/core/foundation.py +543 -0
- geolysis/core/soil_classifier.py +859 -0
- geolysis/core/spt.py +633 -0
- geolysis/core/utils.py +113 -0
- {geolysis-0.2.0.dist-info → geolysis-0.3.0.dist-info}/LICENSE.txt +1 -1
- geolysis-0.3.0.dist-info/METADATA +223 -0
- geolysis-0.3.0.dist-info/RECORD +14 -0
- {geolysis-0.2.0.dist-info → geolysis-0.3.0.dist-info}/WHEEL +1 -1
- geolysis/bearing_capacity/__init__.py +0 -1
- geolysis/bearing_capacity/abc.py +0 -335
- geolysis/constants.py +0 -19
- geolysis/estimators.py +0 -255
- geolysis/foundation.py +0 -176
- geolysis/soil_classifier.py +0 -658
- geolysis/spt.py +0 -424
- geolysis/utils.py +0 -106
- geolysis-0.2.0.dist-info/METADATA +0 -193
- geolysis-0.2.0.dist-info/RECORD +0 -14
- {geolysis-0.2.0.dist-info → geolysis-0.3.0.dist-info}/top_level.txt +0 -0
geolysis/soil_classifier.py
DELETED
@@ -1,658 +0,0 @@
|
|
1
|
-
from types import MappingProxyType
|
2
|
-
from typing import NamedTuple
|
3
|
-
|
4
|
-
from .constants import ERROR_TOL
|
5
|
-
from .utils import ceil, isclose, round_
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"AASHTO_SOIL_DESC",
|
9
|
-
"USCS_SOIL_DESC",
|
10
|
-
"AtterbergLimits",
|
11
|
-
"PSD",
|
12
|
-
"AASHTO",
|
13
|
-
"USCS",
|
14
|
-
]
|
15
|
-
|
16
|
-
|
17
|
-
def _chk_psd(fines: float, sand: float, gravel: float):
|
18
|
-
total_agg = fines + sand + gravel
|
19
|
-
if not isclose(total_agg, 100.0, rel_tol=ERROR_TOL):
|
20
|
-
errmsg = f"fines + sand + gravels = 100% not {total_agg}"
|
21
|
-
raise PSDError(errmsg)
|
22
|
-
|
23
|
-
|
24
|
-
# Soil Symbols
|
25
|
-
GRAVEL = "G"
|
26
|
-
SAND = "S"
|
27
|
-
SILT = "M"
|
28
|
-
CLAY = "C"
|
29
|
-
ORGANIC = "O"
|
30
|
-
|
31
|
-
# Gradation Symbols
|
32
|
-
WELL_GRADED = "W"
|
33
|
-
POORLY_GRADED = "P"
|
34
|
-
|
35
|
-
# Liquid Limit Symbols
|
36
|
-
LOW_PLASTICITY = "L"
|
37
|
-
HIGH_PLASTICITY = "H"
|
38
|
-
|
39
|
-
|
40
|
-
#: Descriptions for various AASHTO soil classes.
|
41
|
-
AASHTO_SOIL_DESC = {
|
42
|
-
"A-1-a": "Stone fragments, gravel, and sand",
|
43
|
-
"A-1-b": "Stone fragments, gravel, and sand",
|
44
|
-
"A-3": "Fine sand",
|
45
|
-
"A-2-4": "Silty or clayey gravel and sand",
|
46
|
-
"A-2-5": "Silty or clayey gravel and sand",
|
47
|
-
"A-2-6": "Silty or clayey gravel and sand",
|
48
|
-
"A-2-7": "Silty or clayey gravel and sand",
|
49
|
-
"A-4": "Silty soils",
|
50
|
-
"A-5": "Silty soils",
|
51
|
-
"A-6": "Clayey soils",
|
52
|
-
"A-7-5": "Clayey soils",
|
53
|
-
"A-7-6": "Clayey soils",
|
54
|
-
}
|
55
|
-
|
56
|
-
#: Descriptions for various USCS soil classes.
|
57
|
-
USCS_SOIL_DESC = {
|
58
|
-
"GW": "Well graded gravels",
|
59
|
-
"GP": "Poorly graded gravels",
|
60
|
-
"GM": "Silty gravels",
|
61
|
-
"GC": "Clayey gravels",
|
62
|
-
"GM-GC": "Gravelly clayey silt",
|
63
|
-
"GW-GM": "Well graded gravel with silt",
|
64
|
-
"GP-GM": "Poorly graded gravel with silt",
|
65
|
-
"GW-GC": "Well graded gravel with clay",
|
66
|
-
"GP-GC": "Poorly graded gravel with clay",
|
67
|
-
"SW": "Well graded sands",
|
68
|
-
"SP": "Poorly graded sands",
|
69
|
-
"SM": "Silty sands",
|
70
|
-
"SC": "Clayey sands",
|
71
|
-
"SM-SC": "Sandy clayey silt",
|
72
|
-
"SW-SM": "Well graded sand with silt",
|
73
|
-
"SP-SM": "Poorly graded sand with silt",
|
74
|
-
"SW-SC": "Well graded sand with clay",
|
75
|
-
"SP-SC": "Poorly graded sand with clay",
|
76
|
-
"ML": "Inorganic silts with low plasticity",
|
77
|
-
"CL": "Inorganic clays with low plasticity",
|
78
|
-
"ML-CL": "Clayey silt with low plasticity",
|
79
|
-
"OL": "Organic clays with low plasticity",
|
80
|
-
"MH": "Inorganic silts with high plasticity",
|
81
|
-
"CH": "Inorganic clays with high plasticity",
|
82
|
-
"OH": "Organic silts with high plasticity",
|
83
|
-
"Pt": "Highly organic soils",
|
84
|
-
}
|
85
|
-
|
86
|
-
|
87
|
-
class PSDError(ValueError):
|
88
|
-
"""
|
89
|
-
Exception raised when soil aggregates does not approximately sum up to
|
90
|
-
100%.
|
91
|
-
"""
|
92
|
-
|
93
|
-
|
94
|
-
class AtterbergLimits:
|
95
|
-
"""
|
96
|
-
Water contents at which soil changes from one state to the other.
|
97
|
-
|
98
|
-
In 1911, a Swedish agriculture engineer ``Atterberg`` mentioned that a fined-grained
|
99
|
-
soil can exist in four states, namely, liquid, plastic, semi-solid or solid state.
|
100
|
-
|
101
|
-
The main use of Atterberg Limits is in the classification of soils.
|
102
|
-
|
103
|
-
:param float liquid_limit: Water content beyond which soils flows under their own weight.
|
104
|
-
It can also be defined as the minimum moisture content at which a soil flows upon
|
105
|
-
application of a very small shear force.
|
106
|
-
:param float plastic_limit: Water content at which plastic deformation can be initiated.
|
107
|
-
It is also the minimum water content at which soil can be rolled into a thread 3mm
|
108
|
-
thick (molded without breaking)
|
109
|
-
"""
|
110
|
-
|
111
|
-
def __init__(self, liquid_limit: float, plastic_limit: float):
|
112
|
-
self.liquid_limit = liquid_limit
|
113
|
-
self.plastic_limit = plastic_limit
|
114
|
-
|
115
|
-
@property
|
116
|
-
def plasticity_index(self) -> float:
|
117
|
-
"""
|
118
|
-
Return the plasticity index of the soil.
|
119
|
-
|
120
|
-
Plasticity index is the range of water content over which the soil remains in the
|
121
|
-
plastic state. It is also the numerical difference between the liquid limit and
|
122
|
-
plastic limit of the soil.
|
123
|
-
|
124
|
-
.. math::
|
125
|
-
|
126
|
-
PI = LL - PL
|
127
|
-
"""
|
128
|
-
return self.liquid_limit - self.plastic_limit
|
129
|
-
|
130
|
-
@property
|
131
|
-
@round_(ndigits=2)
|
132
|
-
def A_line(self) -> float:
|
133
|
-
"""
|
134
|
-
Return the ``A-line`` which is used to determine if a soil is clayey or
|
135
|
-
silty.
|
136
|
-
"""
|
137
|
-
return 0.73 * (self.liquid_limit - 20)
|
138
|
-
|
139
|
-
@property
|
140
|
-
def type_of_fines(self) -> str:
|
141
|
-
"""
|
142
|
-
Return the type of fine soil, either ``CLAY`` or ``SILT``.
|
143
|
-
"""
|
144
|
-
return CLAY if self.above_A_LINE() else SILT
|
145
|
-
|
146
|
-
def above_A_LINE(self) -> bool:
|
147
|
-
"""
|
148
|
-
Checks if the soil sample is above A-Line.
|
149
|
-
"""
|
150
|
-
return self.plasticity_index > self.A_line
|
151
|
-
|
152
|
-
def limit_plot_in_hatched_zone(self) -> bool:
|
153
|
-
"""
|
154
|
-
Checks if soil sample plot in the hatched zone on the atterberg chart.
|
155
|
-
"""
|
156
|
-
return 4 <= self.plasticity_index <= 7 and 10 < self.liquid_limit < 30
|
157
|
-
|
158
|
-
@round_(ndigits=2)
|
159
|
-
def liquidity_index(self, nmc: float) -> float:
|
160
|
-
r"""
|
161
|
-
Return the liquidity index of the soil.
|
162
|
-
|
163
|
-
Liquidity index of a soil indicates the nearness of its water content
|
164
|
-
to its liquid limit. When the soil is at the plastic limit its liquidity
|
165
|
-
index is zero. Negative values of the liquidity index indicate that the
|
166
|
-
soil is in a hard (desiccated) state. It is also known as Water-Plasticity
|
167
|
-
ratio.
|
168
|
-
|
169
|
-
:param float nmc: Moisture contents of the soil in natural condition.
|
170
|
-
(Natural Moisture Content)
|
171
|
-
|
172
|
-
.. math::
|
173
|
-
|
174
|
-
I_l = \dfrac{w - PL}{PI} \cdot 100
|
175
|
-
"""
|
176
|
-
return ((nmc - self.plastic_limit) / self.plasticity_index) * 100
|
177
|
-
|
178
|
-
@round_(ndigits=2)
|
179
|
-
def consistency_index(self, nmc: float) -> float:
|
180
|
-
r"""
|
181
|
-
Return the consistency index of the soil.
|
182
|
-
|
183
|
-
Consistency index indicates the consistency (firmness) of soil. It shows the
|
184
|
-
nearness of the water content of the soil to its plastic limit. When the soil
|
185
|
-
is at the liquid limit, the consistency index is zero. The soil at consistency
|
186
|
-
index of zero will be extremely soft and has negligible shear strength. A soil
|
187
|
-
at a water content equal to the plastic limit has consistency index of 100%
|
188
|
-
indicating that the soil is relatively firm. A consistency index of greater than
|
189
|
-
100% shows the soil is relatively strong (semi-solid state). A negative value
|
190
|
-
indicate the soil is in the liquid state. It is also known as Relative Consistency.
|
191
|
-
|
192
|
-
:param float nmc: Moisture contents of the soil in natural condition.
|
193
|
-
(Natural Moisture Content)
|
194
|
-
|
195
|
-
.. math::
|
196
|
-
|
197
|
-
I_c = \dfrac{LL - w}{PI} \cdot 100
|
198
|
-
"""
|
199
|
-
return ((self.liquid_limit - nmc) / self.plasticity_index) * 100.0
|
200
|
-
|
201
|
-
|
202
|
-
class _SizeDistribution(NamedTuple):
|
203
|
-
"""
|
204
|
-
Features obtained from the Particle Size Distribution graph.
|
205
|
-
"""
|
206
|
-
|
207
|
-
d_10: float
|
208
|
-
d_30: float
|
209
|
-
d_60: float
|
210
|
-
|
211
|
-
@property
|
212
|
-
@round_(ndigits=2)
|
213
|
-
def coeff_of_curvature(self) -> float:
|
214
|
-
"""
|
215
|
-
Coefficient of curvature of soil sample.
|
216
|
-
"""
|
217
|
-
return (self.d_30**2) / (self.d_60 * self.d_10)
|
218
|
-
|
219
|
-
@property
|
220
|
-
@round_(ndigits=2)
|
221
|
-
def coeff_of_uniformity(self) -> float:
|
222
|
-
"""
|
223
|
-
Coefficient of uniformity of soil sample.
|
224
|
-
"""
|
225
|
-
return self.d_60 / self.d_10
|
226
|
-
|
227
|
-
def grade(self, coarse_soil: str) -> str:
|
228
|
-
"""
|
229
|
-
Grade of soil sample. Soil grade can either be ``WELL_GRADED`` or
|
230
|
-
``POORLY_GRADED``.
|
231
|
-
|
232
|
-
:param str coarse_soil: Coarse fraction of the soil sample. Valid arguments
|
233
|
-
are ``GRAVEL`` or ``SAND``.
|
234
|
-
"""
|
235
|
-
if coarse_soil == GRAVEL and (
|
236
|
-
1 < self.coeff_of_curvature < 3 and self.coeff_of_uniformity >= 4
|
237
|
-
):
|
238
|
-
grade = WELL_GRADED
|
239
|
-
|
240
|
-
elif coarse_soil == SAND and (
|
241
|
-
1 < self.coeff_of_curvature < 3 and self.coeff_of_uniformity >= 6
|
242
|
-
):
|
243
|
-
grade = WELL_GRADED
|
244
|
-
|
245
|
-
else:
|
246
|
-
grade = POORLY_GRADED
|
247
|
-
|
248
|
-
return grade
|
249
|
-
|
250
|
-
|
251
|
-
class PSD:
|
252
|
-
"""
|
253
|
-
Quantitative proportions by mass of various sizes of particles present in a
|
254
|
-
soil.
|
255
|
-
|
256
|
-
Particle Size Distribution is a method of separation of soils into
|
257
|
-
different fractions using a stack of sieves to measure the size of the
|
258
|
-
particles in a sample and graphing the results to illustrate the
|
259
|
-
distribution of the particle sizes.
|
260
|
-
|
261
|
-
:param float fines: Percentage of fines in soil sample i.e. the percentage
|
262
|
-
of soil sample passing through No. 200 sieve (0.075mm)
|
263
|
-
:param float sand: Percentage of sand in soil sample (%)
|
264
|
-
:param float gravel: Percentage of gravel in soil sample (%)
|
265
|
-
:param float d_10: Diameter at which 10% of the soil by weight is finer.
|
266
|
-
:param float d_30: Diameter at which 30% of the soil by weight is finer.
|
267
|
-
:param float d_60: Diameter at which 60% of the soil by weight is finer.
|
268
|
-
|
269
|
-
:raises PSDError: Raised when soil aggregates does not approximately sum up
|
270
|
-
to 100%.
|
271
|
-
"""
|
272
|
-
|
273
|
-
def __init__(
|
274
|
-
self,
|
275
|
-
fines: float,
|
276
|
-
sand: float,
|
277
|
-
gravel: float,
|
278
|
-
d_10: float = 0,
|
279
|
-
d_30: float = 0,
|
280
|
-
d_60: float = 0,
|
281
|
-
):
|
282
|
-
self.fines = fines
|
283
|
-
self.sand = sand
|
284
|
-
self.gravel = gravel
|
285
|
-
self.size_dist = _SizeDistribution(d_10, d_30, d_60)
|
286
|
-
|
287
|
-
_chk_psd(self.fines, self.sand, self.gravel)
|
288
|
-
|
289
|
-
@property
|
290
|
-
def type_of_coarse(self) -> str:
|
291
|
-
"""
|
292
|
-
Return the type of coarse material i.e. either ``GRAVEL`` or ``SAND``.
|
293
|
-
"""
|
294
|
-
return GRAVEL if self.gravel > self.sand else SAND
|
295
|
-
|
296
|
-
@property
|
297
|
-
def coeff_of_curvature(self) -> float:
|
298
|
-
r"""
|
299
|
-
Return the coefficient of curvature of the soil.
|
300
|
-
|
301
|
-
.. math::
|
302
|
-
|
303
|
-
C_c = \dfrac{D^2_{30}}{D_{60} \times D_{10}}
|
304
|
-
"""
|
305
|
-
return self.size_dist.coeff_of_curvature
|
306
|
-
|
307
|
-
@property
|
308
|
-
def coeff_of_uniformity(self) -> float:
|
309
|
-
r"""
|
310
|
-
Return the coefficient of uniformity of the soil.
|
311
|
-
|
312
|
-
.. math::
|
313
|
-
|
314
|
-
C_u = \dfrac{D_{60}}{D_{10}}
|
315
|
-
"""
|
316
|
-
return self.size_dist.coeff_of_uniformity
|
317
|
-
|
318
|
-
def _has_particle_sizes(self) -> bool:
|
319
|
-
"""
|
320
|
-
Checks if soil sample has particle sizes.
|
321
|
-
"""
|
322
|
-
return all(self.size_dist)
|
323
|
-
|
324
|
-
def grade(self) -> str:
|
325
|
-
r"""
|
326
|
-
Return the grade of the soil sample either ``WELL_GRADED`` or
|
327
|
-
``POORLY_GRADED``.
|
328
|
-
|
329
|
-
Conditions for a well-graded soil:
|
330
|
-
|
331
|
-
- :math:`1 \lt C_c \lt 3` and :math:`C_u \ge 4` (for gravels)
|
332
|
-
- :math:`1 \lt C_c \lt 3` and :math:`C_u \ge 6` (for sands)
|
333
|
-
"""
|
334
|
-
return self.size_dist.grade(coarse_soil=self.type_of_coarse)
|
335
|
-
|
336
|
-
|
337
|
-
class AASHTO:
|
338
|
-
r"""
|
339
|
-
American Association of State Highway and Transportation Officials (AASHTO)
|
340
|
-
classification system.
|
341
|
-
|
342
|
-
The AASHTO classification system is useful for classifying soils for highways. It
|
343
|
-
categorizes soils for highways based on particle size analysis and plasticity
|
344
|
-
characteristics. It classifies both coarse-grained and fine-grained soils into eight
|
345
|
-
main groups (A1-A7) with subgroups, along with a separate category (A8) for organic
|
346
|
-
soils.
|
347
|
-
|
348
|
-
- ``A1 ~ A3`` (Granular Materials) :math:`\le` 35% pass No. 200 sieve
|
349
|
-
- ``A4 ~ A7`` (Silt-clay Materials) :math:`\ge` 36% pass No. 200 sieve
|
350
|
-
|
351
|
-
The Group Index ``(GI)`` is used to further evaluate soils with a group (subgroups).
|
352
|
-
When calculating ``GI`` from the equation below, if any term in the parenthesis
|
353
|
-
becomes negative, it is drop and not given a negative value. The maximum values of
|
354
|
-
:math:`(F_{200} - 35)` and :math:`(F_{200} - 15)` are taken as 40 and :math:`(LL - 40)`
|
355
|
-
and :math:`(PI - 10)` as 20.
|
356
|
-
|
357
|
-
If the computed value for ``GI`` is negative, it is reported as zero.
|
358
|
-
|
359
|
-
In general, the rating for the pavement subgrade is inversely proportional to the ``GI``
|
360
|
-
(lower the ``GI``, better the material). For e.g., a ``GI`` of zero indicates a good
|
361
|
-
subgrade, whereas a group index of 20 or greater shows a very poor subgrade.
|
362
|
-
|
363
|
-
.. note::
|
364
|
-
|
365
|
-
The ``GI`` must be mentioned even when it is zero, to indicate that the soil has been
|
366
|
-
classified as per AASHTO system.
|
367
|
-
|
368
|
-
:param float liquid_limit: Water content beyond which soils flows under their own weight.
|
369
|
-
:param float plasticity_index: Range of water content over which soil remains in plastic
|
370
|
-
condition.
|
371
|
-
:param float fines: Percentage of fines in soil sample i.e. the percentage of soil
|
372
|
-
sample passing through No. 200 sieve (0.075mm).
|
373
|
-
:kwparam bool add_group_idx: Used to indicate whether the group index should be added to
|
374
|
-
the classification or not. Defaults to True.
|
375
|
-
"""
|
376
|
-
|
377
|
-
def __init__(
|
378
|
-
self,
|
379
|
-
liquid_limit: float,
|
380
|
-
plasticity_index: float,
|
381
|
-
fines: float,
|
382
|
-
add_group_idx=True,
|
383
|
-
):
|
384
|
-
self.liquid_limit = liquid_limit
|
385
|
-
self.plasticity_index = plasticity_index
|
386
|
-
self.fines = fines
|
387
|
-
self.add_group_idx = add_group_idx
|
388
|
-
|
389
|
-
def group_index(self) -> float:
|
390
|
-
"""
|
391
|
-
Return the Group Index (GI) of the soil sample.
|
392
|
-
|
393
|
-
.. math::
|
394
|
-
|
395
|
-
GI = (F_{200} - 35)[0.2 + 0.005(LL - 40)] + 0.01(F_{200} - 15)(PI - 10)
|
396
|
-
|
397
|
-
- :math:`F_{200}`: Percentage by mass passing American Sieve No. 200.
|
398
|
-
- LL: Liquid Limit (%), expressed as a whole number.
|
399
|
-
- PI: Plasticity Index (%), expressed as a whole number.
|
400
|
-
"""
|
401
|
-
x_1 = 1 if (x_0 := self.fines - 35) < 0 else min(x_0, 40)
|
402
|
-
x_2 = 1 if (x_0 := self.liquid_limit - 40) < 0 else min(x_0, 20)
|
403
|
-
x_3 = 1 if (x_0 := self.fines - 15) < 0 else min(x_0, 40)
|
404
|
-
x_4 = 1 if (x_0 := self.plasticity_index - 10) < 0 else min(x_0, 20)
|
405
|
-
|
406
|
-
grp_idx = round(x_1 * (0.2 + 0.005 * x_2) + 0.01 * x_3 * x_4, 0)
|
407
|
-
|
408
|
-
return 0 if grp_idx <= 0 else ceil(grp_idx)
|
409
|
-
|
410
|
-
@property
|
411
|
-
def soil_class(self) -> str:
|
412
|
-
"""
|
413
|
-
Return the AASHTO classification of the soil.
|
414
|
-
"""
|
415
|
-
return self._classify()
|
416
|
-
|
417
|
-
@property
|
418
|
-
def soil_desc(self) -> str | None:
|
419
|
-
"""
|
420
|
-
Return the AASHTO description of the soil.
|
421
|
-
"""
|
422
|
-
tmp_state = self.add_group_idx
|
423
|
-
try:
|
424
|
-
self.add_group_idx = False
|
425
|
-
return AASHTO_SOIL_DESC[self._classify()]
|
426
|
-
finally:
|
427
|
-
self.add_group_idx = tmp_state
|
428
|
-
|
429
|
-
def _classify(self) -> str:
|
430
|
-
# Silts A4-A7
|
431
|
-
if self.fines > 35:
|
432
|
-
return self._fine_soil_classifier()
|
433
|
-
|
434
|
-
# Coarse A1-A3
|
435
|
-
return self._coarse_soil_classifier()
|
436
|
-
|
437
|
-
def _coarse_soil_classifier(self) -> str:
|
438
|
-
# A-3, Fine sand
|
439
|
-
if self.fines <= 10 and isclose(
|
440
|
-
self.plasticity_index, 0, rel_tol=ERROR_TOL
|
441
|
-
):
|
442
|
-
clf = "A-3"
|
443
|
-
|
444
|
-
# A-1-a -> A-1-b, Stone fragments, gravel, and sand
|
445
|
-
elif self.fines <= 15 and self.plasticity_index <= 6:
|
446
|
-
clf = "A-1-a"
|
447
|
-
|
448
|
-
elif self.fines <= 25 and self.plasticity_index <= 6:
|
449
|
-
clf = "A-1-b"
|
450
|
-
|
451
|
-
# A-2-4 -> A-2-7, Silty or clayey gravel and sand
|
452
|
-
elif self.liquid_limit <= 40:
|
453
|
-
if self.plasticity_index <= 10:
|
454
|
-
clf = "A-2-4"
|
455
|
-
else:
|
456
|
-
clf = "A-2-6"
|
457
|
-
|
458
|
-
else:
|
459
|
-
if self.plasticity_index <= 10:
|
460
|
-
clf = "A-2-5"
|
461
|
-
else:
|
462
|
-
clf = "A-2-7"
|
463
|
-
|
464
|
-
return f"{clf}({self.group_index()})" if self.add_group_idx else clf
|
465
|
-
|
466
|
-
def _fine_soil_classifier(self) -> str:
|
467
|
-
# A-4 -> A-5, Silty Soils
|
468
|
-
# A-6 -> A-7, Clayey Soils
|
469
|
-
if self.liquid_limit <= 40:
|
470
|
-
clf = "A-4" if self.plasticity_index <= 10 else "A-6"
|
471
|
-
|
472
|
-
else:
|
473
|
-
if self.plasticity_index <= 10:
|
474
|
-
clf = "A-5"
|
475
|
-
else:
|
476
|
-
_x = self.liquid_limit - 30
|
477
|
-
clf = "A-7-5" if self.plasticity_index <= _x else "A-7-6"
|
478
|
-
|
479
|
-
return f"{clf}({self.group_index()})" if self.add_group_idx else clf
|
480
|
-
|
481
|
-
|
482
|
-
class USCS:
|
483
|
-
"""
|
484
|
-
Unified Soil Classification System (USCS).
|
485
|
-
|
486
|
-
The Unified Soil Classification System, initially developed by Casagrande in 1948 and
|
487
|
-
later modified in 1952, is widely utilized in engineering projects involving soils. It
|
488
|
-
is the most popular system for soil classification and is similar to Casagrande's
|
489
|
-
Classification System. The system relies on particle size analysis and atterberg limits
|
490
|
-
for classification.
|
491
|
-
|
492
|
-
In this system, soils are first classified into two categories:
|
493
|
-
|
494
|
-
- Coarse grained soils: If more than 50% of the soils is retained on No. 200 (0.075 mm)
|
495
|
-
sieve, it is designated as coarse-grained soil.
|
496
|
-
|
497
|
-
- Fine grained soils: If more than 50% of the soil passes through No. 200 sieve, it is
|
498
|
-
designated as fine grained soil.
|
499
|
-
|
500
|
-
Highly Organic soils are identified by visual inspection. These soils are termed as Peat.
|
501
|
-
(:math:`P_t`)
|
502
|
-
|
503
|
-
Soil symbols:
|
504
|
-
|
505
|
-
- G: Gravel
|
506
|
-
- S: Sand
|
507
|
-
- M: Silt
|
508
|
-
- C: Clay
|
509
|
-
- O: Organic Clay
|
510
|
-
- Pt: Peat
|
511
|
-
|
512
|
-
Liquid limit symbols:
|
513
|
-
|
514
|
-
- H: High Plasticity :math:`(LL > 50)`
|
515
|
-
- L: Low Plasticity :math:`(LL < 50)`
|
516
|
-
|
517
|
-
Gradation symbols:
|
518
|
-
|
519
|
-
- W: Well-graded
|
520
|
-
- P: Poorly-graded
|
521
|
-
|
522
|
-
:param float liquid_limit: Water content beyond which soils flows under their own weight.
|
523
|
-
It can also be defined as the minimum moisture content at which a soil flows upon
|
524
|
-
application of a very small shear force.
|
525
|
-
:param float plastic_limit: Water content at which plastic deformation can be initiated.
|
526
|
-
It is also the minimum water content at which soil can be rolled into a thread 3mm
|
527
|
-
thick (molded without breaking)
|
528
|
-
:param float fines: Percentage of fines in soil sample i.e. the percentage of soil sample
|
529
|
-
passing through No. 200 sieve (0.075mm)
|
530
|
-
:param float sand: Percentage of sand in soil sample (%)
|
531
|
-
:param float gravel: Percentage of gravel in soil sample (%)
|
532
|
-
:param float d_10: Diameter at which 10% of the soil by weight is finer.
|
533
|
-
:param float d_30: Diameter at which 30% of the soil by weight is finer.
|
534
|
-
:param float d_60: Diameter at which 60% of the soil by weight is finer.
|
535
|
-
:kwparam bool organic: Indicates whether soil is organic or not.
|
536
|
-
"""
|
537
|
-
|
538
|
-
def __init__(
|
539
|
-
self,
|
540
|
-
liquid_limit: float,
|
541
|
-
plastic_limit: float,
|
542
|
-
fines: float,
|
543
|
-
sand: float,
|
544
|
-
gravel: float,
|
545
|
-
*,
|
546
|
-
d_10=0,
|
547
|
-
d_30=0,
|
548
|
-
d_60=0,
|
549
|
-
organic=False,
|
550
|
-
):
|
551
|
-
self.atterberg_limits = AtterbergLimits(liquid_limit, plastic_limit)
|
552
|
-
self.psd = PSD(fines, sand, gravel, d_10, d_30, d_60)
|
553
|
-
self.organic = organic
|
554
|
-
|
555
|
-
@property
|
556
|
-
def soil_class(self) -> str:
|
557
|
-
"""
|
558
|
-
Return the USCS Classification of the soil.
|
559
|
-
"""
|
560
|
-
return self._classify()
|
561
|
-
|
562
|
-
@property
|
563
|
-
def soil_desc(self) -> str | None:
|
564
|
-
"""
|
565
|
-
Return the USCS description of the soil.
|
566
|
-
"""
|
567
|
-
return USCS_SOIL_DESC[self._classify()]
|
568
|
-
|
569
|
-
def _classify(self) -> str:
|
570
|
-
# Fine grained, Run Atterberg
|
571
|
-
if self.psd.fines > 50:
|
572
|
-
return self._fine_soil_classifier()
|
573
|
-
|
574
|
-
# Coarse grained, Run Sieve Analysis
|
575
|
-
# Gravel or Sand
|
576
|
-
return self._coarse_soil_classifier()
|
577
|
-
|
578
|
-
def _dual_soil_classifier(self) -> str:
|
579
|
-
fine_soil = self.atterberg_limits.type_of_fines
|
580
|
-
coarse_soil = self.psd.type_of_coarse
|
581
|
-
|
582
|
-
return f"{coarse_soil}{self.psd.grade()}-{coarse_soil}{fine_soil}"
|
583
|
-
|
584
|
-
def _coarse_soil_classifier(self) -> str:
|
585
|
-
coarse_soil = self.psd.type_of_coarse
|
586
|
-
|
587
|
-
# More than 12% pass No. 200 sieve
|
588
|
-
if self.psd.fines > 12:
|
589
|
-
# Above A-line
|
590
|
-
if self.atterberg_limits.above_A_LINE():
|
591
|
-
soil_class = f"{coarse_soil}{CLAY}"
|
592
|
-
|
593
|
-
# Limit plot in hatched zone on plasticity chart
|
594
|
-
elif self.atterberg_limits.limit_plot_in_hatched_zone():
|
595
|
-
soil_class = f"{coarse_soil}{SILT}-{coarse_soil}{CLAY}"
|
596
|
-
|
597
|
-
# Below A-line
|
598
|
-
else:
|
599
|
-
soil_class = f"{coarse_soil}{SILT}"
|
600
|
-
|
601
|
-
elif 5 <= self.psd.fines <= 12:
|
602
|
-
# Requires dual symbol based on graduation and plasticity chart
|
603
|
-
if self.psd._has_particle_sizes():
|
604
|
-
soil_class = self._dual_soil_classifier()
|
605
|
-
|
606
|
-
else:
|
607
|
-
fine_soil = self.atterberg_limits.type_of_fines
|
608
|
-
soil_class = (
|
609
|
-
f"{coarse_soil}{WELL_GRADED}-{coarse_soil}{fine_soil},"
|
610
|
-
f"{coarse_soil}{POORLY_GRADED}-{coarse_soil}{fine_soil}"
|
611
|
-
)
|
612
|
-
|
613
|
-
# Less than 5% pass No. 200 sieve
|
614
|
-
# Obtain Cc and Cu from grain size graph
|
615
|
-
else:
|
616
|
-
if self.psd._has_particle_sizes():
|
617
|
-
soil_class = f"{coarse_soil}{self.psd.grade()}"
|
618
|
-
|
619
|
-
else:
|
620
|
-
soil_class = f"{coarse_soil}{WELL_GRADED} or {coarse_soil}{POORLY_GRADED}"
|
621
|
-
|
622
|
-
return soil_class
|
623
|
-
|
624
|
-
def _fine_soil_classifier(self) -> str:
|
625
|
-
if self.atterberg_limits.liquid_limit < 50:
|
626
|
-
# Low LL
|
627
|
-
# Above A-line and PI > 7
|
628
|
-
if (self.atterberg_limits.above_A_LINE()) and (
|
629
|
-
self.atterberg_limits.plasticity_index > 7
|
630
|
-
):
|
631
|
-
soil_class = f"{CLAY}{LOW_PLASTICITY}"
|
632
|
-
|
633
|
-
# Limit plot in hatched area on plasticity chart
|
634
|
-
elif self.atterberg_limits.limit_plot_in_hatched_zone():
|
635
|
-
soil_class = f"{SILT}{LOW_PLASTICITY}-{CLAY}{LOW_PLASTICITY}"
|
636
|
-
|
637
|
-
# Below A-line or PI < 4
|
638
|
-
else:
|
639
|
-
if self.organic:
|
640
|
-
soil_class = f"{ORGANIC}{LOW_PLASTICITY}"
|
641
|
-
|
642
|
-
else:
|
643
|
-
soil_class = f"{SILT}{LOW_PLASTICITY}"
|
644
|
-
|
645
|
-
# High LL
|
646
|
-
else:
|
647
|
-
# Above A-Line
|
648
|
-
if self.atterberg_limits.above_A_LINE():
|
649
|
-
soil_class = f"{CLAY}{HIGH_PLASTICITY}"
|
650
|
-
|
651
|
-
# Below A-Line
|
652
|
-
else:
|
653
|
-
if self.organic:
|
654
|
-
soil_class = f"{ORGANIC}{HIGH_PLASTICITY}"
|
655
|
-
else:
|
656
|
-
soil_class = f"{SILT}{HIGH_PLASTICITY}"
|
657
|
-
|
658
|
-
return soil_class
|