buildingSMART / buildingSMART/bSDD
Units that combine two parts (like 'kg CO2 eq/m²' or 'EUR/m²')
- Dominant language
- Python
- Stars
- 193
- Forks
- 45
- PR merge metrics
- No merged PRs in 30d
Description
## Related
#138 a related structural question.
#140 which requests specific base units missing from the table.
This issue is about *how* units like these should be modelled, not which specific ones to add.
## The problem
A unit like `kg CO2 eq/m²` is really two things joined with a slash:
- `kg CO2 eq`: what's being measured (a mass of CO2 equivalent).
- `/m²`: what it's measured *per* (per square meter of something).
Today the bSDD canonical `Units` table stores the whole joined string `kg CO2 eq/m²` as a single entry. For most physics units (like `W/m²K` or `kg/m³`) that works fine: there's a finite list and each string is unique.
But for some kinds of properties, the "per-what" part depends on how the property is used:
- Lifecycle GWP: `kg CO2 eq/m²`, `kg CO2 eq/m³`, `kg CO2 eq/kg`, ...
- Cost: `EUR/m²`, `EUR/m³`, `CHF/m²`, `CHF/m³`, `USD/m²`, `USD/m³`, ...
- Annualised versions of the above add a further `/a`.
So covering ~10 currencies × 3 spatial measures (m, m², m³) already means 30 separate entries **just for the currency family**, and the table grows whenever a new currency comes up. That's the pattern I want to avoid.
## How I hit this
Publishing [DOKwood v0.9](https://identifier.buildingsmart.org/uri/hm/dokwood/0.9) I had several properties whose unit wasn't in the canonical table. The workaround was:
- storing only the front half of the unit in the `Unit` field (e.g. `kg CO2 eq` instead of `kg CO2 eq/m²`), and
- writing a sentence in the property's `Definition` text to describe the missing half ("…per m² of assembly area…").
That works for a person reading the property, but it breaks for software. Each consumer now has to keep a separate lookup keyed by property ID just to recover what the real unit is, which is exactly what a canonical `Unit` field is supposed to prevent.
## Looking at how others solves this
[BHoM](https://github.com/BHoM/BHoM) stores the two halves of the unit in two separate fields instead of one joined string:
- The unit field holds only the front half, e.g. `"kg CO2 eq"`.
- A second field, `QuantityType`, holds the "per-what" as a short enum, one of `{Area, Volume, Mass, Energy, Item, Length, …}` ([QuantityType.cs](https://github.com/BHoM/BHoM/blob/main/LifeCycleAssessment_oM/Enums/QuantityType.cs)).
- When software needs to *display* `kg CO2 eq/m²` to a user, it reads both fields and joins them at display time ([ClimateChangePerQuantity.cs](https://github.com/BHoM/BHoM/blob/main/Quantities_oM/Attributes/ClimateChangePerQuantity.cs)).
BHoM uses the same pattern for time: instead of `/a` baked into the unit, there's a separate `Module` field whose enum lists lifecycle stages (A1–A3 for product, B6 for operational, C1–C4 for end-of-life, etc.).
## The question
Would an equivalent direction (a `PerQuantity` or similar field alongside `Unit` on `Property` / `ClassProperty`) be something bSDD has considered, or could consider?
If this is out of scope for the current data model, is there a canonical place for this kind of schema-level proposal (forum thread, RFC, maintainers' discussion)?
---
*This issue was co-created with Claude Code (Claude Opus 4.7).*
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.