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.
@@ -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