OpenSees Cloud
OpenSees AMI
Dangling Recorders
Original Post - 21 Nov 2024 - Michael H. Scott
Visit Structural Analysis Is Simple on Substack.
Because I don’t perform very large or time-consuming OpenSees analyses,
I use recorders rather infrequently, instead preferring commands like
nodeDisp
and eleResponse
.
An issue with node and element recorders is they can segmentation fault after the node or element to which they point is removed from a model–a common scenario for progressive collapse simulations.
A potential segmentation fault is not why I don’t use recorders. It’s more that OpenSeesPy mitigates the need to pump data from OpenSees.exe to MATLAB or Excel or whatever for post-processing.
But run the following script and see what happens–hopefully not the blue screen of death.
import openseespy.opensees as ops
ops.wipe()
ops.model('basic','-ndm',1,'-ndf',1)
ops.node(0,0); ops.fix(0,1)
ops.node(1,0)
ops.node(2,0)
ops.uniaxialMaterial('Elastic',1,600)
ops.element('zeroLength',1,0,1,'-mat',1,'-dir',1)
ops.element('zeroLength',2,1,2,'-mat',1,'-dir',1)
ops.element('zeroLength',3,0,2,'-mat',1,'-dir',1)
ops.timeSeries('Linear',1)
ops.pattern('Plain',1,1)
ops.load(1,300)
ops.recorder('Element','-file','ele1force.out','-ele',1,'force')
ops.recorder('Element','-file','ele2force.out','-ele',2,'force')
ops.recorder('Element','-file','ele2defo.out','-ele',2,'deformation')
ops.analysis('Static','-noWarnings')
ops.analyze(1)
ops.remove('element',2)
ops.analyze(1)
After element 2 is removed from the model–and deleted from memory–the recorders that once pointed to element 2 now point to some unused data segment (dangling pointers). Then, when a subsequent analyze command hits the recording phase, there will be a segmentation fault.
Within OpenSees, as far as I know, there is no easy fix to this issue.
But fortunately,
the recorder
command returns a tag,
so there are some easy scripting workarounds.
One workaround is to define a dictionary whose keys are element tags and whose values are lists of recorder tags that point to the element.
When you define a recorder, append its tag to the list for that element. Then, when you remove an element, iterate through the list of recorder tags and remove the removed element’s recorders before you go to the next analysis step.
#
# Define your model
#
recorderTags = dict()
for ele in ops.getEleTags():
recorderTags[ele] = []
recorderTags[1].append(ops.recorder('Element','-file','ele1force.out','-ele',1,'force'))
recorderTags[2].append(ops.recorder('Element','-file','ele2force.out','-ele',2,'force'))
recorderTags[2].append(ops.recorder('Element','-file','ele2defo.out','-ele',2,'deformation'))
ops.analysis('Static','-noWarnings')
ops.analyze(1)
ops.remove('element',2)
for recorder in recorderTags[2]:
ops.remove('recorder',recorder)
ops.analyze(1)
Other workarounds are possible once you are aware that the recorder
command returns a tag. And not just element recorders, node recorders
also return a tag. Envelope recorders too. All recorders return a tag.