driven-pile 0.1.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.
- driven_pile/__init__.py +28 -0
- driven_pile/analysis.py +43 -0
- driven_pile/bearing.py +148 -0
- driven_pile/capacity.py +73 -0
- driven_pile/constants.py +24 -0
- driven_pile/formulas.py +61 -0
- driven_pile/inputs.py +373 -0
- driven_pile/liquefaction.py +208 -0
- driven_pile/march.py +289 -0
- driven_pile/montecarlo.py +108 -0
- driven_pile/options.py +123 -0
- driven_pile/plots.py +83 -0
- driven_pile/preprocess.py +219 -0
- driven_pile/results.py +262 -0
- driven_pile/shaft.py +166 -0
- driven_pile/spt.py +64 -0
- driven_pile/top_segment.py +42 -0
- driven_pile-0.1.0.dist-info/METADATA +79 -0
- driven_pile-0.1.0.dist-info/RECORD +21 -0
- driven_pile-0.1.0.dist-info/WHEEL +4 -0
- driven_pile-0.1.0.dist-info/licenses/LICENSE +674 -0
driven_pile/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""driven-pile: long-term capacity of driven piles from the pile-driving log.
|
|
2
|
+
|
|
3
|
+
Each logged foot of driving
|
|
4
|
+
characterizes the soil at the toe once (friction angle, equivalent N1,60,
|
|
5
|
+
cyclic resistance), the pore pressure generated by later hammer blows sets
|
|
6
|
+
that foot's shaft resistance for the rest of the drive, and the end-of-drive
|
|
7
|
+
characterization with pore pressure dissipated gives the long-term capacity.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .analysis import analyze
|
|
11
|
+
from .capacity import long_term_capacity
|
|
12
|
+
from .inputs import DriveLog, Hammer, Pile, SoilProfile, bpm_to_stroke, stroke_to_bpm
|
|
13
|
+
from .march import run_drive
|
|
14
|
+
from .montecarlo import monte_carlo
|
|
15
|
+
from .options import ModelOptions, MonteCarloOptions
|
|
16
|
+
from .preprocess import Target, prepare_target
|
|
17
|
+
from .results import Analysis, DriveResult, MonteCarloResult, TopPhiBand
|
|
18
|
+
from .top_segment import sweep_top_phi
|
|
19
|
+
|
|
20
|
+
__version__ = "0.1.0"
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"Analysis", "DriveLog", "DriveResult", "Hammer", "ModelOptions",
|
|
24
|
+
"MonteCarloOptions", "MonteCarloResult", "Pile", "SoilProfile", "Target",
|
|
25
|
+
"TopPhiBand", "analyze",
|
|
26
|
+
"bpm_to_stroke", "long_term_capacity", "monte_carlo", "prepare_target",
|
|
27
|
+
"run_drive", "stroke_to_bpm", "sweep_top_phi",
|
|
28
|
+
]
|
driven_pile/analysis.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""One-call analysis of a driving log."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from .march import run_drive
|
|
6
|
+
from .montecarlo import monte_carlo
|
|
7
|
+
from .options import ModelOptions, MonteCarloOptions
|
|
8
|
+
from .preprocess import prepare_target
|
|
9
|
+
from .results import Analysis
|
|
10
|
+
from .top_segment import sweep_top_phi
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def analyze(log, soil, options=None, mc_options=None, run_mc=False):
|
|
14
|
+
"""Characterize the soil from a driving log and estimate long-term capacity.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
log : DriveLog
|
|
19
|
+
The driving record, with its pile and hammer.
|
|
20
|
+
soil : SoilProfile
|
|
21
|
+
Mudline, water table, unit weight and fines content.
|
|
22
|
+
options : ModelOptions, optional
|
|
23
|
+
Model parameters; defaults to the published values.
|
|
24
|
+
mc_options : MonteCarloOptions, optional
|
|
25
|
+
Monte Carlo settings, used when ``run_mc`` is True.
|
|
26
|
+
run_mc : bool, default False
|
|
27
|
+
Also run the Monte Carlo simulation.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
Analysis
|
|
32
|
+
The deterministic run uses the lowest admissible top-segment
|
|
33
|
+
friction angle.
|
|
34
|
+
"""
|
|
35
|
+
options = options or ModelOptions()
|
|
36
|
+
target = prepare_target(log, soil, options)
|
|
37
|
+
band = sweep_top_phi(target, options)
|
|
38
|
+
drive = run_drive(target, options, top_phi=band.lo)
|
|
39
|
+
mc = None
|
|
40
|
+
if run_mc:
|
|
41
|
+
mc = monte_carlo(log, soil, options, mc_options or MonteCarloOptions(),
|
|
42
|
+
target=target, top_band=band)
|
|
43
|
+
return Analysis(drive=drive, top_band=band, mc=mc)
|
driven_pile/bearing.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Toe bearing in sand: Vesic cavity expansion with a stress-dependent rigidity
|
|
2
|
+
index, and its inversion for the friction angle."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
from scipy.optimize import brentq
|
|
8
|
+
|
|
9
|
+
from .constants import ABOVE_CEILING, BELOW_FLOOR, NONFINITE, OK, P_ATM
|
|
10
|
+
|
|
11
|
+
_GRID_POINTS = 512
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def nq_vesic(phi, irr, k0=None):
|
|
15
|
+
"""Vesic bearing capacity factor on vertical effective stress.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
phi : array_like
|
|
20
|
+
Friction angle, deg.
|
|
21
|
+
irr : array_like
|
|
22
|
+
Reduced rigidity index.
|
|
23
|
+
k0 : array_like, optional
|
|
24
|
+
At-rest earth pressure coefficient; ``1 - sin(phi)`` by default.
|
|
25
|
+
|
|
26
|
+
Returns
|
|
27
|
+
-------
|
|
28
|
+
ndarray
|
|
29
|
+
``N_q* = N_sigma (1 + 2 K0) / 3`` with
|
|
30
|
+
``N_sigma = 3 / (3 - sin phi) exp((pi/2 - phi) tan phi)
|
|
31
|
+
tan^2(45 + phi/2) Irr^(4 sin phi / (3 (1 + sin phi)))``.
|
|
32
|
+
|
|
33
|
+
References
|
|
34
|
+
----------
|
|
35
|
+
Vesic (1977).
|
|
36
|
+
"""
|
|
37
|
+
p = np.radians(np.asarray(phi, dtype=float))
|
|
38
|
+
sin_p = np.sin(p)
|
|
39
|
+
if k0 is None:
|
|
40
|
+
k0 = 1.0 - sin_p
|
|
41
|
+
n_sigma = (
|
|
42
|
+
(3.0 / (3.0 - sin_p))
|
|
43
|
+
* np.exp((np.pi / 2.0 - p) * np.tan(p))
|
|
44
|
+
* np.tan(np.pi / 4.0 + p / 2.0) ** 2
|
|
45
|
+
* np.asarray(irr, dtype=float) ** (4.0 * sin_p / (3.0 * (1.0 + sin_p)))
|
|
46
|
+
)
|
|
47
|
+
return n_sigma * (1.0 + 2.0 * k0) / 3.0
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def rigidity_index(phi, sigma_v, options):
|
|
51
|
+
"""Rigidity index from a stress-dependent shear modulus.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
phi : array_like
|
|
56
|
+
Friction angle, deg.
|
|
57
|
+
sigma_v : array_like
|
|
58
|
+
Vertical effective stress, ksf.
|
|
59
|
+
options : ModelOptions
|
|
60
|
+
Supplies ``g_ratio``, ``k2_lo``, ``k2_hi``, ``phi_lo``, ``phi_hi``
|
|
61
|
+
and ``irr_bounds``.
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
ndarray
|
|
66
|
+
``I_r = g_ratio G_max / (sigma'_m tan phi)`` clamped to
|
|
67
|
+
``irr_bounds``, with ``sigma'_m = (1 + 2 K0) / 3 sigma'_v`` and
|
|
68
|
+
``G_max = 21.7 K2 Pa sqrt(sigma'_m / Pa)``.
|
|
69
|
+
|
|
70
|
+
References
|
|
71
|
+
----------
|
|
72
|
+
Seed and Idriss (1970).
|
|
73
|
+
"""
|
|
74
|
+
phi = np.asarray(phi, dtype=float)
|
|
75
|
+
p = np.radians(phi)
|
|
76
|
+
k0 = 1.0 - np.sin(p)
|
|
77
|
+
sig_m = np.maximum((1.0 + 2.0 * k0) / 3.0 * np.asarray(sigma_v, dtype=float), 1e-3)
|
|
78
|
+
k2 = np.interp(phi, [options.phi_lo, options.phi_hi], [options.k2_lo, options.k2_hi])
|
|
79
|
+
g_max = 21.7 * k2 * P_ATM * np.sqrt(sig_m / P_ATM)
|
|
80
|
+
ir = options.g_ratio * g_max / (sig_m * np.tan(p))
|
|
81
|
+
return np.clip(ir, *options.irr_bounds)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def toe_bearing(sigma_v, phi, options):
|
|
85
|
+
"""Unit toe resistance ``q_p = N_q*(phi, I_r) sigma'_v``, ksf."""
|
|
86
|
+
irr = rigidity_index(phi, sigma_v, options)
|
|
87
|
+
return np.asarray(sigma_v, dtype=float) * nq_vesic(phi, irr)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def phi_from_toe_bearing(q_needed, sigma_v, options):
|
|
91
|
+
"""Friction angle whose toe bearing on ``sigma_v`` equals ``q_needed``.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
q_needed : float
|
|
96
|
+
Required unit toe resistance, ksf.
|
|
97
|
+
sigma_v : float
|
|
98
|
+
Vertical effective stress at the toe, ksf.
|
|
99
|
+
options : ModelOptions
|
|
100
|
+
Supplies the friction angle bounds and rigidity parameters.
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
phi : float
|
|
105
|
+
Friction angle, deg, held at a bound when the requirement lies
|
|
106
|
+
outside the attainable range; NaN when ``q_needed`` is not finite.
|
|
107
|
+
reason : str
|
|
108
|
+
One of the reason codes in `driven_pile.constants`.
|
|
109
|
+
"""
|
|
110
|
+
lo, hi = options.phi_lo, options.phi_hi
|
|
111
|
+
if not np.isfinite(q_needed):
|
|
112
|
+
return np.nan, NONFINITE
|
|
113
|
+
if sigma_v <= 0:
|
|
114
|
+
return lo, BELOW_FLOOR
|
|
115
|
+
if q_needed <= toe_bearing(sigma_v, lo, options):
|
|
116
|
+
return lo, BELOW_FLOOR
|
|
117
|
+
if q_needed >= toe_bearing(sigma_v, hi, options):
|
|
118
|
+
return hi, ABOVE_CEILING
|
|
119
|
+
phi = brentq(lambda p: float(toe_bearing(sigma_v, p, options)) - q_needed, lo, hi)
|
|
120
|
+
return phi, OK
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def phi_from_toe_bearing_grid(q_needed, sigma_v, options):
|
|
124
|
+
"""Friction angle from toe bearing by interpolation on a fixed grid.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
q_needed : float or array_like
|
|
129
|
+
Required unit toe resistance, ksf.
|
|
130
|
+
sigma_v : float or array_like
|
|
131
|
+
Vertical effective stress at the toe, ksf.
|
|
132
|
+
options : ModelOptions
|
|
133
|
+
Supplies the friction angle bounds and rigidity parameters.
|
|
134
|
+
|
|
135
|
+
Returns
|
|
136
|
+
-------
|
|
137
|
+
float or ndarray
|
|
138
|
+
Friction angle, deg, clamped to the bounds. Faster than
|
|
139
|
+
`phi_from_toe_bearing` when evaluated many times.
|
|
140
|
+
"""
|
|
141
|
+
grid = np.linspace(options.phi_lo, options.phi_hi, _GRID_POINTS)
|
|
142
|
+
sig = np.atleast_1d(np.asarray(sigma_v, dtype=float))
|
|
143
|
+
q = np.broadcast_to(np.atleast_1d(np.asarray(q_needed, dtype=float)), sig.shape)
|
|
144
|
+
out = np.empty_like(sig)
|
|
145
|
+
for k, (s_k, q_k) in enumerate(zip(sig, q)):
|
|
146
|
+
qp = toe_bearing(max(s_k, 1e-9), grid, options)
|
|
147
|
+
out[k] = np.interp(q_k, qp, grid)
|
|
148
|
+
return out if np.ndim(sigma_v) else float(out[0])
|
driven_pile/capacity.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Long-term capacity from the end-of-drive characterization."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from .bearing import toe_bearing
|
|
8
|
+
from .constants import FOOT_INCREMENT
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def shaft_long_term(fs_ltc, pile):
|
|
12
|
+
"""Long-term shaft resistance, kips.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
fs_ltc : array_like
|
|
17
|
+
Unit shaft resistance per foot after pore-pressure dissipation, ksf.
|
|
18
|
+
pile : Pile
|
|
19
|
+
Supplies the perimeter.
|
|
20
|
+
"""
|
|
21
|
+
fs = np.asarray(fs_ltc, dtype=float)
|
|
22
|
+
return float(np.nansum(fs) * pile.perimeter * FOOT_INCREMENT)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def toe_end_of_drive(phi, sigma_v0, ru_toe, residual, pile, options):
|
|
26
|
+
"""Toe resistance at the end of the drive, kips.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
phi : float
|
|
31
|
+
Friction angle of the final foot, deg.
|
|
32
|
+
sigma_v0 : float
|
|
33
|
+
Static vertical effective stress at the toe, ksf.
|
|
34
|
+
ru_toe : float
|
|
35
|
+
Pore-pressure ratio applied to the toe stress.
|
|
36
|
+
residual : float
|
|
37
|
+
Modeled minus target capacity at the final reconciled foot, kips;
|
|
38
|
+
subtracted from the toe so the end-of-drive total matches the log.
|
|
39
|
+
pile : Pile
|
|
40
|
+
Supplies the toe area.
|
|
41
|
+
options : ModelOptions
|
|
42
|
+
Rigidity parameters.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
float
|
|
47
|
+
Vesic bearing on the reduced stress ``(1 - ru_toe) sigma'v0``, less
|
|
48
|
+
the residual, floored at zero. No toe setup is modeled.
|
|
49
|
+
"""
|
|
50
|
+
if not np.isfinite(phi):
|
|
51
|
+
return 0.0
|
|
52
|
+
qp = float(toe_bearing(sigma_v0 * (1.0 - ru_toe), phi, options)) * pile.area
|
|
53
|
+
return max(qp - residual, 0.0)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def long_term_capacity(result):
|
|
57
|
+
"""Long-term shaft and toe resistance of a `DriveResult`.
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
result : DriveResult
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
shaft, toe : float
|
|
66
|
+
Kips. The toe is its end-of-drive value.
|
|
67
|
+
"""
|
|
68
|
+
shaft = shaft_long_term(result.fs_ltc, result.pile)
|
|
69
|
+
m = np.isfinite(result.target) & np.isfinite(result.predicted)
|
|
70
|
+
residual = float(result.predicted[m][-1] - result.target[m][-1]) if m.any() else 0.0
|
|
71
|
+
toe = toe_end_of_drive(result.phi[-1], result.sigma_v0[-1], result.ru_toe[-1],
|
|
72
|
+
residual, result.pile, result.options)
|
|
73
|
+
return shaft, toe
|
driven_pile/constants.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Physical constants and the per-foot reason codes shared across modules."""
|
|
2
|
+
|
|
3
|
+
GAMMA_WATER = 0.0624
|
|
4
|
+
"""Unit weight of water, ksf/ft."""
|
|
5
|
+
|
|
6
|
+
P_ATM = 2.116
|
|
7
|
+
"""Atmospheric pressure, ksf."""
|
|
8
|
+
|
|
9
|
+
G_FT_S2 = 32.2
|
|
10
|
+
"""Gravitational acceleration, ft/s^2."""
|
|
11
|
+
|
|
12
|
+
FOOT_INCREMENT = 1.0
|
|
13
|
+
"""Length of one analysis increment, ft."""
|
|
14
|
+
|
|
15
|
+
OK = "ok"
|
|
16
|
+
ABOVE_CEILING = "above_ceiling"
|
|
17
|
+
BELOW_FLOOR = "below_floor"
|
|
18
|
+
NONFINITE = "nonfinite"
|
|
19
|
+
TOP_SEGMENT = "top_segment"
|
|
20
|
+
|
|
21
|
+
LIQ_BEFORE = "before"
|
|
22
|
+
LIQ_DURING = "during"
|
|
23
|
+
LIQ_AFTER = "after"
|
|
24
|
+
LIQ_NEVER = ""
|
driven_pile/formulas.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Dynamic capacity formula applied to the driving log."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def elastic_set(stroke, ram_weight, pile):
|
|
9
|
+
"""Elastic compression term of the Danish formula.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
stroke : array_like
|
|
14
|
+
Hammer stroke, ft.
|
|
15
|
+
ram_weight : float
|
|
16
|
+
Ram weight, kips.
|
|
17
|
+
pile : Pile
|
|
18
|
+
Pile geometry and modulus.
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
ndarray
|
|
23
|
+
``s0 = sqrt(W h L / (2 A E))``, ft.
|
|
24
|
+
"""
|
|
25
|
+
stroke = np.asarray(stroke, dtype=float)
|
|
26
|
+
return np.sqrt(ram_weight * stroke * pile.length / (2.0 * pile.area * pile.modulus))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def danish_capacity(bpf, stroke, ram_weight, pile, c1=0.45, c2=0.0):
|
|
30
|
+
"""Capacity at the time of driving from the recalibrated Danish formula.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
bpf : array_like
|
|
35
|
+
Blows per foot.
|
|
36
|
+
stroke : array_like
|
|
37
|
+
Hammer stroke, ft.
|
|
38
|
+
ram_weight : float
|
|
39
|
+
Ram weight, kips.
|
|
40
|
+
pile : Pile
|
|
41
|
+
Pile geometry and modulus.
|
|
42
|
+
c1, c2 : float
|
|
43
|
+
Multiplicative and additive (kips) recalibration coefficients.
|
|
44
|
+
|
|
45
|
+
Returns
|
|
46
|
+
-------
|
|
47
|
+
ndarray
|
|
48
|
+
``c1 * W h / (s + s0) + c2``, kips, with the set per blow
|
|
49
|
+
``s = 1 / bpf`` ft.
|
|
50
|
+
|
|
51
|
+
References
|
|
52
|
+
----------
|
|
53
|
+
Sorensen and Hansen (1957); Reddy and Stuedlein (2013), Puget Sound
|
|
54
|
+
recalibration with unadjusted hammer energy.
|
|
55
|
+
"""
|
|
56
|
+
bpf = np.asarray(bpf, dtype=float)
|
|
57
|
+
stroke = np.asarray(stroke, dtype=float)
|
|
58
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
59
|
+
s = 1.0 / bpf
|
|
60
|
+
q = ram_weight * stroke / (s + elastic_set(stroke, ram_weight, pile))
|
|
61
|
+
return c1 * q + c2
|