| name | ifc-syntax-units |
| description | Use when you need to declare, read, or debug the units of an IFC model : the project unit assignment, SI units with a prefix (millimetre = METRE + MILLI), imperial units via a conversion factor, compound units like velocity, monetary currency, and how a property value resolves to a concrete unit. Prevents a model that is off by 1000x because millimetres were declared as metres, a duplicate unit type that breaks the WR01 rule, inventing a separate "millimetre" unit name, and embedding a currency string in a numeric value. Covers IfcUnitAssignment, IfcSIUnit, IfcConversionBasedUnit and the WithOffset subtype, IfcDerivedUnit with IfcDerivedUnitElement, IfcContextDependentUnit, IfcMonetaryUnit, IfcMeasureWithUnit, the unit-propagation chain, and IFC2x3 / IFC4 / IFC4.3 version differences. Keywords: IFC units, IfcUnitAssignment, IfcSIUnit, IfcSIPrefix, IfcSIUnitName, IfcConversionBasedUnit, IfcDerivedUnit, IfcDerivedUnitElement, IfcContextDependentUnit, IfcMonetaryUnit, IfcMeasureWithUnit, IfcUnitEnum, IfcDerivedUnitEnum, millimetre, UnitsInContext, WR01, my model is off by 1000x, model too big or too small, wrong scale, how do I set units, what unit is this value, currency, IFC2x3, IFC4, IFC4.3.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IFC IFC2x3, IFC4, IFC4.3. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
IFC Syntax : Units
An IFC model declares its units once, at the project level, and every measure value
rides on that declaration. This skill covers the unit entities, how they are
assembled, and how a property value resolves to a concrete unit.
Applies to IFC2x3, IFC4, and IFC4.3. One entity changed type across versions :
see the Version Differences section.
Quick Reference
The project unit assignment
IfcUnitAssignment is the project-global unit set. Verified verbatim (IFC4.3) :
ENTITY IfcUnitAssignment;
Units : SET [1:?] OF IfcUnit;
WHERE
WR01 : IfcCorrectUnitAssignment(Units);
END_ENTITY;
It is referenced by IfcContext (the supertype of IfcProject) through the
attribute UnitsInContext. The WR01 rule enforces that each unit type appears
only once : one length unit, one area unit, one monetary unit, and so on.
ALWAYS attach exactly one IfcUnitAssignment to the project via UnitsInContext.
NEVER place two units of the same type in it : that breaks WR01.
The IfcUnit select tree
IfcUnit is the select that every unit slot accepts :
IfcUnit (SELECT)
├── IfcNamedUnit (abstract) attributes : Dimensions, UnitType (IfcUnitEnum)
│ ├── IfcSIUnit an SI unit, optionally prefixed
│ ├── IfcConversionBasedUnit a non-SI unit defined by a conversion factor
│ │ └── IfcConversionBasedUnitWithOffset adds a ConversionOffset
│ └── IfcContextDependentUnit a unit with no SI conversion (context-defined)
├── IfcDerivedUnit a compound unit built from exponents
└── IfcMonetaryUnit a currency
IfcSIUnit
Verified verbatim (IFC4.3), IfcSIUnit is a subtype of IfcNamedUnit :
ENTITY IfcSIUnit
SUBTYPE OF (IfcNamedUnit);
Prefix : OPTIONAL IfcSIPrefix;
Name : IfcSIUnitName;
DERIVE
SELF\IfcNamedUnit.Dimensions : IfcDimensionalExponents
:= IfcDimensionsForSIUnit (SELF.Name);
END_ENTITY;
Name is an IfcSIUnitName enumeration value (29 values : METRE,
SQUARE_METRE, CUBIC_METRE, GRAM, SECOND, RADIAN, NEWTON, PASCAL,
WATT, DEGREE_CELSIUS, ...).
Prefix is an optional IfcSIPrefix enumeration value (16 values : KILO,
MILLI, MICRO, CENTI, DECI, MEGA, GIGA, ...).
Dimensions is DERIVED : it is computed from Name, NEVER serialized.
UnitType is inherited from IfcNamedUnit and is an IfcUnitEnum value.
A millimetre is Name = METRE with Prefix = MILLI. ALWAYS express a metric scale
with the Prefix enumeration. NEVER invent a MILLIMETRE name : there is no such
IfcSIUnitName value.
Full enum lists : see references/methods.md.
IfcConversionBasedUnit
For a non-SI unit (inch, foot, pound) defined by a conversion from an SI unit.
Subtype of IfcNamedUnit. Attributes : Name (IfcLabel), ConversionFactor
(IfcMeasureWithUnit). An inch is a ConversionFactor of 25.4 expressed in
millimetres.
IfcConversionBasedUnitWithOffset is a subtype that adds ConversionOffset
(IfcReal), applied after the factor. It exists for temperature scales such as
Fahrenheit, where a conversion needs both a factor and an offset.
IfcDerivedUnit and IfcDerivedUnitElement
For a compound unit built from products and quotients of other units. Verified
verbatim (IFC4.3) :
ENTITY IfcDerivedUnit;
Elements : SET [1:?] OF IfcDerivedUnitElement;
UnitType : IfcDerivedUnitEnum;
UserDefinedType : OPTIONAL IfcLabel;
Name : OPTIONAL IfcLabel;
DERIVE
Dimensions : IfcDimensionalExponents := IfcDeriveDimensionalExponents(Elements);
WHERE
WR1 : (SIZEOF (Elements) > 1) OR
((SIZEOF (Elements) = 1) AND (Elements[1].Exponent <> 1));
WR2 : (UnitType <> IfcDerivedUnitEnum.USERDEFINED) OR
((UnitType = IfcDerivedUnitEnum.USERDEFINED) AND
(EXISTS(SELF.UserDefinedType)));
END_ENTITY;
Each IfcDerivedUnitElement pairs a Unit with an Exponent (INTEGER). A linear
velocity is a length unit with exponent 1 plus a time unit with exponent -1.
UnitType is an IfcDerivedUnitEnum value (52 values : LINEARVELOCITYUNIT,
MASSDENSITYUNIT, THERMALTRANSMITTANCEUNIT, ACCELERATIONUNIT, TORQUEUNIT,
USERDEFINED, ...). When UnitType = USERDEFINED, UserDefinedType is required by
WR2.
IfcContextDependentUnit and IfcMonetaryUnit
IfcContextDependentUnit : a named unit with no conversion to SI, defined by
context (subtype of IfcNamedUnit).
IfcMonetaryUnit : carries a currency. In IFC4 and IFC4.3 its Currency
attribute is an IfcLabel holding a three-letter ISO 4217 code (EUR, USD,
GBP). In IFC2x3 Currency was an IfcCurrencyEnum enumeration. See the
Version Differences section.
IfcMeasureWithUnit : pairing a value with a unit
IfcMeasureWithUnit pairs one value with one unit. Attributes : ValueComponent
(IfcValue, the magnitude) and UnitComponent (IfcUnit, the unit). It is the
bridge entity used inside IfcConversionBasedUnit.ConversionFactor and anywhere a
single value must explicitly carry its own unit.
The unit-propagation chain
A measure value almost never carries its unit inline. The unit is resolved through a
chain :
A property value (IfcPropertySingleValue.NominalValue)
carries a MEASURE TYPE (for example IfcLengthMeasure)
|
v
The measure type maps to a UNIT TYPE (IfcUnitEnum, for example LENGTHUNIT)
|
v
The project IfcUnitAssignment holds exactly ONE unit per unit type
|
v
That unit is the value's unit -- UNLESS the property's own Unit
attribute (an IfcUnit) overrides it locally.
ALWAYS resolve a value's unit through this chain. NEVER assume a bare number is in
metres : the measure type plus the project IfcUnitAssignment give it a unit.
Version differences (compact)
| Item | IFC2x3 | IFC4 | IFC4.3 |
|---|
IfcMonetaryUnit.Currency type | IfcCurrencyEnum (enum) | IfcLabel (ISO 4217 string) | IfcLabel |
IfcConversionBasedUnit.HasExternalReference inverse | absent | present | present |
IfcConversionBasedUnitWithOffset | absent | present | present |
Decision Trees
Which unit entity for a given unit?
What kind of unit do you need?
|
+-- A pure SI unit (metre, gram, second, newton, pascal)
| --> IfcSIUnit. Use Prefix for a scale (MILLI, KILO).
|
+-- A non-SI unit with a fixed conversion (inch, foot, pound)
| --> IfcConversionBasedUnit. ConversionFactor is an IfcMeasureWithUnit.
| Needs an offset too (Fahrenheit)? --> IfcConversionBasedUnitWithOffset.
|
+-- A compound unit (velocity, density, U-value)
| --> IfcDerivedUnit with one IfcDerivedUnitElement per factor.
|
+-- A currency
| --> IfcMonetaryUnit.
|
+-- A unit with no SI conversion, defined only by project context
--> IfcContextDependentUnit.
How does a value get its unit?
Does the property carry an explicit Unit attribute?
|
+-- YES --> that explicit IfcUnit is the value's unit (local override).
|
+-- NO --> the value's measure type selects an IfcUnitEnum unit type;
the project IfcUnitAssignment holds the one unit of that type;
that unit applies.
Millimetre : prefix or new name?
Need millimetres / centimetres / kilometres?
|
+-- ALWAYS : IfcSIUnit with Name = METRE and Prefix = MILLI / CENTI / KILO.
|
+-- NEVER : there is no MILLIMETRE, CENTIMETRE, or KILOMETRE in IfcSIUnitName.
Inventing one is not a valid enumeration value.
Patterns
Pattern : Declare one IfcUnitAssignment per project
ALWAYS attach exactly one IfcUnitAssignment to the project through
IfcContext.UnitsInContext. Populate its Units set with one unit per unit type
the model uses : a length unit, an area unit, a volume unit, a plane-angle unit, and
so on.
NEVER place two units of the same unit type in one IfcUnitAssignment : the WR01
rule (IfcCorrectUnitAssignment) rejects a duplicate unit type and the file is
schema-invalid.
ALWAYS declare every unit type the model's measure values need : a value whose unit
type is absent from the assignment cannot be resolved.
See ifc-core-spatial-structure for IfcProject and UnitsInContext.
Pattern : Express a metric scale with the prefix
ALWAYS express millimetres, centimetres, and kilometres as IfcSIUnit with
Name = METRE and the Prefix enumeration (MILLI, CENTI, KILO). The same
holds for other quantities : a square millimetre is Name = SQUARE_METRE,
Prefix = MILLI.
NEVER write a Name value that is not in the 29-value IfcSIUnitName enumeration.
MILLIMETRE is not a valid name ; METRE plus Prefix = MILLI is the only correct
form.
Pattern : Express a non-SI unit via a conversion
ALWAYS model a non-SI unit (inch, foot, pound) as an IfcConversionBasedUnit whose
ConversionFactor is an IfcMeasureWithUnit : the magnitude plus the SI unit it
converts from. An inch is 25.4 paired with a millimetre IfcSIUnit.
ALWAYS use IfcConversionBasedUnitWithOffset when the conversion needs an offset as
well as a factor : a Fahrenheit scale needs both. Its ConversionOffset (IfcReal)
is applied after the inherited factor.
Pattern : Build a compound unit
ALWAYS build a compound unit as an IfcDerivedUnit whose Elements set holds one
IfcDerivedUnitElement per factor, each pairing a Unit with an INTEGER
Exponent. A linear velocity is a length unit at exponent 1 and a time unit at
exponent -1.
ALWAYS set UserDefinedType when UnitType = IfcDerivedUnitEnum.USERDEFINED : the
WR2 rule requires it.
NEVER write a single-element IfcDerivedUnit whose one element has exponent 1 :
the WR1 rule forbids it (such a unit is just the base unit, not a derived one).
Pattern : Resolve a value's unit through the propagation chain
ALWAYS resolve the unit of a measure value through the chain : measure type to unit
type, unit type to the project IfcUnitAssignment, unless an explicit Unit
attribute on the property overrides it.
ALWAYS treat an explicit Unit on a property as a local override of the project-
global unit for that one property only.
NEVER assume a bare numeric value is in metres, millimetres, or any specific unit
without resolving it : the number is unit-agnostic.
See ifc-syntax-data-types for measure types and ifc-syntax-property-sets for the
property entities that carry the Unit attribute.
Pattern : Honour the version differences
ALWAYS write IfcMonetaryUnit.Currency as an IfcLabel (an ISO 4217 string such as
'EUR') in IFC4 and IFC4.3.
ALWAYS write IfcMonetaryUnit.Currency as an IfcCurrencyEnum value in IFC2x3 : in
that version the attribute was a fixed enumeration, not a free string.
NEVER carry a currency inside a monetary value : IfcMonetaryMeasure is a bare
number, and IfcMonetaryUnit carries the currency separately.
Reference Links
references/methods.md : the complete verified entity definitions, the full
IfcUnitEnum (30 values), IfcDerivedUnitEnum (52 values), IfcSIUnitName
(29 values), IfcSIPrefix (16 values), the IfcUnit select, and the per-version
difference table.
references/examples.md : worked STEP scenarios : a unit assignment, a millimetre
unit, an inch conversion unit, a velocity derived unit, a Fahrenheit offset unit,
a monetary unit, and reading a value through the propagation chain.
references/anti-patterns.md : the failure modes this skill prevents, each with
the reason it fails.
Official sources
Related skills
ifc-syntax-data-types : measure types and how a measure type implies a unit type.
ifc-syntax-property-sets : the property entities whose Unit attribute overrides
the project-global unit.
ifc-errors-property-set-mistakes : the unit-related failure modes in real models.