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:
| Code | Length | Force |
|---|---|---|
| 0 | Inch | Kilopound |
| 1 | Feet | Pound |
| 2 | Feet (same as 1) | Kilogram |
| 3 | CentiMeter | Metric Ton |
| 4 | Meter | Newton |
| 5 | MilliMeter | KiloNewton |
| 6 | DeciMeter | MegaNewton |
| 7 | KiloMeter | DecaNewton |
Length code
2is listed upstream as a duplicate ofFeet, and testing confirms it: with English base units,SetInputUnitForLength(2)makesGetInputUnitForLength()return"Feet", and a node sent atx = 1comes back as12.0in. Use1for feet and ignore2.
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 value | Input units at send time | Returned (in / kip) |
|---|---|---|
| Node x = 120 | in / kip | 120.0 in |
| Node x = 3.048 | m / kN | 119.99976 in |
| Nodal FY = −10, MZ = 100 | in / kip | −10.0 kip, 100.0 kip·in |
| Nodal FY = −10, MZ = 10 | m / kN | −2.24809 kip, 88.5073 kip·in |
| UDL w = −0.5 | in / kip | −0.5 kip/in |
| UDL w = −2 | m / kN | −0.01142 kip/in |
| Conc. P = −5 at d1 = 60 | in / kip | −5.0 kip at 60.0 in |
| Conc. P = −5 at d1 = 1.5 | m / 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,GetInputUnitForLengthandGetInputUnitForForce.