Input Units: the units OpenStaad reads from you

Every number your script sends to OpenSTAAD — a node coordinate in CreateNode, a load in AddNodalLoad, a distributed force in AddMemberUniformForce — is interpreted in the model's input units: whatever the model's current UNIT command says, such as UNIT MMS KN or UNIT FEET KIP. Unlike base units, your script can read them and change them.

Getting this wrong is silent. Send 3.048 while the input length unit is meters and you have a 3.048 m node; send the same number while it is millimeters and you have a 3 mm one. Nothing raises, nothing warns.

This page is only about input units, the set side. For the units of values you get back, see Base Units; for how the two fit together, see Unit Systems.


Reading the input units

from openstaad import ops

s = ops.connect()

print(s.GetInputUnitForLength())    # e.g. "Meter"
print(s.GetInputUnitForForce())     # e.g. "KiloNewton"

Read them before sending anything. They are a property of the open model's current UNIT command, so they can differ from what you expect if the model was authored, or last changed, by someone else.

Input units are independent of base units. A session can have English base units and metric input units at the same time: reads come back in inches while writes are taken as meters. A model can be authored in UNIT METER KN, show meters everywhere in the STAAD.Pro interface, and still return inches through OpenSTAAD, because its base unit is English. This is working as designed.


Setting the input units

SetInputUnits() sets length and force together; SetInputUnitForLength() and SetInputUnitForForce() set one at a time. All three take integer codes:

CodeLengthForce
0InchKilopound
1FeetPound
2Feet (same as 1)Kilogram
3CentiMeterMetric Ton
4MeterNewton
5MilliMeterKiloNewton
6DeciMeterMegaNewton
7KiloMeterDecaNewton

Length code 2 is listed upstream as a duplicate of Feet, and testing confirms it: with English base units, SetInputUnitForLength(2) makes GetInputUnitForLength() return "Feet", and a node sent at x = 1 comes back as 12.0 in. Use 1 for feet and ignore 2.

s.SetInputUnits(4, 5)                 # Meter, KiloNewton
print(s.GetInputUnitForLength())      # -> "Meter"
print(s.GetInputUnitForForce())       # -> "KiloNewton"

SetInputUnits changes what you send, not what you get back

They change how values you write are interpreted, and how the model displays them. They do not touch how values you read look, but they are not harmless — every value you send after calling them is taken in the new units, silently:

# English base units; input units set to Meter, KiloNewton
s.SetInputUnits(4, 5)
s.GetNodeCoordinates(2)               # (120.0, 0, 0): still inches (base)
s.CreateNode(3, 3.048, 0, 0)          # 3.048 is taken as METERS
s.GetNodeCoordinates(3)               # (119.99976, 0, 0): returned in inches

If you need values back in a different unit, no input-unit setting will do it: convert them yourself. See Base Units.


Derived quantities you send

The same rule holds for derived quantities. A distributed load sent as -2 with input units m/kN is stored and returned as -0.01142 kip/in in an English-base model, because -2 kN/m is -0.01142 kip/in.

What we measured (STAAD.Pro 2025 25.0.1.424, openstaad 0.0.15), with English base units:

Sent valueInput units at send timeReturned (in / kip)
Node x = 120in / kip120.0 in
Node x = 3.048m / kN119.99976 in
Nodal FY = −10, MZ = 100in / kip−10.0 kip, 100.0 kip·in
Nodal FY = −10, MZ = 10m / kN−2.24809 kip, 88.5073 kip·in
UDL w = −0.5in / kip−0.5 kip/in
UDL w = −2m / kN−0.01142 kip/in
Conc. P = −5 at d1 = 60in / kip−5.0 kip at 60.0 in
Conc. P = −5 at d1 = 1.5m / kN−1.124 kip at 59.055 in

The same model with Metric base units returns each value in m / kN, whichever input units it was sent in: a UDL sent as -0.5 in kip/in reads -87.56342 kN/m, and one sent as -2 in kN/m reads -2.0 kN/m. Every returned value was identical whether it was read with input units set to in/kip or to m/kN: input units never change what you read.


Align input units with base units before writing

The simplest safe habit is to set the input units to match the base units before writing, so sent and returned values share one system:

if s.GetBaseUnit() == "English":
    s.SetInputUnits(0, 0)   # Inch, Kilopound
else:
    s.SetInputUnits(4, 5)   # Meter, KiloNewton

If you change them for a while, put them back. Anything else that writes to the same session, or the next script, inherits whatever you left.

A precision note: when STAAD returns a value in inches that was sent in meters, it converts with 39.37 in/m, not the exact 1 / 0.0254. The result is off in the 6th significant digit — 3.048 m returns as 119.99976 in, not 120. The opposite direction (in → m) and every force conversion were exact in testing. Values written under one input unit and read after a base-unit switch came back exact, which suggests STAAD keeps each value in the units it was sent in and converts when it returns it. Compare round-tripped values with a tolerance, never with ==.


Checklist

  • Read GetInputUnitForLength() / GetInputUnitForForce() before sending values; every sent value is interpreted in those units.
  • Prefer aligning input units with base units before writing.
  • Never assume SetInputUnits() is harmless: it changes how all later writes are interpreted, even though it leaves already-read values untouched.
  • Restore the input units you found if you change them for one operation.
  • Compare round-tripped values with a tolerance — STAAD converts length with 39.37 in/m, not the exact inverse of 0.0254.

Further reading

  • Unit Systems — how base units and input units work together.
  • Base Units — the units of every value you get back.
  • SetInputUnits — the function reference, alongside SetInputUnitForLength, SetInputUnitForForce, GetInputUnitForLength and GetInputUnitForForce.