OpenSees Cloud
OpenSees AMI
How to Test a UniaxialMaterial
Input Command
Test all possible input formats as shown in the OPS_MyMaterial
function. Determine which overloaded constructors are called by
issuing these commands. It’s possible that some overloaded constructors
are never called.
Destructor
The destructor is called when an instance of the material goes out of
scope. The destructor cannot be called directly from C++, but you can
guarantee the destructor will be called when you issue the wipe()
command.
Unit Test 1
Call all possible input formats, then call wipe.
For example, with the Elastic material, there are three
possible input formats.
def test_ops():
ops.wipe()
ops.uniaxialMaterial('Elastic',1,E)
ops.uniaxialMaterial('Elastic',2,E,eta)
ops.uniaxialMaterial('Elastic',3,E,eta,Eneg)
ops.wipe()
assert True
There’s nothing to assert here, but are there errors or memory leaks?
Get a Copy
Instead of overloading the copy constructor, OpenSees utilizes the
getCopy() method, allowing calling objects to obtain copies of
materials at will.
UniaxialMaterial *getCopy();
This method is invoked whenever an element, section, or material that uses your material is created.
State Determination
Virtually all elements, sections, and other materials will call the following sequence of methods to obtain the material state during an analysis.
int setTrialStrain(double strain, double strainRate = 0.0);
double getStress();
double getTangent();
Unit Test 2
Create a truss or zero length element. Do an analysis.
from math import isclose
def test_state():
k = 10
P = 2
ops.wipe()
ops.model('basic','-ndm',1,'-ndf',1)
ops.node(1,0); ops.fix(1,1)
ops.node(2,0)
ops.uniaxialMaterial('Elastic',1,k)
ops.element('zeroLength',1,1,2,'-mat',1,'-dir',1)
ops.timeSeries('Linear',1)
ops.pattern('Plain',1,1)
ops.load(2,P)
ops.analysis('Static','-noWarnings')
ops.analyze(1)
u = ops.nodeDisp(2,1)
assert isclose(u,P/k)
ops.reactions()
R = ops.nodeReaction(1,1)
assert isclose(P,-R)
The assertion on displacement doesn’t make much sense if you don’t have a known solution, but does this test produce any errors or memory leaks?
Fiber State Determination
In some specialized cases, e.g., fiber sections, these three methods can be invoked with one call to the following method.
int setTrial(double strain, double &stress, double &tangent, double strainRate = 0.0);
To ensure this method is invoked on your material, do an analysis with fiber sections. And if you want analyses with fiber sections comprised of Concrete23 to run faster, override the default behavior by implementing this method.
Unit Test 3
Create a fiber section and zero length section element. Do an analysis.
Initial Tangent
double getInitialTangent();
Will be called during an analysis where the initial stiffness is used,
e.g., using the Newton algorithm with the -initialThenCurrent
option.
Damping Tangent
double getDampTangent();
Won’t be called unless your material overrides the default implementation.
History Variables
int commitState();
Invoked upon convergence of the equilibrium solution at a time step. There’s no way to test this method other than to force your material to yield under cyclic loading, e.g., half-cycle sine pulse and make sure the initial and final displacement are not the same.
int revertToLastCommit();
Invoked when you switch algorithms or reduce a time step after the equilibrium solution fails at a time step. Two successive failed analyses with the same time step should produce the same residual.
int revertToStart();
Invoked when the analysis is reset via the reset() command. Two
repeated analyses should produce the same result. You may have to do
many repetitions to see errors, e.g., SAWS.
Send and Receive Methods
The following methods are called during parallel processing and when the
save and restore commands are issued.
int sendSelf(int commitTag, Channel &theChannel);
int recvSelf(int commitTag, Channel &theChannel,
FEM_ObjectBroker &theBroker);
Do an analysis, create a database, save to database, then analyze another step and save the result. Wipe the model, restore from database, analyze one step and should get the same result.
Default Constructor
The default constructor may be called implicitly in
various scenarios throughout OpenSees, but the default constructor
will definitely be called by an FEM_ObjectBroker when
issuing the restore() command.
It is good practice for the default constructor to initialize all private data.
Set and Get Response
Most materials use the default methods for recorders and the
eleResponse command; however some materials override the defaults in
order to get specialized information.
Response *setResponse(const char **argv, int argc,
OPS_Stream &theOutputStream);
int getResponse(int responseID, Information &matInformation);
For the Elastic material, we have the defaults
ops.eleResponse(1,...,'material','stress')
ops.eleResponse(1,...,'material','strain')
ops.eleResponse(1,...,'material','tangent')
ops.eleResponse(1,...,'material','plasticStrain')
ops.eleResponse(1,...,'material','stressStrain')
ops.eleResponse(1,...,'material','stressANDstrain')
ops.eleResponse(1,...,'material','stressAndStrain')
ops.eleResponse(1,...,'material','stressStrainTangent')
ops.eleResponse(1,...,'material','stressANDstrainANDtangent')
ops.eleResponse(1,...,'material','TempElong')
ops.eleResponse(1,...,'material','tempANDelong')
ops.eleResponse(1,...,'material','energy')
ops.eleResponse(1,...,'material','Energy')
Set and Update Parameters
Some materials allow calling objects to update internal parameter values.
int setParameter(const char **argv, int argc, Parameter ¶m);
int updateParameter(int parameterID, Information &info);
For the Elastic material, we have
ops.parameter(1,...,'material','E')
ops.parameter(2,...,'material','Epos')
ops.parameter(3,...,'material','Eneg')
ops.parameter(4,...,'material','eta')
I work on problems related to modeling and nonlinear structural analysis. If these problems are relevant to a current professional project, feel free to reach out.