OpenSees Cloud

OpenSees AMI

Something They Can Agree On

24 May 2026 - Michael H. Scott


When it comes to material nonlinear flexural response, there is very little the displacement-based and force-based formulations will agree on. Significant discrepancies can arise due to how equilibrium and compatibility are enforced along an element.

But there is one thing these element formulations can agree on: material nonlinear response under symmetric bending.

A direct analogy to pure tension and pure compression, symmetric bending induces constant bending moment along an element. Assuming the same constitutive model at each section, all integration points will have the same moment-curvature response. As a result, the curvature will be constant along an element, even after yield–a condition both formulations should be able to handle.

Consider a simple beam with applied end moments of equal magnitude but opposite direction as shown below. The moment-curvature response at each section along the element is bilinear with initial stiffness EI, yield moment My, and hardening ratio $alpha;.

The model is defined with a section aggregator and single element. The section axial response uses an elastic material while the flexural response uses Steel01 because the hardening ratio can be specified directly, not because there’s any steel involved. For the analysis, the applied end moments are increased to 1.2 times the section yield moment.

import openseespy.opensees as ops

L = 96
A = 20
I = 800
E = 29000

My = 2000
alpha = 0.05

Mmax = 1.2*My
Nsteps = 100
dM = Mmax/Nsteps

ops.wipe()
ops.model('basic','-ndm',2,'-ndf',3)

ops.node(1,0,0); ops.fix(1,1,1,0)
ops.node(2,L,0); ops.fix(2,1,1,0)

ops.uniaxialMaterial('Elastic',1,E*A)
ops.uniaxialMaterial('Steel01',2,My,E*I,alpha)
ops.section('Aggregator',1,1,'P',2,'Mz')

ops.beamIntegration('Legendre',1,1,2)

ops.geomTransf('Linear',1)

# Change to 'forceBeamColumn'
ops.element('dispBeamColumn',1,1,2,1,1)

ops.timeSeries('Linear',1)
ops.pattern('Plain',1,1)
ops.load(1,0,0,-1)
ops.load(2,0,0, 1)

ops.integrator('LoadControl',dM)
ops.analysis('Static','-noWarnings')
ops.analyze(Nsteps)

The normalized moment-rotation response from both the displacement-based and force-based elements is shown below. Unnormalized, the initial slope is 2EI/L while the second slope is α2EI/L. From the specified yield moment, My, the yield rotation is θy=MyL/(2EI).

The results agree perfectly. The script above used two Gauss points in each formulation, but you can use any integration rule, including plastic hinge integration. Just be sure to assign nonlinear response to the interior portion of the element. However, once the loading conditions lead to a moment gradient along the element–which is practically always–the two element formulations will give different results for material nonlinear response.