Hi friends,
Today, we’ll take a break from the structural loads series to refresh our knowledge about stress and strain - an essential fundamental of structural engineering.
This article is contributed by James O’Reilly from Flocode.
I highly recommend checking out James’ newsletter and course if you want to learn Python. It’s an amazing resource.
When I started learning Python, there weren’t any resources specifically for civil and structural engineers. I took a general introductory course in Python during my bachelor's degree, which was available to all students at my university. We learned about variables, functions, and matrices. However, it didn’t showcase Python examples from our industry, and I didn’t see how I could apply Python to my engineering tasks.
Guess what?! I failed the course. I have a hard time learning theoretical concepts when I don’t understand how to apply the knowledge. For context, this was in 2018.
Once I started working as an engineer, I realized how Python can help automate tasks, and I began coding in my spare time. I started implementing Python in my Dynamo and Grasshopper scripts and coded a prototype of an object detection tool for construction objects.
Python is a powerful skill set to have as a structural engineer, and with Flocode, you have the perfect resource to learn Python with industry-related examples.
Thank you, James, for contributing great content to our engineering community.
Now, let’s talk about stress and strain.
Stress and Strain in Structural Engineering
Stress and strain are pivotal ideas in many branches of engineering, forming the backbone of material behaviour analysis under various loads. These principles are integral to structure design, analysis, and assessment.
While I appreciate that most engineers already understand this, there is great value in reviewing these ideas every so often to gain new insights.
In this article, we will explore stress-strain relationships, material-specific behaviours, and analytical methods, complemented by simple Python code examples to illustrate key calculations.
If you’re not familiar with Python, fear not, the code will be explained as we progress.
If you are interested in Python and its many wonderful Structural and Civil Engineering applications, you can review many more articles at flocode.substack.com.
Stress and strain are much more than abstract concepts from engineering textbooks; they are the fundamental forces that determine whether structures stand or collapse. Consider the intricate interplay of forces within a tied-arch bridge as it supports vehicles, or the invisible tensions within a skyscraper swaying in the wind. These forces, quantified as stress and strain, govern the safety and durability of all engineered structures.
We will revisit these fundamentals, not through dry academic discourse, but by igniting a deeper curiosity and appreciation for the mechanics behind stress and strain. By blending technical insights with intuitive analogies and real-world examples, we will enrich our understanding and application of these concepts.
Historical Context
The journey to understanding stress and strain has been long and winding. Early pioneers like Galileo and Hooke made significant strides in understanding material behaviour, yet they often viewed structures as whole entities rather than focusing on the forces at individual points within the material. This approach led to complex and often convoluted theories that puzzled even the brightest minds of their time.
The breakthrough came in 1822 when Augustin Cauchy introduced the concepts of stress and strain in a paper presented to the French Academy of Sciences. This paradigm shift allowed engineers to analyze materials at a granular level, understanding how forces and deformations interact within the material itself. Cauchy's work transformed the study of elasticity from a philosophical exercise into a practical tool for engineers, simplifying the design and analysis of structures.
Fundamentals of Stress and Strain
Stress is defined as the internal force per unit area within a material. It is typically measured in Pascals (Pa) or pounds per square inch (psi). Mathematically, it is expressed as:
Where:
σ is the stress,
F is the internal force,
A is the cross-sectional area.
Strain is the measure of deformation representing the displacement between particles in the material body. It is a dimensionless quantity and is given by:
Where:
ϵ is the strain,
ΔL is the change in length,
L_0 is the original length.
Let us examine a Python function that calculates stress and strain.
A Python function is a reusable block of code designed to perform a specific task. It can take inputs, called arguments (force and area), and return an output (stress). Functions help organize and modularize code, making it easier to read, maintain, and reuse. They are defined using the def
keyword followed by the function name and parentheses containing any parameters.
# Function to calculate stress
def calculate_stress(force, area):
return force / area
This function, calculate_stress
, takes two arguments: force
and area
. It returns the stress, calculated by dividing the force by the area.
# Function to calculate strain
def calculate_strain(delta_length, original_length):
return delta_length / original_length
This function, calculate_strain
, takes two arguments: delta_length
and original_length
. It returns the strain, calculated by dividing the change in length (delta_length
) by the original length (original_length
).
# Example usage
force = 5000 # Newtons
area = 50 # mm²
delta_length = 0.2 # mm
original_length = 1000 # mm
stress = calculate_stress(force, area)
strain = calculate_strain(delta_length, original_length)
print(f"Stress: {stress} N/mm²")
print(f"Strain: {strain}")
Stress: 100.0 N/mm²
Strain: 0.0002
In this example, we complete the following:
Define variables for force, area, change in length, and original length with appropriate units.
Calculate stress and strain using the defined functions.
Print the results.
The output will show the stress in (N/mm²) and the strain as a dimensionless ratio.
To truly grasp stress and strain, consider stress as the “pressure” within solids, like the pressure in a car’s tires or a basketball. Strain, on the other hand, is the “stretching” of bonds between atoms, similar to how a basketball deforms as it bounces or a rubber band elongates when pulled.
Imagine stretching the rubber band. As you pull, the rubber band resists, creating stress within the material. The elongation you observe is the strain. Similarly, consider a cable supporting a bridge deck. The force exerted by the deck creates stress in the cable, while the elongation of the cable represents strain.
Stress-Strain Relationship
Understanding the stress-strain relationship is crucial for predicting material behaviour under load. Hooke's Law describes the linear relationship between stress and strain in the elastic region.
Beyond the elastic limit, materials exhibit plastic deformation, characterized by permanent changes in shape. The stress-strain curve highlights key points such as the yield point, ultimate tensile strength, and failure point, which are crucial for defining material limits.
Let’s consider some common materials.
Steel
Stress-strain in steel typically exhibits a linear elastic region followed by a yield point, strain hardening, and eventual ultimate tensile strength before failure.
Concrete
Concrete exhibits high compressive strength but low tensile strength, often necessitating reinforcement to handle tensile stresses. Its non-linear stress-strain curve in compression is characterized by a steep initial rise, plateau, and eventual failure.
Composites
Composite materials and composite action are two fundamental concepts, each playing a crucial role in how structures respond to various loads. Composite materials are engineered by combining two or more constituent materials with different physical or chemical properties to create a new material with unique characteristics. Examples include fibre-reinforced polymers (FRP) and carbon fibre composites designed to optimize the strength-to-weight ratio. These materials typically exhibit anisotropic behaviour, meaning their properties vary depending on the direction of the load. The stress-strain curves for composite materials reflect this anisotropic nature, showing different responses based on the orientation of the reinforcing fibres. For instance, fibre-reinforced composites (including concrete) have high tensile strength and stiffness along the fibre direction but may be weaker perpendicular to the fibres.
In contrast, composite action refers to the synergistic interaction between distinct materials within a structure, allowing them to work together as a single unit to resist loads. A common example is a steel girder and cast-in-place concrete deck in bridge construction. Here, the steel provides tensile strength while the concrete offers compressive strength. The stress-strain curves for composite action illustrate the combined behaviour of the materials involved, showing the high tensile strength and elasticity of steel alongside the high compressive strength of concrete. This interaction is facilitated by shear connectors, ensuring the materials act together under load.
Polymers
Polymers, composed of large molecules with repeating structural units, exhibit viscoelastic behaviour, meaning their stress-strain response is time-dependent and combines both viscous and elastic characteristics. This unique property allows polymers to deform under long-term loads and then recover their shape, making them ideal for applications requiring flexibility and durability (e.g. bridge expansion joints, marine fenders, elastomeric bearings).
Analytical Methods and Tools
Analyzing stress and strain involves various analytical tools and methodologies that provide detailed insights into material behaviour.
Stress-Strain Curves: As mentioned above, these curves plot the relationship between stress and strain, highlighting key material properties such as elasticity, yield strength, and ultimate tensile strength.
Mohr's Circle: This graphical method is used to understand and analyze the state of stress at a point within a material. By providing a graphical representation, it simplifies the complex relationships between different stress components, making it easier to determine principal stresses, maximum shear stress, and stress transformations.
Finite Element Method (FEM): FEM is a numerical technique used for solving complex stress-strain problems, allowing detailed analysis of stresses and strains within each element of a structure. I have spent a lot of time wrestling with FE models.
I both love and hate FE modelling.
Here’s a Python example using Mohr's Circle to analyze stress states:
import numpy as np
import matplotlib.pyplot as plt
# Function to calculate Mohr's Circle parameters
def mohrs_circle(sigma_x, sigma_y, tau_xy):
center = (sigma_x + sigma_y) / 2
radius = np.sqrt(((sigma_x - sigma_y) / 2) ** 2 + tau_xy ** 2)
return center, radius
# Example usage
sigma_x = 50 # N/mm²
sigma_y = 20 # N/mm²
tau_xy = 30 # N/mm²
center, radius = mohrs_circle(sigma_x, sigma_y, tau_xy)
theta = np.linspace(0, 2 * np.pi, 100)
x = center + radius * np.cos(theta)
y = radius * np.sin(theta)
# Plotting Mohr's Circle
plt.plot(x, y)
plt.scatter([sigma_x, sigma_y], [tau_xy, -tau_xy], color='red')
plt.xlabel('Normal Stress (N/mm²)')
plt.ylabel('Shear Stress (N/mm²)')
plt.title("Mohr's Circle")
plt.grid(True)
plt.axis('equal')
plt.show()
This example demonstrates the computation and visualization of stress states using Mohr's Circle, aiding in the assessment of principal stresses and strains.
Advances and Emerging Trends
Our industry is continually evolving, with new materials and advanced analytical techniques reshaping the landscape. Innovations such as high-performance concrete, advanced composites, and smart materials offer enhanced strength, durability, and functionality. These materials exhibit unique stress-strain behaviors, requiring updated research and analysis methods to fully leverage their properties.
In my area of practice. ‘Power and Water’, I’ve been dealing with new concrete mix designs and methods, specialized steel coatings and advanced polymers. It’s fascinating stuff, but the depth of information can be both overwhelming and sometimes distracting. This simply enforces the importance of understanding the fundamental principles of stress and strain to navigate these complexities effectively.
Analytical methods have also advanced, with computational tools becoming increasingly more sophisticated, for better or worse depending on who you ask!
These tools allow for detailed simulations of complex structures, enabling us to predict and optimize performance with greater accuracy. The integration of artificial intelligence and machine learning further enhances the capability to model and analyze structural behaviour, leading to more efficient and innovative designs.
Emerging trends include the use of parametric design and generative design techniques, which utilize algorithms to explore a vast array of design possibilities, optimizing for various criteria such as material usage, strength, and aesthetics. These approaches are revolutionizing how engineers approach problem-solving and design, leading to more innovative and efficient structures.
ANSYS and Altair are undertaking some exciting work on this topic.
We will explore this stuff more deeply in the future but for now, see below for an example of using Python with a machine learning model (polynomial regression) to predict material behaviour under stress.
If you are not familiar with this library, don’t worry. We will dig into Scikit-Learn much more in the future. You can also check out my previous article for some ML fundamentals: #003 - Machine Learning for Civil and Structural Engineers | 01: The Fundamentals
Below, is a larger code block, bear with me; it’s much easier than it first appears. Half of the code is for plotting the visuals.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error, r2_score
def steel_stress_strain(strain, E=200000, yield_stress=250, ultimate_stress=400, ultimate_strain=0.005):
elastic_strain = yield_stress / E
plastic_strain = ultimate_strain - elastic_strain
stress = np.where(strain <= elastic_strain,
E * strain,
yield_stress + (ultimate_stress - yield_stress) *
(1 - np.exp(-(strain - elastic_strain) / (plastic_strain / 10))))
return np.minimum(stress, ultimate_stress)
# Generate synthetic stress-strain data
strain = np.linspace(0, 0.005, 1000).reshape(-1, 1)
stress = steel_stress_strain(strain.flatten()) + np.random.normal(0, 1, strain.shape).flatten()
# Split data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(strain, stress, test_size=0.2, random_state=42)
# Create and train the model
model = make_pipeline(StandardScaler(), PolynomialFeatures(degree=5), Ridge(alpha=0.1))
model.fit(X_train, y_train)
# Make predictions and evaluate the model
y_pred = model.predict(X_test)
mse, r2 = mean_squared_error(y_test, y_pred), r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse:.2f}\nR-squared Score: {r2:.4f}")
# Plot results
plt.figure(figsize=(12, 8))
plt.scatter(X_test, y_test, color='blue', alpha=0.5, label='Actual Data')
sort_idx = np.argsort(X_test.ravel())
plt.plot(X_test[sort_idx], y_pred[sort_idx], color='red', linewidth=2, label='Predicted')
plt.xlabel('Strain'), plt.ylabel('Stress (MPa)'), plt.title('Stress-Strain Curve for Typical Structural Steel')
plt.legend(), plt.grid(True), plt.ylim(0, 450), plt.xlim(0, 0.005)
# Add annotations
elastic_limit = 250 / 200000
annotations = [('Elastic Region', (elastic_limit/2, 125), (0.0015, 50)),
('Yield Point', (elastic_limit, 250), (0.002, 300)),
('Strain Hardening', (0.0035, 400), (0.004, 425))]
for text, xy, xytext in annotations:
plt.annotate(text, xy=xy, xytext=xytext, arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
Mean Squared Error: 46.47
R-squared Score: 0.9965
This model is designed to predict the stress-strain relationship in structural steel, which often exhibits non-linear behavior. Here's a breakdown of the process:
Data Simulation: We generate synthetic data that mimics a non-linear stress-strain curve for structural steel, incorporating some random noise to simulate real-world variability. The stress-strain relationship includes both elastic and plastic deformation regions, reflecting typical material behavior under load.
Polynomial Regression: Instead of fitting a straight line, we use polynomial regression to model the curved stress-strain relationship. This approach captures the non-linear behavior of steel, especially at higher strains.
Feature Scaling: The input strain values are normalized to a common scale. Normalization improves the model's performance, particularly when dealing with polynomial terms of varying magnitudes.
Model Training: The model "learns" the relationship between strain and stress by adjusting its internal parameters to minimize the error between its predictions and the actual data. We use a combination of polynomial features and Ridge regression.
Regularization: Ridge regression helps prevent overfitting by adding a penalty to the model's complexity. This ensures the model generalizes well to new, unseen data rather than just fitting the training data perfectly.
Model Evaluation: We assess the model's performance on a test set, which it hasn't seen before, using metrics such as Mean Squared Error (MSE) and R-squared. These metrics quantify the accuracy and goodness-of-fit of the model.
Prediction: Once trained, the model can predict the stress for new strain values, providing insights into material behavior beyond the range of the training data.
In essence, this model approximates the complex stress-strain behaviour of structural steel, offering flexibility over traditional analytical methods by adapting to various material behaviours without explicitly defining the underlying physical equations.
This approach is particularly useful in structural engineering for:
Predicting material behaviour under different loading conditions
Analyzing new or complex materials where traditional models might fall short
Quickly estimating stress-strain relationships without extensive physical testing
The accuracy of the model depends on the quality and quantity of the data used for training. In real-world applications, you'd use actual experimental/recorded data rather than synthetic data.
The availability of quality data is the current bottleneck in structural engineering for the widespread use of machine learning in design and analysis.
Conclusion
A thorough understanding of stress and strain is obviously critical for structural engineers. These fundamental concepts are essential for designing safe, efficient, innovative structures that withstand diverse loads and conditions.
Throughout this article, we've explored the theoretical aspects of stress and strain and demonstrated how Python can be a powerful tool in deepening your understanding and practical application of these principles.
By leveraging Python, you can visualize stress-strain relationships, perform complex calculations, and even implement machine learning models to predict material behaviour. These computational tools offer a dynamic way to explore and analyze stress and strain beyond traditional methods, providing insights that can significantly enhance your workflow.
The examples provided here are just the beginning. I encourage you to explore further, experiment with the code, and find creative ways to apply these techniques in your own projects. You can access the notebook here.
By doing so, you'll enhance your understanding of stress and strain and develop a more versatile and powerful approach to your broader structural engineering challenges.
The Flocode Community is currently in Beta; please be sure to apply here for access.
Thank you for your time.👋
See you in the next one!
James 🌊