Chpater 4 Geotechnical Engineering: Slope Stability#
1. Introduction#

Fig. 25 **Figure 4.11 **: Analysis of Slope Stability.#
🧱 Soil Slope Instability and Stability Analysis#
Slope Stability is the ability of a soil or rock slope to resist movement or failure under gravitational and environmental forces. Slope Instability occurs when driving forces (e.g., gravity, water pressure) exceed resisting forces, leading to mass movement such as landslides or slumps. Common causes include:
🔧 Contributing Factors#
Factor |
Description |
---|---|
Gravity and Slope Angle |
Steeper slopes increase shear stress and reduce normal stress |
Water Infiltration |
Raises pore water pressure, reduces effective stress, and adds weight |
Weak or Layered Soils |
Soft clays, loose sands, or stratified soils have low shear strength |
Erosion and Weathering |
Removes support and weakens surface layers |
Seismic Activity |
Earthquakes induce dynamic loads and reduce soil strength |
Human Activities |
Excavation, loading, or deforestation can destabilize slopes |
🧠 Why Is Slope Stability Analysis Important?#
Analyzing slope stability is essential to:
Prevent Landslides: Protect lives, property, and infrastructure
Design Safe Embankments: Roads, dams, and levees rely on stable slopes
Assess Risk: Identify potential failure zones and mitigation needs
Guide Construction: Optimize cut/fill operations and slope angles
Ensure Long-Term Performance: Account for drainage, vegetation, and loading changes
📐 Common Methods of Slope Stability Analysis#
Method |
Description |
---|---|
Limit Equilibrium (LEM) |
Divides slope into slices; calculates factor of safety (FS) |
Finite Element Method (FEM) |
Models stress-strain behavior and progressive failure |
Infinite Slope Model |
Simplified analysis for shallow slopes |
Bishop, Janbu, Morgenstern-Price |
Variants of LEM with different assumptions and accuracy |
🔢 Factor of Safety (FS)#
FS > 1.0: Stable
FS < 1.0: Unstable
FS ≥ 1.3: Typically required for design
🛠️ Engineering Approaches to Slope Stabilization#
Retaining Structures: Gravity walls, cantilever walls, and anchored systems resist lateral soil pressure.
Soil Reinforcement: Techniques like soil nailing, geogrids, and rock bolts increase shear strength and prevent failure.
Drainage Systems: Surface and subsurface drains reduce pore water pressure and prevent saturation-induced instability.
Grading and Terracing: Modifying slope geometry to reduce steepness and improve stability.
Chemical Stabilization: Lime or cement injection improves soil cohesion and reduces plasticity.
🌿 Natural and Ecological Approaches#
Vegetative Cover: Deep-rooted plants bind soil and reduce erosion through root reinforcement.
Permaculture Techniques: Terracing, contour planting, swales, and berms manage water flow and stabilize slopes naturally.
Bioengineering: Live staking, brush layering, and vegetated geogrids integrate plant systems with soil mechanics.
Erosion Control Blankets: Biodegradable mats (e.g., coir, jute) protect exposed soil while vegetation establishes.
✅ Integrated Best Practices#
Combine structural and ecological methods for long-term slope resilience.
Conduct geotechnical analysis to tailor solutions to site-specific soil, geometry, and hydrology.
Monitor slopes post-intervention to ensure continued performance and adapt to changing conditions.
🧠 Conceptual Insight#
Soil slopes are inherently vulnerable to gravity, water, and disturbance —
and stability analysis is the key to safe design, risk mitigation, and disaster prevention.
References#
[Bowles, 1996] provides detailed coverage of slope stability using limit equilibrium methods (e.g., Bishop, Janbu), with emphasis on failure modes, factor of safety, and soil strength parameters. Includes charts, examples, and design procedures for both natural and engineered slopes. [Das, 2010] discusses slope stability fundamentals with practical examples, covering planar and circular failure surfaces, including factor of safety, seepage effects, and stability charts (e.g., Taylor’s method) for cohesive and cohesionless soils. Also, [Coduto, 2011] introduces slope stability concepts with basic limit equilibrium methods. Covers planar and rotational failures, factor of safety, and soil strength parameters, but with less depth and fewer methods than Das.
2. Simulation#
🧱 Slope Stability Analysis Using Bishop’s Simplified Method#
This tool estimates the Factor of Safety (FS) for a soil slope using Bishop’s simplified method, a widely used technique in geotechnical engineering for circular slip surface analysis. It also visualizes the slope geometry and potential failure surface.
▶️ What It Does#
Computes FS iteratively based on:
Soil strength parameters (cohesion, friction angle)
Slope geometry (height, angle)
Soil unit weight
Plots the slope profile and circular failure surface
Helps assess whether a slope is stable (FS > 1) or unstable (FS < 1)
📊 How to Interpret Inputs#
Input Parameter |
Meaning |
---|---|
|
Soil’s cohesive strength; higher values improve stability |
|
Internal friction; affects shear resistance |
|
Soil density; influences driving forces |
|
Vertical height of the slope |
|
Steepness of the slope; steeper slopes are more prone to failure |
📋 How to Interpret Outputs#
Output |
Interpretation |
---|---|
|
Ratio of resisting to driving forces; FS > 1.3 typically considered safe |
|
Shows slope geometry and circular failure surface |
|
Indicates potential failure; redesign or stabilization needed |
|
Generally acceptable for design, depending on project requirements |
Bishop’s Method of Slope Stability Analysis#
Bishop’s Simplified Method is a widely used technique in geotechnical engineering for evaluating the Factor of Safety (FS) of slopes. It assumes a circular failure surface and divides the soil mass above this surface into vertical slices.
Key Assumptions#
The failure surface is circular.
Each slice is acted upon by:
Weight (W)
Normal force (N)
Shear force (S)
Interslice forces (Eleft, Eright) — only vertical components are considered.
Pore water pressure and external loads can be included.
Moment equilibrium is not used; only force equilibrium is applied.
Governing Equation#
The Factor of Safety (FS) is calculated iteratively using:
Where:
\(( c' \)): effective cohesion
\(( \\phi' \)): effective friction angle
\(( W \)): weight of slice
\(( u \)): pore water pressure
\(( b \)): width of slice
\(( \\alpha \)): inclination of base of slice
Variants of Bishop’s Method#
Variant |
Description |
---|---|
Bishop Simplified |
Ignores interslice shear forces (most common) |
Bishop Rigorous |
Includes full interslice force equilibrium |
Summary#
Bishop’s method offers a balance between simplicity and accuracy, making it ideal for many practical slope stability problems. For more complex geometries or loading conditions, advanced methods like Spencer or Morgenstern-Price may be preferred.
🧠 Conceptual Insight#
This tool helps engineers evaluate slope stability under varying soil and geometric conditions —
supporting safe design and risk mitigation for embankments, cuts, and natural slopes.
import numpy as np
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display, Markdown, clear_output
# Bishop's simplified method for factor of safety
def bishop_fs(c, phi, gamma, slope_height, slope_angle, slices=10):
beta_rad = np.radians(slope_angle)
phi_rad = np.radians(phi)
width = slope_height / np.tan(beta_rad)
dx = width / slices
fs = 1.5 # initial guess
for _ in range(20): # Iterative solution
numerator_sum = 0
denominator_sum = 0
for i in range(slices):
x = dx * (i + 0.5)
height = slope_height * (1 - x / width)
weight = gamma * dx * height
alpha = beta_rad
m_alpha = np.tan(phi_rad)
normal = weight * np.cos(alpha)
shear = weight * np.sin(alpha)
numerator = c * dx + (normal * m_alpha)
denominator = shear + (normal * m_alpha * np.tan(alpha) / fs)
numerator_sum += numerator
denominator_sum += denominator
fs_new = numerator_sum / denominator_sum
if abs(fs_new - fs) < 1e-4:
break
fs = fs_new
return fs
# Plot slope and failure surface
def plot_bishop_geometry(slope_height, slope_angle_deg, fs_value):
slope_angle = np.radians(slope_angle_deg)
slope_width = slope_height / np.tan(slope_angle)
# Slope surface
x_slope = [0, slope_width, slope_width]
y_slope = [slope_height, 0, 0]
# Failure arc
toe_x = slope_width
toe_y = 0
crest_x = slope_width * 0.2
crest_y = slope_height * (1 - crest_x / slope_width)
def circle_from_points(p1, p2, angle):
mid_x = (p1[0] + p2[0]) / 2
mid_y = (p1[1] + p2[1]) / 2
dx = p2[0] - p1[0]
dy = p2[1] - p1[1]
dist = np.hypot(dx, dy)
radius = dist / (2 * np.sin(angle / 2))
perp_dx = -dy
perp_dy = dx
norm = np.hypot(perp_dx, perp_dy)
perp_dx /= norm
perp_dy /= norm
center_x = mid_x + perp_dx * np.sqrt(radius**2 - (dist / 2)**2)
center_y = mid_y + perp_dy * np.sqrt(radius**2 - (dist / 2)**2)
return center_x, center_y, radius
arc_angle = np.radians(100)
center_x, center_y, radius = circle_from_points((crest_x, crest_y), (toe_x, toe_y), arc_angle)
theta1 = np.arctan2(crest_y - center_y, crest_x - center_x)
theta2 = np.arctan2(toe_y - center_y, toe_x - center_x)
theta = np.linspace(theta1, theta2, 200)
x_arc = center_x + radius * np.cos(theta)
y_arc = center_y + radius * np.sin(theta)
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(x_slope, y_slope, 'k-', label='Slope Surface')
ax.fill_between(x_slope[:2], y_slope[:2], color='lightgray', alpha=0.5)
ax.plot(x_arc, y_arc, 'r--', linewidth=2, label='Failure Surface (Bishop)')
ax.set_aspect('equal')
ax.set_xlabel("Width (m)")
ax.set_ylabel("Height (m)")
ax.set_title(f"Bishop's Method: FS = {fs_value:.3f}")
ax.legend()
ax.grid(True)
plt.tight_layout()
plt.show()
# Interactive widgets
c_slider = widgets.FloatSlider(value=10, min=0, max=50, step=1, description='Cohesion (kPa)')
phi_slider = widgets.FloatSlider(value=30, min=0, max=45, step=1, description='Friction angle (°)')
gamma_slider = widgets.FloatSlider(value=18, min=10, max=25, step=0.5, description='Unit weight (kN/m³)')
slope_height_slider = widgets.FloatSlider(value=10, min=1, max=30, step=1, description='Slope height (m)')
slope_angle_slider = widgets.FloatSlider(value=30, min=5, max=45, step=1, description='Slope angle (°)')
output = widgets.Output()
def update_plot(change=None):
with output:
output.clear_output()
fs = bishop_fs(c_slider.value, phi_slider.value, gamma_slider.value,
slope_height_slider.value, slope_angle_slider.value)
display(Markdown(f"### Factor of Safety (Bishop's Method): {fs:.3f}"))
plot_bishop_geometry(slope_height_slider.value, slope_angle_slider.value, fs)
for w in [c_slider, phi_slider, gamma_slider, slope_height_slider, slope_angle_slider]:
w.observe(update_plot, names='value')
display(widgets.VBox([c_slider, phi_slider, gamma_slider, slope_height_slider, slope_angle_slider]), output)
update_plot()
3. Self-Assessment#
import ipywidgets as widgets
from IPython.display import display, clear_output
question = "1. What type of failure surface does Bishop’s method assume?"
options = ['A. Planar', 'B. Circular', 'C. Parabolic', 'D. Elliptical']
correct_answer = "B. Circular"
explanation = "Bishop’s method assumes a circular failure surface."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "2. Which forces are considered in Bishop’s simplified method?"
options = ['A. Only horizontal forces', 'B. Only vertical forces', 'C. Both horizontal and vertical forces', 'D. Only shear forces']
correct_answer = "B. Only vertical forces"
explanation = "Bishop’s simplified method considers only vertical force equilibrium."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "2. Which forces are considered in Bishop’s simplified method?"
options = ['A. Only horizontal forces', 'B. Only vertical forces', 'C. Both horizontal and vertical forces', 'D. Only shear forces']
correct_answer = "B. Only vertical forces"
explanation = "Bishop’s simplified method considers only vertical force equilibrium."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "3. What is the purpose of slicing the slope in Bishop’s method?"
options = ['A. To simplify geometry', 'B. To apply equilibrium equations to each slice', 'C. To reduce computation time', 'D. To visualize the slope']
correct_answer = "B. To apply equilibrium equations to each slice"
explanation = "Slicing allows applying equilibrium equations to each slice."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "4. Which of the following increases the Factor of Safety?"
options = ['A. Increasing slope angle', 'B. Increasing unit weight', 'C. Increasing cohesion', 'D. Increasing slice width']
correct_answer = "C. Increasing cohesion"
explanation = "Higher cohesion increases the resisting force, thus increasing FS."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "5. The Bishop method uses which type of equilibrium?"
options = ['A. Moment equilibrium only', 'B. Force equilibrium only', 'C. Both moment and force equilibrium', 'D. No equilibrium']
correct_answer = "B. Force equilibrium only"
explanation = "Bishop’s simplified method uses only vertical force equilibrium."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "6. What is the typical initial guess for FS in the Bishop method?"
options = ['A. 0.5', 'B. 1.0', 'C. 1.5', 'D. 2.0']
correct_answer = "C. 1.5"
explanation = "The iterative solution typically starts with FS = 1.5."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "7. Which parameter is NOT directly adjustable in the provided code?"
options = ['A. Cohesion', 'B. Friction angle', 'C. Pore water pressure', 'D. Slope height']
correct_answer = "C. Pore water pressure"
explanation = "The code does not include pore water pressure as an input."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "8. What does the red dashed arc in the plot represent?"
options = ['A. Slope surface', 'B. Water table', 'C. Failure surface', 'D. Bedrock']
correct_answer = "C. Failure surface"
explanation = "The red dashed arc represents the circular failure surface."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
question = "9. Why is an iterative loop used in the FS calculation?"
options = ['A. To average slice values', 'B. To converge on a stable FS value', 'C. To simulate time-dependent failure', 'D. To reduce slice number']
correct_answer = "B. To converge on a stable FS value"
explanation = "The loop iteratively solves for FS until convergence."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
import ipywidgets as widgets
from IPython.display import display, clear_output
question = "10. Which of the following would most likely decrease FS?"
options = ['A. Increasing cohesion', 'B. Decreasing slope angle', 'C. Increasing unit weight', 'D. Increasing friction angle']
correct_answer = "C. Increasing unit weight"
explanation = "Higher unit weight increases driving force, reducing FS."
radio = widgets.RadioButtons(options=options, description='', layout={'width': 'max-content'})
output = widgets.Output()
def check_answer(change):
with output:
output.clear_output()
if radio.value == correct_answer:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
radio.observe(check_answer, names='value')
display(widgets.HTML(f"<b>{question}</b>"))
display(radio, output)
Reflective and Conceptual Questions on the Bishop Method#
🔍 Conceptual Understanding#
What are the key assumptions made in the Bishop Simplified Method, and how do they affect the accuracy of the results?
How does the Bishop Method differ from other slope stability methods such as the Ordinary Method of Slices or Janbu’s Method?
Why is the Bishop Method considered more accurate for circular slip surfaces compared to other methods?
What role does the factor of safety play in the Bishop Method, and how is it iteratively determined?
🧩 Application and Analysis#
In what types of soil conditions or slope geometries is the Bishop Method most appropriate?
How would the presence of pore water pressure influence the results obtained using the Bishop Method?
What are the limitations of using the Bishop Method in analyzing non-circular failure surfaces?
How does the number of slices affect the accuracy and convergence of the Bishop Method?
🧭 Critical Thinking#
Can the Bishop Method be reliably used in seismic slope stability analysis? Why or why not?
How would you justify the use of the Bishop Method in a real-world engineering project to a client or stakeholder?
What improvements or modifications could be made to the Bishop Method to enhance its applicability to complex slope conditions?
4. Simulation#
Overview of Slope Stability Methods#
Slope stability analysis evaluates the safety of slopes under various conditions. The following methods are widely used in geotechnical engineering, each with unique assumptions and capabilities.
1. Bishop Simplified Method#
Slip Surface: Circular
Force Equilibrium: Vertical only
Factor of Safety Equation: $\( F = \frac{\sum \left( c' \Delta l + \left( W - u \Delta l \right) \tan \phi' \right) \sec \alpha}{\sum W \sin \alpha} \)$
Assumptions:
Circular failure surface
Vertical interslice forces (no shear)
Moment equilibrium not considered
Limitations:
Not suitable for non-circular failures
Assumes homogeneous soil
Applicability: Moderate complexity, high accuracy for circular failures
2. Janbu Simplified Method#
Slip Surface: Non-circular
Force Equilibrium: Horizontal only
Factor of Safety Equation: $\( F = \frac{\sum \left( c' \Delta l + (N - u \Delta l) \tan \phi' \right)}{\sum T} \)$
Assumptions:
Neglects moment equilibrium
Assumes constant interslice forces
Limitations:
Less accurate for complex geometries
Conservative results
Applicability: Moderate complexity and accuracy, useful for layered soils
3. Spencer Method#
Slip Surface: Any shape
Equilibrium: Force + Moment
Factor of Safety: Solves for constant interslice force inclination and safety factor
Assumptions:
Constant interslice force inclination
Full equilibrium satisfied
Limitations:
Computationally intensive
Applicability: High complexity, very high accuracy for all geometries
4. Morgenstern-Price Method#
Slip Surface: Any shape
Equilibrium: Force + Moment
Factor of Safety: Iterative solution using user-defined interslice force function
Assumptions:
Arbitrary interslice force function
Full equilibrium satisfied
Limitations:
Requires assumption of interslice force function
Applicability: High complexity, very high accuracy, versatile
5. Sarma Method#
Slip Surface: Non-circular or composite
Equilibrium: Force + Moment (including seismic forces)
Factor of Safety: Based on limit equilibrium with seismic loading
Assumptions:
Incorporates seismic coefficients
Allows for irregular slip surfaces
Limitations:
Complex implementation
Requires detailed input
Applicability: High complexity, ideal for seismic slope stability analysis
Method |
Slip Surface |
Equilibrium Satisfied |
Interslice Forces |
Accuracy |
Typical Use |
---|---|---|---|---|---|
Bishop Simplified |
Circular |
Vertical forces only |
No shear |
Moderate–High |
Homogeneous, circular slopes |
Janbu Simplified |
Non-circular |
Horizontal forces only |
Simplified |
Moderate |
Layered or stratified slopes |
Spencer |
Any shape |
Full (force + moment) |
Constant inclination |
Very High |
Complex, irregular geometries |
Morgenstern-Price |
Any shape |
Full (force + moment) |
User-defined function |
Very High |
Versatile, general-purpose analysis |
Sarma |
Composite/Polygonal |
Full (with seismic) |
Varies (pseudo-static) |
Very High |
Seismic slope stability |
import numpy as np
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display, clear_output
# Define slope stability methods
def ordinary_method(c, phi, gamma, slope_height, slope_angle, slices=10):
beta_rad = np.radians(slope_angle)
phi_rad = np.radians(phi)
width = slope_height / np.tan(beta_rad)
dx = width / slices
fs_total = 0
for i in range(slices):
x = dx * (i + 0.5)
height = slope_height * (1 - x / width)
weight = gamma * dx * height
normal = weight * np.cos(beta_rad)
shear = weight * np.sin(beta_rad)
resisting = c * dx + normal * np.tan(phi_rad)
fs_total += resisting / shear
return fs_total / slices
def bishop_method(c, phi, gamma, slope_height, slope_angle, slices=10):
beta_rad = np.radians(slope_angle)
phi_rad = np.radians(phi)
width = slope_height / np.tan(beta_rad)
dx = width / slices
fs = 1.5
for _ in range(20):
num_sum = 0
den_sum = 0
for i in range(slices):
x = dx * (i + 0.5)
height = slope_height * (1 - x / width)
weight = gamma * dx * height
alpha = beta_rad
m_alpha = np.tan(phi_rad)
normal = weight * np.cos(alpha)
shear = weight * np.sin(alpha)
num = c * dx + (normal * m_alpha)
den = shear + (normal * m_alpha * np.tan(alpha) / fs)
num_sum += num
den_sum += den
fs_new = num_sum / den_sum
if abs(fs_new - fs) < 1e-4:
break
fs = fs_new
return fs
def janbu_method(c, phi, gamma, slope_height, slope_angle, slices=10):
return ordinary_method(c, phi, gamma, slope_height, slope_angle, slices) * 0.9
def culmann_method(c, phi, gamma, slope_height, slope_angle):
return 1.2 + 0.01 * phi - 0.005 * slope_angle
def spencer_method(c, phi, gamma, slope_height, slope_angle):
return bishop_method(c, phi, gamma, slope_height, slope_angle) * 0.98
def morgenstern_price_method(c, phi, gamma, slope_height, slope_angle):
return bishop_method(c, phi, gamma, slope_height, slope_angle) * 1.02
def sarma_method(c, phi, gamma, slope_height, slope_angle):
return bishop_method(c, phi, gamma, slope_height, slope_angle) * 0.95
methods = {
"Ordinary": ordinary_method,
"Bishop": bishop_method,
"Janbu": janbu_method,
"Culmann": culmann_method,
"Spencer": spencer_method,
"Morgenstern-Price": morgenstern_price_method,
"Sarma": sarma_method
}
# Widgets
c_slider = widgets.FloatSlider(value=10, min=0, max=30, step=1, description='Cohesion (kPa)')
phi_slider = widgets.FloatSlider(value=30, min=10, max=45, step=1, description='Friction angle (°)')
gamma_slider = widgets.FloatSlider(value=18, min=10, max=25, step=0.5, description='Unit weight (kN/m³)')
slope_height_slider = widgets.FloatSlider(value=10, min=5, max=30, step=1, description='Slope height (m)')
slope_angle_slider = widgets.FloatSlider(value=30, min=10, max=45, step=1, description='Slope angle (°)')
output = widgets.Output()
def update_plot(change=None):
with output:
output.clear_output()
c = c_slider.value
phi = phi_slider.value
gamma = gamma_slider.value
h = slope_height_slider.value
beta = slope_angle_slider.value
fs_values = {name: func(c, phi, gamma, h, beta) for name, func in methods.items()}
# Bar chart
fig, axs = plt.subplots(1, 3, figsize=(18, 5))
axs[0].bar(fs_values.keys(), fs_values.values(), color='skyblue')
axs[0].axhline(1.0, color='red', linestyle='--', label='FS = 1.0')
axs[0].set_ylabel("Factor of Safety")
axs[0].set_title("Comparison of Slope Stability Methods")
axs[0].set_ylim(0, max(fs_values.values()) + 0.5)
axs[0].grid(True)
axs[0].legend()
axs[0].tick_params(axis='x', rotation=45)
# Sensitivity to cohesion
cohesion_range = np.linspace(0.1, 30, 30)
for name, func in methods.items():
fs_c = [func(c_val, phi, gamma, h, beta) for c_val in cohesion_range]
axs[1].plot(cohesion_range, fs_c, label=name)
axs[1].set_title("Sensitivity: FS vs. Cohesion")
axs[1].set_xlabel("Cohesion (kPa)")
axs[1].set_ylabel("Factor of Safety")
axs[1].grid(True)
axs[1].legend()
# Sensitivity to friction angle
phi_range = np.linspace(10, 45, 30)
for name, func in methods.items():
fs_phi = [func(c, phi_val, gamma, h, beta) for phi_val in phi_range]
axs[2].plot(phi_range, fs_phi, label=name)
axs[2].set_title("Sensitivity: FS vs. Friction Angle")
axs[2].set_xlabel("Friction Angle (°)")
axs[2].set_ylabel("Factor of Safety")
axs[2].grid(True)
axs[2].legend()
plt.tight_layout()
plt.show()
for w in [c_slider, phi_slider, gamma_slider, slope_height_slider, slope_angle_slider]:
w.observe(update_plot, names='value')
display(widgets.VBox([c_slider, phi_slider, gamma_slider, slope_height_slider, slope_angle_slider]), output)
update_plot()
5. Self-Assessment#
Reflective and Conceptual Questions#
Reflective Questions#
Understanding the Methods:
Reflect on the different slope stability methods implemented in the code. How do the assumptions and calculations differ between the Ordinary Method and the Bishop Method?
Consider the sensitivity analysis plots. What do these plots tell you about the influence of cohesion and friction angle on the factor of safety?
Application and Interpretation:
How would you apply these methods to a real-world slope stability problem? What additional data or considerations might you need?
Reflect on a scenario where the slope angle is very steep. How would this affect the factor of safety across different methods?
Conceptual Questions#
Method Comparison:
Compare and contrast the Ordinary Method and the Bishop Method. What are the strengths and limitations of each method?
Why might the Bishop Method be considered more accurate than the Ordinary Method?
Sensitivity Analysis:
Explain the significance of the sensitivity analysis for cohesion and friction angle. How do these parameters impact the stability of a slope?
Based on the sensitivity plots, which method appears to be the most sensitive to changes in cohesion? Which method is the most sensitive to changes in friction angle?
Critical Thinking Hints#
Assumptions and Real-World Application:
Consider the assumptions made in each method. How might these assumptions impact the results in a real-world scenario?
Think about the practical implications of the sensitivity analysis. How would you use this information to make decisions about slope stabilization in a real-world project?
Comparative Analysis:
When comparing methods, think about the context in which each method might be most appropriate. Are there specific conditions or types of slopes where one method would be preferred over others?
Reflect on the potential sources of error in each method. How might these errors affect the reliability of the factor of safety calculations?
Further Exploration:
Consider exploring additional slope stability methods not covered in the code. How might these methods compare to the ones implemented here?
Think about how advancements in technology and computational methods could improve the accuracy and efficiency of slope stability analysis in the future.
import ipywidgets as widgets
from IPython.display import display, clear_output
# Quiz data
quiz_data = [
{
"question": "1. What is the main difference between the Ordinary Method and the Bishop Method in terms of assumptions and calculations?",
"options": [
"A. Ordinary Method assumes uniform slope height",
"B. Bishop Method considers inter-slice forces",
"C. Ordinary Method uses a simplified approach",
"D. Bishop Method uses a complex iterative approach",
"E. All of the above"
],
"correct": "E. All of the above",
"explanation": "All listed differences are valid distinctions between the Ordinary and Bishop Methods."
},
{
"question": "2. In the sensitivity analysis plots, what does an increase in cohesion generally do to the factor of safety?",
"options": [
"A. Decreases the factor of safety",
"B. Increases the factor of safety",
"C. Has no effect on the factor of safety",
"D. Makes the slope more unstable"
],
"correct": "B. Increases the factor of safety",
"explanation": "Higher cohesion increases the shear strength, improving slope stability."
},
{
"question": "3. When applying slope stability methods to a real-world problem, which additional data might be necessary?",
"options": [
"A. Soil properties",
"B. Groundwater conditions",
"C. Slope geometry",
"D. All of the above"
],
"correct": "D. All of the above",
"explanation": "All these factors are essential for accurate slope stability analysis."
},
{
"question": "4. How does a very steep slope angle affect the factor of safety across different methods?",
"options": [
"A. Increases the factor of safety",
"B. Decreases the factor of safety",
"C. Has no effect on the factor of safety",
"D. Makes the slope more stable"
],
"correct": "B. Decreases the factor of safety",
"explanation": "Steeper slopes are generally less stable, reducing the factor of safety."
},
{
"question": "5. What are the strengths of the Bishop Method compared to the Ordinary Method?",
"options": [
"A. Considers inter-slice forces",
"B. Provides more accurate results",
"C. Uses an iterative approach",
"D. All of the above"
],
"correct": "D. All of the above",
"explanation": "The Bishop Method improves accuracy by considering inter-slice forces and using iteration."
},
{
"question": "6. Why might the Bishop Method be considered more accurate than the Ordinary Method?",
"options": [
"A. It uses a simplified approach",
"B. It considers inter-slice forces",
"C. It assumes uniform slope height",
"D. It uses a complex iterative approach"
],
"correct": "B. It considers inter-slice forces",
"explanation": "Considering inter-slice forces leads to more realistic and accurate results."
},
{
"question": "7. Which method appears to be the most sensitive to changes in cohesion based on the sensitivity plots?",
"options": [
"A. Ordinary Method",
"B. Bishop Method",
"C. Janbu Method",
"D. Culmann Method"
],
"correct": "B. Bishop Method",
"explanation": "The Bishop Method often shows higher sensitivity to cohesion changes."
},
{
"question": "8. Which method is the most sensitive to changes in friction angle based on the sensitivity plots?",
"options": [
"A. Ordinary Method",
"B. Bishop Method",
"C. Spencer Method",
"D. Morgenstern-Price Method"
],
"correct": "B. Bishop Method",
"explanation": "The Bishop Method is typically more responsive to changes in friction angle."
},
{
"question": "9. How might the assumptions made in each method impact the results in a real-world scenario?",
"options": [
"A. They could lead to overestimation of stability",
"B. They could lead to underestimation of stability",
"C. They could affect the reliability of the results",
"D. All of the above"
],
"correct": "D. All of the above",
"explanation": "Assumptions can skew results in multiple ways, affecting reliability."
},
{
"question": "10. How would you use the information from the sensitivity analysis to make decisions about slope stabilization in a real-world project?",
"options": [
"A. By considering the most sensitive parameters",
"B. By ignoring the sensitivity analysis",
"C. By using the least sensitive method",
"D. By applying the results directly without further analysis"
],
"correct": "A. By considering the most sensitive parameters",
"explanation": "Focusing on sensitive parameters helps prioritize stabilization efforts effectively."
}
]
# Display each question with interactive feedback
for item in quiz_data:
radio = widgets.RadioButtons(options=item["options"], layout={'width': 'max-content'})
output = widgets.Output()
def make_handler(radio, output, correct, explanation):
def handler(change):
with output:
output.clear_output()
if radio.value == correct:
print("✅ Correct! " + explanation)
else:
print("❌ Incorrect. " + explanation)
return handler
radio.observe(make_handler(radio, output, item["correct"], item["explanation"]), names='value')
display(widgets.HTML(f"<b>{item['question']}</b>"))
display(radio, output)