Skip to content

Commit

Permalink
added PWP and Soil Profile
Browse files Browse the repository at this point in the history
  • Loading branch information
the-sean-c committed Nov 3, 2023
1 parent a36e94d commit 07b6de3
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# geotech

This is a suite of tools for geotechnical engineering.
This is a suite of tools for geotechnical engineering. This is a work in progress.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "geotech"
version = "0.1.0a1"
version = "0.1.0a2"
description = "A suite of tools for geotechnical engineering."
authors = [
{name = "Sean Daly", email = "[email protected]"},
Expand Down
99 changes: 78 additions & 21 deletions src/geotech/soil.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def sample(self):
"""Must return a sample from the distribution"""
pass

@abstractmethod
def __repr__(self) -> str:
pass


class Uniform(ParameterDistribution):
def __init__(self, lower, upper):
Expand All @@ -29,6 +33,9 @@ def __init__(self, lower, upper):
def sample(self):
return np.random.uniform(self.lower, self.upper)

def __repr__(self) -> str:
return f"{self.lower} to {self.upper}"


class Normal(ParameterDistribution):
def __init__(self, mean, std):
Expand All @@ -38,6 +45,9 @@ def __init__(self, mean, std):
def sample(self):
return np.random.normal(self.mean, self.std)

def __repr__(self) -> str:
return f"{self.mean} +- {self.std}"


class LogNormal(ParameterDistribution):
def __init__(self, mean, std):
Expand All @@ -47,6 +57,9 @@ def __init__(self, mean, std):
def sample(self):
return np.random.lognormal(self.mean, self.std)

def __repr__(self) -> str:
return f"{self.mean} */ {self.std}"


class Constant(ParameterDistribution):
def __init__(self, value):
Expand All @@ -55,6 +68,9 @@ def __init__(self, value):
def sample(self):
return self.value

def __repr__(self) -> str:
return f"{self.value}"


class PoreWaterPressure(ABC):
"""Abstract class for pore water pressure.
Expand All @@ -75,33 +91,69 @@ def sample(self, elevation):
"""Must return a sample from the PWP distribution at a given elevation"""
pass

@abstractmethod
def __repr__(self) -> str:
pass


class WaterTable(PoreWaterPressure):
def __init__(
self,
groundwater_elevation: ParameterDistribution,
gradient: ParameterDistribution = None,
water_table_elevation: ParameterDistribution,
gradient: ParameterDistribution = Constant(0.0),
):
"""Initialize pore water pressure
Args:
groundwater_elevation: Elevation of the groundwater table
water_table_elevation: Elevation of the groundwater table
gradient: Pore water pressure gradient in m/m. Positive indicates
artesian conditions. Defaults to None.
artesian conditions. Defaults to 0.0.
"""
self.water_table_elevation = water_table_elevation # m
self.gradient = gradient # m/m

def sample(self, elevation):
water_table_elevation = self.water_table_elevation.sample()
hydrostatic = (water_table_elevation - elevation) * self.water_unit_weight
artesian = (
(water_table_elevation - elevation)
* self.water_unit_weight
* self.gradient.sample()
)
return hydrostatic + artesian

def __repr__(self):
return f"Water table at {self.water_table_elevation} m"


class MeasuredPoreWaterPressure(PoreWaterPressure):
def __init__(
self,
pore_water_pressure_measurements: list[float, ParameterDistribution],
):
"""Initialize pore water pressure
Args:
pore_water_pressure_measurements: List of pore water pressure measurements
as tuples of elevation (m) and pore water pressure (kPa).
"""
self.groundwater_elevation = groundwater_elevation
self.gradient = gradient
self.pore_water_pressure_measurements = sorted(
pore_water_pressure_measurements, reverse=True
)

def sample(self, elevation):
return self.groundwater_elevation.sample() + self.gradient.sample()

def __repr__(self):
return f"Measured PWP"


class SoilLayer:
def __init__(
self,
name: str,
depth_top: ParameterDistribution,
depth_bottom: ParameterDistribution,
elevation_top: ParameterDistribution,
elevation_bottom: ParameterDistribution,
wet_density: ParameterDistribution,
dry_density: ParameterDistribution,
cohesion: ParameterDistribution,
Expand All @@ -111,18 +163,18 @@ def __init__(
initial_void_ratio: ParameterDistribution,
):
self.name = name
self.depth_top = depth_top
self.depth_bottom = depth_bottom
self.wet_density = wet_density
self.dry_density = dry_density
self.cohesion = cohesion
self.angle_of_internal_friction = angle_of_internal_friction
self.compression_index = compression_index
self.recompression_index = recompression_index
self.initial_void_ratio = initial_void_ratio
self.elevation_top = elevation_top # m
self.elevation_bottom = elevation_bottom # m
self.wet_density = wet_density # kN/m3
self.dry_density = dry_density # kN/m3
self.cohesion = cohesion # kPa
self.angle_of_internal_friction = angle_of_internal_friction # degrees
self.compression_index = compression_index # m2/kN
self.recompression_index = recompression_index # m2/kN
self.initial_void_ratio = initial_void_ratio # unitless

def is_wet(self, groundwater_depth):
return self.depth_top >= groundwater_depth
return self.elevation_top >= groundwater_depth

def get_density(self, groundwater_depth):
if self.is_wet(groundwater_depth):
Expand All @@ -131,9 +183,14 @@ def get_density(self, groundwater_depth):
return self.dry_density

def __repr__(self):
return f"{self.name} ({self.depth_top}m to {self.depth_bottom}m)"
return f"{self.name} ({self.elevation_top}m to {self.elevation_bottom}m)"


class SoilProfile:
def __init__(self):
pass
def __init__(
self,
layers: list[float, SoilLayer],
pore_water_pressure: PoreWaterPressure = Constant(0.0),
):
self.layers = []
self.porewater_pressure = None

0 comments on commit 07b6de3

Please sign in to comment.