3.1.6.21. NDTest Command

The NDTest command provides a comprehensive suite of testing functions for nDMaterial objects, allowing users to directly manipulate and query material states for testing, validation, and educational purposes. This functionality is particularly useful for material model development, verification, and understanding material behavior under controlled loading conditions.

Warning

These commands are intended for material testing and debugging purposes. They should not be used in regular structural analysis models where materials should be tested through elements.

3.1.6.21.1. Command Syntax

The general syntax for NDTest commands is:

NDTest $command $arguments

Where $command specifies the specific operation to perform on the material, and $arguments are the command-specific parameters.

3.1.6.21.2. Available Commands

The following commands are available within the NDTest framework:

SetStrain

Sets trial strain components on a specified nDMaterial.

NDTest SetStrain $matTag $eps11 $eps22 $eps33 $gamma12 $gamma23 $gamma31

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

$eps11

|double|

Normal strain in direction 1 (ε₁₁)

$eps22

|double|

Normal strain in direction 2 (ε₂₂)

$eps33

|double|

Normal strain in direction 3 (ε₃₃)

$gamma12

|double|

Engineering shear strain γ₁₂

$gamma23

|double|

Engineering shear strain γ₂₃

$gamma31

|double|

Engineering shear strain γ₃₁

Example:

TCL:

# Set a uniaxial strain state
NDTest SetStrain 1 0.001 0.0 0.0 0.0 0.0 0.0

Python:

# Set a uniaxial strain state
op.NDTest("SetStrain", 1, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0)

CommitState

Commits the current trial state of the material, making it the converged state.

NDTest CommitState $matTag

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

Example:

TCL:

NDTest CommitState 1

Python:

op.NDTest("CommitState", 1)

PrintStrain

Prints the current strain state of the material to the OpenSees output stream.

NDTest PrintStrain $matTag

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

PrintStress

Prints the current stress state of the material to the OpenSees output stream.

NDTest PrintStress $matTag

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

GetStrain

Returns the current strain components as a list that can be assigned to a Tcl variable.

set strainList [NDTest GetStrain $matTag]

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

Returns: A list of 6 double values [ε₁₁, ε₂₂, ε₃₃, γ₁₂, γ₂₃, γ₃₁]

Example:

TCL:

set strains [NDTest GetStrain 1]
puts "Strain components: $strains"

Python:

strains = op.NDTest("GetStrain", 1)
print("Strain components:", strains)

GetStress

Returns the current stress components as a list that can be assigned to a Tcl variable.

set stressList [NDTest GetStress $matTag]

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

Returns: A list of 6 double values [σ₁₁, σ₂₂, σ₃₃, τ₁₂, τ₂₃, τ₃₁]

Example:

TCL:

set stresses [NDTest GetStress 1]
puts "Stress components: $stresses"

Python:

stresses = op.NDTest("GetStress", 1)
print("Stress components:", stresses)

GetTangentStiffness

Returns the current tangent stiffness matrix as a flat list of 36 values.

set stiffnessList [NDTest GetTangentStiffness $matTag]

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

Returns: A list of 36 double values representing the 6×6 tangent stiffness matrix in row-major order: [C₁₁, C₁₂, C₁₃, C₁₄, C₁₅, C₁₆, C₂₁, C₂₂, …, C₆₆]

Example:

TCL:

set tangent [NDTest GetTangentStiffness 1]
# Access C11 component
set C11 [lindex $tangent 0]
# Access C26 component
set C26 [lindex $tangent 17]

Python:

tangent = op.NDTest("GetTangentStiffness", 1)
# Access C11 component
C11 = tangent[0]
# Access C26 component
C26 = tangent[17]

GetResponse

Queries the material for custom responses specific to the material type.

set responseList [NDTest GetResponse $matTag $responseType]

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

$responseType

string

Type of response to query (material-dependent)

Returns: A list of double values containing the requested response data.

Common Response Types: (varies by material type) - “stress” - stress components - “strain” - strain components - “tangent” - tangent stiffness - “plasticStrain” - plastic strain components - “backstress” - backstress tensor components - Custom material-specific responses

Example:

TCL:

# Get plastic strain from a plasticity model
set plasticStrain [NDTest GetResponse 1 "plasticStrain"]

# Get damage variable from a damage model
set damage [NDTest GetResponse 1 "damage"]

Python:

# Get plastic strain from a plasticity model
plastic_strain = op.NDTest("GetResponse", 1, "plasticStrain")

# Get damage variable from a damage model
damage = op.NDTest("GetResponse", 1, "damage")

UpdateIntegerParameter

Updates an integer parameter in the material during runtime.

NDTest UpdateIntegerParameter $matTag $paramID $newValue

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

$paramID

integer

Integer parameter identifier (material-specific)

$newValue

integer

New integer value for the parameter

Example:

TCL:

NDTest UpdateIntegerParameter 1 1 0

Python:

op.NDTest("UpdateIntegerParameter", 1, 1, 0)

UpdateDoubleParameter

Updates a double-precision parameter in the material during runtime.

NDTest UpdateDoubleParameter $matTag $paramID $newValue

Argument

Type

Description

$matTag

integer

Unique tag identifying the nDMaterial object

$paramID

integer

Integer parameter identifier (material-specific)

$newValue

|double|

New double value for the parameter

Example:

TCL:

NDTest UpdateDoubleParameter 1 1 2.1e-5

Python:

op.NDTest("UpdateDoubleParameter", 1, 1, 2.1e-5)

3.1.6.21.3. Usage Examples

Complete Material Test Procedure

Here’s a complete example of how to use NDTest commands to test a material:

TCL:

# Create a simple elastic material
nDMaterial ElasticIsotropic 1 200000 0.3

# Test procedure 1: Uniaxial tension
puts "=== Uniaxial Tension Test ==="

# Apply strain increment
NDTest SetStrain 1 0.001 0.0 0.0 0.0 0.0 0.0

# Get and display results
set strains [NDTest GetStrain 1]
set stresses [NDTest GetStress 1]
puts "Strain: $strains"
puts "Stress: $stresses"

# Commit the state
NDTest CommitState 1

# Test procedure 2: Shear test
puts "=== Pure Shear Test ==="
NDTest SetStrain 1 0.0 0.0 0.0 0.002 0.0 0.0
set stresses [NDTest GetStress 1]
puts "Shear stress: $stresses"
NDTest CommitState 1

# Test procedure 3: Get tangent stiffness
puts "=== Tangent Stiffness ==="
set tangent [NDTest GetTangentStiffness 1]
puts "C11 = [lindex $tangent 0]"
puts "C12 = [lindex $tangent 1]"

Python:

import openseespy.opensees as op

# Create a simple elastic material
op.nDMaterial("ElasticIsotropic", 1, 200000, 0.3)

# Test procedure 1: Uniaxial tension
print("=== Uniaxial Tension Test ===")

# Apply strain increment
op.NDTest("SetStrain", 1, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0)

# Get and display results
strains = op.NDTest("GetStrain", 1)
stresses = op.NDTest("GetStress", 1)
print("Strain:", strains)
print("Stress:", stresses)

# Commit the state
op.NDTest("CommitState", 1)

# Test procedure 2: Shear test
print("=== Pure Shear Test ===")
op.NDTest("SetStrain", 1, 0.0, 0.0, 0.0, 0.002, 0.0, 0.0)
stresses = op.NDTest("GetStress", 1)
print("Shear stress:", stresses)
op.NDTest("CommitState", 1)

# Test procedure 3: Get tangent stiffness
print("=== Tangent Stiffness ===")
tangent = op.NDTest("GetTangentStiffness", 1)
print("C11 =", tangent[0])
print("C12 =", tangent[1])

Cyclic Loading Test

TCL:

# Create a material with cyclic behavior
nDMaterial J2Plasticity 1 27 0.3 0.001 300 20.0 0.0

# Cyclic loading parameters
set cycles 5
set maxStrain 0.01
set strainIncrement 0.001

# Apply cyclic loading
for {set cycle 0} {$cycle < $cycles} {incr cycle} {
    puts "Cycle $cycle"

    # Loading
    for {set i 0} {$i <= $maxStrain/$strainIncrement} {incr i} {
        set strain [expr {$i * $strainIncrement}]
        NDTest SetStrain 1 $strain 0.0 0.0 0.0 0.0 0.0
        set stress [lindex [NDTest GetStress 1] 0]
        puts "$strain $stress"
        NDTest CommitState 1
    }

    # Unloading
    for {set i [expr {$maxStrain/$strainIncrement}]} {$i >= 0} {incr i -1} {
        set strain [expr {$i * $strainIncrement}]
        NDTest SetStrain 1 $strain 0.0 0.0 0.0 0.0 0.0
        set stress [lindex [NDTest GetStress 1] 0]
        puts "$strain $stress"
        NDTest CommitState 1
    }
}

Python:

import openseespy.opensees as op

# Create a material with cyclic behavior
op.nDMaterial("J2Plasticity", 1, 27, 0.3, 0.001, 300, 20.0, 0.0)

# Cyclic loading parameters
cycles = 5
max_strain = 0.01
strain_increment = 0.001

# Apply cyclic loading
for cycle in range(cycles):
    print(f"Cycle {cycle}")

    # Loading
    num_steps = int(max_strain / strain_increment)
    for i in range(num_steps + 1):
        strain = i * strain_increment
        op.NDTest("SetStrain", 1, strain, 0.0, 0.0, 0.0, 0.0, 0.0)
        stress = op.NDTest("GetStress", 1)[0]
        print(f"{strain} {stress}")
        op.NDTest("CommitState", 1)

    # Unloading
    for i in range(num_steps, -1, -1):
        strain = i * strain_increment
        op.NDTest("SetStrain", 1, strain, 0.0, 0.0, 0.0, 0.0, 0.0)
        stress = op.NDTest("GetStress", 1)[0]
        print(f"{strain} {stress}")
        op.NDTest("CommitState", 1)

Parameter Study

TCL:

# Create material
nDMaterial ElasticIsotropic 1 200000 0.3

# Study effect of Poisson's ratio
set poissons {0.15 0.20 0.25 0.30 0.35 0.40}

foreach nu $poissons {
    # Update Poisson's ratio
    NDTest UpdateDoubleParameter 1 2 $nu

    # Apply uniaxial strain
    NDTest SetStrain 1 0.001 0.0 0.0 0.0 0.0 0.0

    # Get lateral strain (should be -nu*axial_strain for elastic material)
    set strains [NDTest GetStrain 1]
    set lateralStrain [lindex $strains 1]

    puts "Poisson's ratio: $nu, Lateral strain: $lateralStrain"

    NDTest CommitState 1
}

Python:

import openseespy.opensees as op

# Create material
op.nDMaterial("ElasticIsotropic", 1, 200000, 0.3)

# Study effect of Poisson's ratio
poissons = [0.15, 0.20, 0.25, 0.30, 0.35, 0.40]

for nu in poissons:
    # Update Poisson's ratio
    op.NDTest("UpdateDoubleParameter", 1, 2, nu)

    # Apply uniaxial strain
    op.NDTest("SetStrain", 1, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0)

    # Get lateral strain (should be -nu*axial_strain for elastic material)
    strains = op.NDTest("GetStrain", 1)
    lateral_strain = strains[1]

    print(f"Poisson's ratio: {nu}, Lateral strain: {lateral_strain}")

    op.NDTest("CommitState", 1)

3.1.6.21.4. Implementation Details

The NDTest command framework is implemented in OpenSeesNDTestCommands.cpp and consists of:

Core Components

  1. Command Registration System: Uses a function map to associate command strings with their corresponding handler functions

  2. Material Interface: Interfaces directly with the NDMaterial class hierarchy

  3. Error Handling: Comprehensive error checking and reporting through the OpenSees opserr stream

  4. Data Conversion: Handles conversion between OpenSees internal data structures and Tcl variables

Technical Specifications

Strain/Stress Ordering: All 6-component vectors follow the engineering convention: - Normal components: (ε₁₁, ε₂₂, ε₃₃) or (σ₁₁, σ₂₂, σ₃₃) - Shear components: (γ₁₂, γ₂₃, γ₃₁) or (τ₁₂, τ₂₃, τ₃₁)

Tangent Stiffness Matrix: Returned as a flat array in row-major order for the 6×6 matrix C where: dσ = C : dε (using tensor notation)

Parameter Updates: Parameter IDs are material-specific and typically defined in the material’s documentation or source code.

3.1.6.21.5. Error Handling

The NDTest commands include comprehensive error checking:

  • Material Existence: Verifies the material tag exists before operations

  • Input Validation: Checks for correct number and type of arguments

  • Parameter Validation: Validates parameter ranges where applicable

  • Memory Management: Ensures proper handling of temporary data structures

Common error messages and their meanings:

WARNING too few arguments: NDTest cmd?
# Command requires additional arguments

WARNING NDTest type UnknownCommand is unknown
# Command not recognized

material with tag X does not exist
# Material tag not found in model

need 6 components of floating-point strains
# SetStrain requires exactly 6 strain components

3.1.6.21.6. Best Practices

When using NDTest commands, consider these best practices:

  1. Material Testing: Use for isolated material testing, not in structural analyses

  2. State Management: Always commit states when appropriate to maintain material history

  3. Error Checking: Wrap commands in try-catch blocks when possible

  4. Documentation: Document parameter IDs and response types for custom materials

  5. Performance: Consider performance implications when using in loops

3.1.6.21.7. Integration with Analysis

While NDTest commands are primarily for material testing, they can be integrated with analysis workflows:

  • Pre-analysis Calibration: Calibrate material parameters before main analysis

  • Post-analysis Verification: Verify material states after analysis completion

  • Batch Testing: Automate material testing procedures

  • Educational Use: Demonstrate material behavior concepts

For detailed examples and advanced usage patterns, see NDTest_examples.

3.1.6.21.8. See Also

  • nDMaterial Command - Main nDMaterial command documentation

  • Material Testing Commands - Basic material testing commands

  • NDTest_examples - Comprehensive usage examples

  • Material-specific documentation for available response types and parameter IDs

  • OpenSees examples repository for complete testing procedures