Updated 23 November 2021
Reading time: 15 mins

P-Delta Analysis and Geometric Non-linearity

In this tutorial, we'll explore P-Delta analysis, a geometric non-linearity that can lead to large deflections in slender structures
[object Object]
by Dr Seán Carroll
Free Download - The Complete Python Code for this Tutorial

Free Download - The Complete Python Code for this Tutorial

In this tutorial, we’ll consider P-Delta analysis (PΔP-\Delta); a form of non-linear behaviour that can lead to large magnitude sway deflections in columns. PΔP-\Delta behaviour occurs in members subject to compression and it presents a particular challenge for columns within tall flexible structures. If you want to download the complete Jupyter Notebook for this tutorial, just follow the link below.

1.0 What is the P-Delta effect?

Put simply, PΔP-\Delta describes the phenomenon whereby an additional or secondary moment is generated in a column due to the combination of axial load (P)(P) and lateral sway (Δ)(\Delta). This leads to non-linear structural behaviour and can result in lateral deflections far in excess of those arising from lateral loading alone. These so-called second-order deflections will induce additional stresses within the structure that may be significant and require special consideration in design.

The PΔP-\Delta effect is referred to as a geometric non-linearity because it arises as a result of the deformed geometry of the structure. This is in contrast to a material non-linearity such as plastic hinge formation that arises due to the properties of the material.

2.0 Secondary moments caused by sway deflections

To flesh out the PΔP-\Delta concept, consider a column segment of length LL subject to an axial force PP and undergoing a relative sway Δ\Delta between its ends. The sway may have been caused by wind loading or inertia forces due to lateral ground motion. Regardless of how the initial sway deflection came to be, the key point is that the compression forces in the column are no longer co-linear.

P-delta effects 1 | EngineeringSkills.com

Figure 1. Column segment with length LL and axial force PP experiencing relative sway Δ\Delta between its ends.

We can think of the axial forces, shears and moments shown above as the primary actions on the structure consistent with the first-order sway deflection, Δ\Delta. Again, notice that the axial forces, PP are no longer co-linear. As a result, an extra second-order moment is developed at the base of the column,

M2=PΔ(1)M_2 = P\Delta \tag{1}

If Δ\Delta is a non-negligible value, we must also consider the additional secondary sway deflection caused my M2M_2. Since the second-order sway deflection further increases the overall sway, leading to yet more secondary sway, we have a feedback loop that could ultimately lead to collapse.

For a tall flexible structure that may undergo significant sway from one storey to the next (storey drift) under lateral base excitation for example, this has catastrophic potential. Only when we are sure that the first-order sway deflection is negligibly small can second-order deflections be ignored.

The PΔP-\Delta effect is a good example of non-linear structural behaviour arising from geometric non-linearity. The typical method of analysis requires iteration to determine the final value that the sway deflection converges on.

This value of sway deflection may be mathematically stable but represent an unsustainable physical configuration for the column. In other words, the second-order deflection may be so high that the column collapses. Ultimately the deciding factor as to whether collapse will occur is the initial sway deflection, Δ\Delta, as this sets in motion the feedback loop that delivers the additional second-order deflection.

Since this is a non-linear structural behaviour wherein the inputs to the structural system are not linearly proportional to the outputs (the structure’s behaviour), superposition should not be used in the analysis.

3.0 P-Delta Analysis Example: Fixed-Free Column

Next, we can demonstrate the iterative nature of PΔP-\Delta analysis with a simple example. Consider a simple column with one end fixed and the other free, subject to a vertical load PVP_V. We will assume that this column experiences a lateral load PLP_L at BB that induces an initial first-order deflection Δ\Delta.

P-delta effects 2 | EngineeringSkills.com

Figure 2. Fixed-free column with axial load PVP_V and lateral load PLP_L which induces an initial sway deflection Δ\Delta at its free end.

Let’s assume the column has the following parameters,

L = 6000 #(mm) Column height
E = 200*10**3 #(N/mm^2) Young's modulus
I = 2065*10**4 #(mm^4) Iyy for 203UC60 column section

We can determine the Euler buckling load for this column to work out a sensible upper limit for the axial load. We can use the following formula for a fixed-free column,

Pcr=π2EI4L2(2)P_{cr} = \frac{\pi^2EI}{4L^2} \tag{2}

Note that we’re assuming buckling about the minor axis. This is why we selected IyyI_{yy} from the section tables.

Pcr = pi**2*E*I/(4*L**2) #(N) Critical buckling load
print('The critical buckling load is Pcr = {one} N'.format(one=round(Pcr)))

-> The critical buckling load is Pcr = 283066 N

Let’s assume the column is subject to a compression force of PV=0.7PcrP_V =0.7 P_{cr}. Let’s also assume that the column is subjected to a lateral force magnitude PL=0.05PVP_L = 0.05P_V.

Pv = 0.7*Pcr
Pl = 0.05*Pv
print('The column axial load is Pv = {one} N'.format(one=round(Pv)))
print('The column lateral load is Pl = {one} N'.format(one=round(Pl)))

->The column axial load is Pv=198146NPv = 198146 N ->The column lateral load is Pl=9907NPl = 9907 N

We can calculate the first-order deflection (hereafter referred to as Δ1\Delta_1) due to the lateral load PVP_V using he standard formula for cantilever deflection,

Δ1=MBL23EI=PLL33EI(3)\Delta_1 = \frac{M_BL^2}{3EI} = \frac{P_L L^3}{3EI} \tag{3}

where MB=PLLM_B=P_L L is the moment generated at the base of the column by the lateral load PLP_L.

D1 = (Pl*L**3)/(3*E*I)
print('The first-order deflection, Delta = {one} mm'.format(one=round(D1,1)))

-> The first-order deflection, Delta=172.7mmDelta = 172.7 mm

We know that this first-order sway deflection induces an additional second-order moment that has a value of M2=PVΔ1M_2 = P_V\Delta_1 at the base of the column. If we examine the internal moment at some distance xx from the base of the column, we can see that this moment actually varies between M2=0M_2 = 0 at the tip of the column and M2=PVΔ1M_2=P_V\Delta_1 at the base of the column, with the moment diagram having the same shape as the first-order deflected shape, M2(x)=PV(Δv(x))M_2(x) = P_V(\Delta-v(x)), Fig. 3.

P-delta effects 3 | EngineeringSkills.com

Figure 3. Second-order bending moment.

At this point we can make a simplification and assume that the second-order moment varies linearly between M2=0M_2 = 0 and M2=PVΔ1M_2=P_V\Delta_1, Fig.4.

P-delta effects 4 | EngineeringSkills.com

Figure 4. Fixed-free column with first-order, second-order and linearised second-order bending moment diagrams.

If we do this, we can quickly determine the additional deflection induced by the second-order moment using the same equation that was used to calculate Δ1\Delta_1,

Δ2_1=M2L23EI(4)\Delta_{2\_1} = \frac{M_2 L^2}{3EI} \tag{4}

where Δ2_1\Delta_{2\_1} is the first value of second-order deflection calculated. We refer to this value of Δ2\Delta_2 as the first iteration value, Δ2_1\Delta_{2\_1}.

M2 = Pv*D1D2 = (M2*L**2)/(3*E*I)
print('The first iteration of second-order deflection, D = {one} mm'.format(one=round(D2,3)))

-> The first iteration of second-order deflection, D=99.438mmD = 99.438 mm

Now the iterative nature of the analysis becomes apparent as we need to calculate an additional second-order deflection, Δ2_2\Delta_{2\_2} induced by this first iteration value, Δ2_1\Delta_{2\_1}; in other words, our axial load PVP_V now generates a further second-order moment, M2_2=PVΔ2_1M_{2\_2} = P_V \Delta_{2\_1}, leading to a second iteration which yields a further second-order deflection, Δ2_2\Delta_{2\_2}.

The entire process must be repeated yet again with each subsequent value of Δ2\Delta_2 being added to the preceding value. The iterations continue until the new values of second-order deflection being added become sufficiently small. In this way the second-order deflection converges to its final value. We must then judge the acceptability of the total lateral deflection,

Δtotal=Δ1+i=1NΔ2_i(5)\Delta_{total} = \Delta_1 + \sum_{i=1}^N \Delta_{2\_i} \tag{5}

3.1 Writing a function to calculate the secondary deflection

Rather than continuing to perform iterations manually, let’s write a short function to perform the iterations and identify the final second-order deflection.

def P_Delta(Pv,Pl,L,E,I,tol):
  """
  Function to iterate towards the final second-order deflection
  Pv: Vertical load
  Pl: Lateral load
  L: Column length
  E: Young's modulus
  I: Second moment of area
  tol: % change tolerance used to check convergence of deflection

  returns an array of second-order deflection values
  """

  D2Array = np.empty([1,0]) #Initialse an array to hold second-order deflection values
  initMoment = Pl*L #First-order moment
  initDef = (initMoment*L**2)/(3*E*I) #Initial first-order sway deflection
  Dp = initDef #Assign initial sway deflection to variable to be updated in loop  

  i=0 #Initialise an iteration counter
  stop = False #Initialise the stop flag
  while stop is False:
    M2 = Pv*Dp #Calculate second-order moment
    D2 = (M2*L**2)/(3*E*I) #Calculate second-order sway deflection  
    D2Array = np.append(D2Array, D2) #Save current value of D2
    Dp = D2 #Update the value of sway deflection for next loop iteration

    #Test for convergence
    if i>0:
      diff = np.sum(D2Array) - np.sum(D2Array[0:len(D2Array)-1]) #Change in second-order deflection
      perDiff = 100*diff/(initDef + np.sum(D2Array)) #Change as a percentage of total deflection
      if(perDiff<tol):
        stop = True #Switch stop flag if change within tolerance
    i+=1
  return D2Array

The function defined above continues to perform iterations to identify second-order deflection values until the value of second-order deflection calculated falls below a threshold percentage of the total column deflection. The function then returns the array of all second-order deflections calculated. Next, we need to call the function and print out the array of deflections calculated.

vals = P_Delta(Pv,Pl,L,E,I,0.1) #Call the function to calculate the second-order deflection
print('The second-order deflections obtained on each iteration are:')
print('')
print(vals)

-> The second-order deflections obtained on each iteration are:

[99.4384471  57.24939121 32.96001587 18.97596853 10.92497598   6.28980281  3.62120882  2.08482741  1.20029127  0.69104     0.39785033]

The total deflection is then easily obtained as the sum of the first-order and all second-order deflections.

D2_total = np.sum(vals) #Sum of all second-order deflections across all iterations
print('- The final value of second-order deflection is {one} mm'.format(one=round(D2_total,1)))
print('- {one} iterations were required to reach this value'.format(one=len(vals)))
print('- The total sway deflection is {one} mm + {two} mm = {three} mm'.format(one=round(D1,1), two=round(D2_total,1), three=round(D1+D2_total,1)))

-> The final value of second-order deflection is 233.8mm233.8 mm -> 11 iterations were required to reach this value -> The total sway deflection is 172.7mm+233.8mm=406.6mm172.7 mm + 233.8 mm = 406.6 mm

Next we can plot the deflection values on each iteration to observer the convergence.

x = np.arange(1,len(vals)+1) #Define an array of iteration numbers 

#Plotting
fig = plt.figure()
axes = fig.add_axes([0.1,0.1,2,1.5])
axes.plot(x,np.cumsum(vals),'-o', label='$\Delta_2$')
axes.plot(x,np.cumsum(vals)+D1,'-o', label='$\Delta*{total}$')
axes.set_xlim([1,len(vals)])
axes.set_ylim([0,1.1*np.cumsum(vals)[-1]+D1])
axes.set_xlabel('Iteration (sec)')
axes.set_ylabel('Deflection (mm)')
axes.set_title('Deflection convergence')
axes.grid()
axes.legend(loc='lower right')
plt.show()
P-delta effects 5 | EngineeringSkills.com

Figure 5. Plot showing convergence of lateral column deflection arising from first and second-order effects.

Now that the additional second-order sway deflection has been determined, subsequent analysis can be carried out to determine the acceptability of the stresses induced. The take away message is the need to be aware of second-order effects when considering the behaviour of slender structures that must resist large axial loads.

4.0 Exploring the P-Delta parameter space

Now that we have a function to calculate the second-order deflection, we can perform a parameter sweep to get a better understanding of the behaviour of the column within the parameter space. After all, we’ve only considered a single combination of axial and lateral load. It would be nice to plot the lateral deflection as a function of these input parameters. We start by defining a range of axial loads as a function of the column critical load and then a range of lateral loads as a proportion of the axial load.

#Axial load as a proportion of the critical load
Axial = np.arange(0.5,1.05,0.05)
#Lateral load as a proportion of the axial load
Lateral = np.arange(0.01,0.11,0.01)

We can now iterate through these values; looping through the axial load with an outer for loop and then the lateral loads with a nested for loop. For every combination of axial and lateral load we will calculate the maximum lateral deflection and the ratio of second to first-order deflection to get a sense of the degree of non-linearity for each parameter combination.

#Define containers to hold calculated values
maxDeflection = np.empty([len(Axial), len(Lateral)])
D2D1*ratio = np.empty([len(Axial), len(Lateral)])

#Initialse a figure (add to it within the loop)
fig, axes = plt.subplots(figsize=(15,15),nrows=2,ncols=1)

#Cycle through each axial load
for i, pv in enumerate(Axial):
  Pv = pv*Pcr #Axial load for this range of iterations 

  #Cycle through each lateral load
  for j, pl in enumerate(Lateral):
    Pl = pl*Pv #Lateral load for this iteration

    vals = P_Delta(Pv,Pl,L,E,I,0.1) #Call the function
    D2_total = np.sum(vals) #Total second-order deflection
    D1 = (Pl*L**3)/(3*E*I) #First-order deflection
    maxDeflection[i,j] = D1+D2_total #Total deflection
    D2D1_ratio[i,j] = D2_total/D1 #Deflection ratio

  #Add to plots
  axes[0].plot(Lateral,maxDeflection[i,:]/L,'-o', label='Axial = {one}Pcr'.format(one=round(pv,2)))
  axes[1].plot(Lateral,D2D1_ratio[i,:],'-o', label='Axial = {one}Pcr'.format(one=round(pv,2)))

#Tidy up plots
axes[0].set_title('Total lateral def normalised by column length')
axes[0].set_xlim([Lateral[0],Lateral[-1]])axes[0].set_xlabel('Lateral load as proportion of axial')
axes[0].set_ylabel('$\Delta*{total}/L$')
axes[0].grid()axes[0].legend(loc='upper left')
axes[1].set_title('Ratio of second to first-order deflection')
axes[1].set_xlim([Lateral[0],Lateral[-1]])axes[1].set_xlabel('Lateral load as proportion of axial')
axes[1].set_ylabel('$\Delta_2/\Delta_1$')
axes[1].grid()
axes[1].legend(loc='upper left')
plt.show()
P-delta effects 6 | EngineeringSkills.com

Figure 6. Lateral deflection normalised by column length (top), ratio of secondary to primary deflection (bottom).

We can see from the first plot above that for any particular value of axial load, the total deflection increases linearly with increasing lateral load. This is not at all surprising, however we also note that the rate of increase (slope of each line) increases as the axial load increases.

If we plot the ratio of second to first-order deflection for each load combination (second plot) we can see that for each value of axial load the ratio of second to first-order defection remains constant but as the axial load increases linearly, the increase in the deflection ratios is not linear. We can see this more clearly if we simply plot a single value of deflection ratio against each value of axial load.

fig = plt.figure()
axes = fig.add_axes([0.1,0.1,2,1.5])
axes.plot(Axial,D2D1_ratio[:,0],'-o')
axes.set_xlim([Axial[0],Axial[-1]])
axes.set_xlabel('Axial load as proportion of critical')
axes.set_ylabel('$\Delta_2/\Delta_1$')
axes.set_title('Ratio of second to first-order deflection')
axes.grid()
plt.show()
P-delta effects 7 | EngineeringSkills.com

Figure 7. Ratio of secondary to primary deflection for increasing levels of axial load.

We can clearly see that the non-linear deflection exceeds the linear deflection as the axial load increases; the column deflection is quickly dominated by the non-linear component of deflection as the axial load increases. Even though in this example we’ve based our analysis on a column that is particularly prone to non-linear PΔP-\Delta deflection, this highlights the importance of not neglecting second-order sway deflections for slender structures that must resists large axial loads.

5.0 P-Delta analysis for more complex structures

The example above is a pretty contrived but simple and common example used to explain and illustrate PΔP-\Delta effects. However, the question now arises; how do we apply what we’ve learned to more complex structures?

At this point, the road forks and there are two approaches. In each case we assume that you have a model of your structure that you can perform a stiffness method analysis on (check out these courses for building stiffness method analysis tools).

Iterative approach

The first approach is to implement basically the same solution strategy described above:

  1. Apply any lateral load, PLP_L to calculate first-order sway deflection, Δ1\Delta_1 for the structure.
  2. Manually displace the structural model by applying the nodal displacements to each node in the model according to Δ1\Delta_1 nodal deflections.
  3. Apply any vertical loads to the deformed structure (PV×Δ1)(P_V\times \Delta_1) to calculate second-order deflections, Δ2_1\Delta_{2\_1} and note the second-order nodal deflections obtained.
  4. Displace the structure (from its undisplaced position) according to Δ2_1\Delta_{2\_1} nodal deflections.
  5. Apply vertical loads again to the deformed structure (PV×Δ2_1)(P_V\times \Delta_{2\_1}) to calculate second-order deflections, Δ2_2\Delta_{2\_2}.
  6. Repeat steps 4 and 5 until the second-order deflections observed have become negligibly small.
  7. Calculate the total deflection, Δtotal=Δ1+Δ2_i\Delta_{total} = \Delta_1 + \sum \Delta_{2\_i}.

Geometric stiffness matrix approach

A more sophisticated and efficient approach would be to modify the element stiffness matrix to take into account geometric non-linearity. This will result in an element stiffness matrix that exhibits coupling between the axial force and bending moments in the element. Derivation of this stiffness matrix is beyond the scope of this tutorial, but once obtained, this approach will allow the structure to be solved without iteration. Most commercial frame solvers will have the option of taking into account geometric non-linearity and will calculate the appropriate element stiffness matrix.

Well that’s all for this tutorial. I hope you found it helpful and now have a good understanding of PΔP-\Delta effects as a form of geometric non-linearity and how to calculate them in practice. Remember that you can download the complete Jupyter Notebook for this tutorial for free by clicking the link at the top of this tutorial.

getting-started
Dr Seán Carroll
BEng (Hons), MSc, PhD, CEng MIEI, FHEA
Hi, I’m Seán, the founder of EngineeringSkills.com (formerly DegreeTutors.com). I hope you found this tutorial helpful. After spending 10 years as a university lecturer in structural engineering, I started this site to help more people understand engineering and get as much enjoyment from studying it as I do. Feel free to get in touch or follow me on any of the social accounts.

Dr Seán Carroll's latest courses.

Analytical Modelling of Plate and Shell Structures: Part 1 - Plates

Analytical Modelling of Plate and Shell Structures: Part 1 - Plates

A practical guide to the analysis of circular and rectangular plates under load, from first principles.

Fundamentals of Reinforced Concrete Design to Eurocode 2

Fundamentals of Reinforced Concrete Design to Eurocode 2

An introduction to ultimate limit state design for bending and shear with optional calculation automation using Python.

Modelling and Analysis of Non-linear Cablenet Structures using Python and Blender

Modelling and Analysis of Non-linear Cablenet Structures using Python and Blender

Learn how to combine parametric modelling, exploratory form-finding and iterative analysis techniques to simulate 3D tensile structures.

Non-linear Finite Element Analysis of 2D Catenary & Cable Structures using Python

Non-linear Finite Element Analysis of 2D Catenary & Cable Structures using Python

Build an iterative solution toolbox to analyse structures that exhibit geometric non-linearity due to large deflections.


Do you have some knowledge or expertise you'd like to share with the EngineeringSkills community?
Check out our guest writer programme - we pay for every article we publish.