How to Record Fiber Response

Recording the response of a single fiber in a fiber section is a common ask. You will need to use an Element recorder, but what you can record in each fiber is defined in the UniaxialMaterial::setResponse() method. The most common option is 'stressStrain', which gives the fiber stress-strain response history.

After setResponse() drills down to the section level, there are three options to specify the fiber whose response you would like to record.

1. Fiber index – Let’s get this option out of the way. You can specify the index (from the internal array of material pointers; 0,…,Nf-1) of the fiber you want to record.

...,'fiber',fiberIndex,'stressStrain')

Although I’m pretty sure I coded this option, I don’t know how anyone would know the index of a particular fiber. Perhaps this was a useful option for debugging?

2. Fiber closest to a section coordinate – You can ask the recorder to find the fiber closest to section coordinates that you specify.

...,'fiber',y,z,'stressStrain')

The section yz axes are shown below.

3. Fiber with a specified material tag closest to a section coordinate – Just like option 2, but restricts the search to only fibers with the specified material tag. This option is useful for sections with overlapping fibers, e.g., steel and concrete fibers in a reinforced concrete section, where you want to be sure you get the correct fiber.

...,'fiber',y,z,matTag,'stressStrain')

The same three options are available for FiberSection2d and 3d as well as NDFiberSection2d and 3d.

What comes before 'fiber' depends on the element. For zero length section elements, which are convenient for moment-curvature and axial-moment interaction analysis, you input 'section', 'fiber', and then one of the three options shown above.

ops.recorder('Element','-ele',1,'-file','fiber.out','section','fiber',...)

For the beam-column elements (displacement-based, force-based, and mixed), you can specify a section (integration point) number (1,…,Np; in sequence from node I to node J) and then give the fiber arguments.

ops.recorder('Element','-ele',1,'-file','fiber.out','section',secNum,'fiber',...)

A lesser known, but more direct, option is to find the section closest to a specified x-coordinate (0 to L from node I to node J) along a beam-column element.

ops.recorder('Element','-ele',1,'-file','fiber.out','sectionX',x,'fiber',...)

For the sake of demonstration, we’ll do moment-curvature analysis of an RC section with a single layer of longitudinal steel reinforcement.

Using a zeroLengthSection element with displacement control on the nodal rotation, we know the curvature is the nodal rotation and the moment is the load factor. The model uses basic material models–Concrete01 with standard inputs for compressive and spalling strains, and EPP Steel01–for the fibers.

import openseespy.opensees as ops

kip = 1.0
inch = 1.0

ft = 12*inch
ksi = kip/inch**2

fc = 4*ksi
fy = 60*ksi
E = 29000*ksi

Abar = 0.79*inch**2

h = 24*inch
b = 16*inch

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

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

ops.uniaxialMaterial('Concrete01',1,fc,0.002,0,0.006)
ops.uniaxialMaterial('Steel01',2,fy,E,0)

ops.section('Fiber',1)
ops.patch('rect',1,20,1,-h/2,-b/2,h/2,b/2)
ops.layer('straight',2,3,Abar,-h/2+2.5*inch,b/2-2.5*inch,-h/2+2.5*inch,-b/2+2.5*inch)

ops.element('zeroLengthSection',1,1,2,1)

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

Ky = 0.003/(h/2) # ballpark estimate of yield curvature
ops.integrator('DisplacementControl',2,3,Ky/100)

ops.analysis('Static')

epsc = 0
while epsc > -0.003:
    ops.analyze(1)
    epsc = ops.nodeDisp(2,1) - h/2*ops.nodeDisp(2,3)

ops.wipe()

The analysis stops when the strain at the compression face reaches 0.003. Note that the strain in the extreme compression fiber will be a little less than 0.003 because the strain is sampled at the center of the fiber.

The resulting moment-curvature response is shown below.

With the Whitney stress block (WSB) approximation, the nominal moment strength should be 239.3 kip-ft. The load factor reported by OpenSees is 239.5 kip-ft. For reinforced concrete, that is exact. You can also use the displacements of node 2 to determine the depth to the neutral axis, which also matches the WSB approximation.

Now, let’s define three fiber recorders: A – fiber closest to compression face (y=h/2); B – fiber closest to tension face (y=-h/2); and C – steel fiber closest to tension face.

For 2D problems, bending is about the z-axis, so only the y-coordinate matters when specifying the fiber location. The recorder ignores the z-coordinate, but you still have to input something in its place–0 is perfectly fine.

# Compression fiber
ops.recorder('Element','-ele',1,'-file','fiberA.out','section','fiber',h/2,0,'stressStrain')
# Tension fiber
ops.recorder('Element','-ele',1,'-file','fiberB.out','section','fiber',-h/2,0,'stressStrain')
# Tension fiber - steel
ops.recorder('Element','-ele',1,'-file','fiberC.out','section','fiber',-h/2,0,2,'stressStrain')

The stress-strain response from each fiber is shown below

Fiber A shows the concrete stress-strain response in compression; fiber B shows the concrete tension response (zero stress); and fiber C shows the EPP response of the reinforcing steel.


Let me know if you run into any problems recording fiber response. There’s been some changes in the code lately that could have temporarily broken this functionality.

20 thoughts on “How to Record Fiber Response

  1. Seems like my build of Release 13 (OpenSees Version 3.3.0–May 18) does not take the ‘matTag’ option.

    The following recorder worked fine in the OpenSeesPy Version 3.3.0.0 (6/4/2021) but doesn’t record anything now.

    ops.recorder(‘Element’, ‘-file’, ‘ConTStressStrain.txt’,’-ele’, 1,’section’, ‘fiber’, str(Dia/2), str(0), str(ConMatTag),’stressStrain’);

    The following code (according to your example) also doesn’t record anything.
    ops.recorder(‘Element’, ‘-ele’, 1,’-file’, ‘ConTStressStrain.txt’, ‘section’, ‘fiber’, Dia/2, 0, ConMatTag,’stressStrain’);

    But the recorder seems to work without the material tag in this code. Am I missing something here?

    And if the code has been changed, what files should I add from the current repository?

    Thank you.

    Like

      1. It is very nice to see this, because I am dealing with the same problem. I am using OpenSees 3.3.0 not OpenSeesPY. I am doing seismic analysis of utility tunnel (box shape in section), and simplify it as soil spring-beam. I use to define the section (including core concrete, steel bar and cover concrete). I want to record of core concrete, steel bar and cover concrete at specified location. Codes are attached bellow:
        recorder Element -file F-PpipeLine_5008.out -time −ele 3005 section 1 fiber 0.5 0.5 3022 stressStrain ;(I can only get time series by using this)
        recorder Element -file $dataDir/D-pipe_Example2.out -time -ele 3005 section 1 deformation;(I can get perfect data(axial deformation and curvature) by using this)

        I have see this page but I doesn’t work in OpenSees. https://portwooddigital.com/2020/08/14/recorders-not-recording/
        set Numsec 1;
        set y 0.5;
        set z 0.5;
        recorder Element -file F-PpipeLine_3005.out −ele 3005 section $Numsec fiber $y $z 3022 stressStrain ;

        Many thanks!

        Like

  2. I am trying to record the stress strain response of column fiber section in openseespy for the pushover analysis of single bay single storey RC structure. I am using element recorder for that. However I am getting a single column of data in output file and I am not sure if it is stress or strain. While plotting the single column data in excel, the shape resembles the pushover curve. How can the stress strain response of concrete fiber look like a pushover curve? For the stress strain response, Shouldn’t we get the two columns- one for stress and another for strain?

    Like

  3. Hi prof Scott.
    Thanks for this awesome site.

    I am trying to get the moment-curvature relation for the RC section with unbonded post-tensioned (UPT) bars. The thing is that the axial force increases with the increase of curvature due to the elongation of the UPT bar. The force on the UPT bar will depend on the length of the bar itself and the deflection profile.
    Does this mean that I can not get the moment-curvature for this section and I need to get the pushover behaviour for this member and then the moment-curvature relation? Based on your experience, do you have any other method I can try?

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.