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 &param);
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.