diff --git a/README.md b/README.md
index b940e2f..a87ff96 100644
--- a/README.md
+++ b/README.md
@@ -1,178 +1,226 @@
# bps-schema
-多尺度多性能协同数据模型。
+建筑性能模拟数据模型。所有类型定义以 draft-2020-12 标准 JSON Schema 为准。
-## 仓库文件
+## 文件架构
-| 文件 | 说明 |
-|------|------|
-| `schema-building.json` | 建筑几何 + 核心实体(Building, Floor, Room, Aperture, Boundary, Element, Shaft 等) |
-| `schema-energy.json` | 能耗模拟领域(Material, Construction, RoomProgram, Schedule 等) |
+采用"尺度 × 模拟域"二维分文件架构。每个尺度按几何和模拟域拆分为独立文件。
-## Schema 规则
+### 建筑单体尺度
-### 1. JSON 为唯一真理源
+| 文件 | $id | defs | 说明 |
+|------|-----|------|------|
+| `schema-building.json` | bps/building | 30 | 建筑几何实体,对齐 HBJSON 几何层级 |
+| `schema-energy.json` | bps/energy | 49 | EnergyPlus 能耗模拟参数 |
+| `schema-radiance.json` | bps/radiance | 25 | Radiance 采光模拟参数 |
+| `schema-cfd.json` | bps/cfd | 14 | CFD 建筑风环境模拟参数(AI 生成的示例文件,需人工审核后使用) |
-所有类型定义以 JSON 文件为准。TypeScript / Python 等语言的绑定代码均从 JSON 生成,不得手工维护。
+### 社区尺度
-### 2. 不保存派生数据
+| 文件 | $id | defs | 说明 |
+|------|-----|------|------|
+| `schema-community.json` | bps/community | 7 | 社区几何:Site / Terrain / Road / GreenSpace / WaterBody(AI 生成的示例文件,需人工审核后使用) |
+| `schema-community-energy.json` | bps/community-energy | 8 | 区域能源:Plant / Network / Pipe / BuildingConnection(AI 生成的示例文件,需人工审核后使用) |
+| `schema-community-cfd.json` | bps/community-cfd | 13 | 社区风环境:计算域 / 网格 / 湍流 / 边界条件 / 求解器(AI 生成的示例文件,需人工审核后使用) |
+| `schema-community-microclimate.json` | bps/community-microclimate | 2 | 微气候:UHI 强度 / 风速修正 / 地表反照率(AI 生成的示例文件,需人工审核后使用) |
-Schema 只保存**原始定义数据**,不包含任何可从已有字段计算得出的值。
+### 城市尺度
-```
-❌ area — 可由 region 计算
-❌ volume — 可由 region + height 计算
-❌ boundingBox — 可由子实体几何计算
-✅ region — 房间轮廓点集
-✅ height — 房间高度
-```
+| 文件 | $id | defs | 说明 |
+|------|-----|------|------|
+| `schema-urban.json` | bps/urban | 3 | 城市几何:ClimateZone / LandUse(AI 生成的示例文件,需人工审核后使用) |
+| `schema-urban-energy.json` | bps/urban-energy | 5 | 城市能源:需求聚合 / 可再生能源潜力 / 碳平衡(AI 生成的示例文件,需人工审核后使用) |
+| `schema-urban-cfd.json` | bps/urban-cfd | 15 | 城市风环境:行人高度评估 / 街道峡谷 / 风舒适标准(AI 生成的示例文件,需人工审核后使用) |
-### 3. 字段命名
+### 聚合入口
-| 规则 | 示例 |
-|------|------|
-| 使用 camelCase | `siteBasePoint`, `sillHeight`, `openRatio` |
-| 避免缩写(广为人知的除外) | `identifier` 而非 `id`, `displayName` 而非 `name` |
-| 布尔值用正面语义 | `operable` 而非 `nonOperable` |
-| 枚举值用 snake_case | `exterior_wall`, `curtain_wall` |
+| 文件 | $id | defs | 说明 |
+|------|-----|------|------|
+| `schema-all.json` | bps/all | 11 | 引用以上所有文件,提供完整验证入口 |
-### 4. 类型系统
+**合计**:11 个领域文件 + 1 个聚合文件,171 个类型定义。
-**基础类型:**
-- `string` — 字符串
-- `number` — 浮点数
-- `integer` — 整数
-- `boolean` — 布尔值
-- `object` — 任意对象
+## Schema 规范
-**复合类型:**
-- `TypeName[]` — 数组,如 `Polyline3d` 的 `points` 字段类型为 `Point3d[]`
-- `TypeName` — 引用自定义类型或实体
+所有文件均遵循 [JSON Schema draft-2020-12](https://json-schema.org/draft/2020-12/release-notes):
-**自定义类型**定义在 `types` 段,描述纯数据结构,不是业务实体。例如 `Point3d`(三维点)、`Polyline3d`(多段线)、`TimePoint`(时刻点)。
+- `$defs` — 所有类型、枚举、实体的定义区
+- `$ref` — 类型引用,使用 JSON Schema 标准 `$ref` 机制
+- `oneOf` — 判别联合体(如边界条件的 5 种类型)
+- `allOf` — 实体组合(`_IdentifiedObject` + 具体属性)
+- `const` / `enum` — 类型判别字段和枚举值
+- `required` — 必填字段
+- `default` — 缺省值
+- `minimum` / `maximum` / `exclusiveMinimum` — 数值约束
+- `pattern` / `minLength` / `maxLength` — 字符串约束
+- `additionalProperties: false` — 严格模式,禁止额外字段
-### 5. 实体结构
+## schema-building.json:建筑几何
-```json
-"EntityName": {
- "description": "中文说明",
- "tags": { "scale": ["building"], "simulation": ["energy"] },
- "attributes": {
- "fieldName": {
- "type": "string",
- "required": true,
- "unit": "m",
- "default": 0,
- "description": "字段说明",
- "tags": { "scale": ["building"], "simulation": ["energy", "daylight"] }
- }
- },
- "children": {
- "childName": {
- "type": "ChildEntity",
- "multiple": true,
- "description": "子实体说明"
- }
- }
-}
-```
+对齐 [honeybee-schema](https://github.com/ladybug-tools/honeybee-schema) 几何层级,覆盖 Model → Room → Face → Aperture/Door → Shade 层级。
-- `attributes` — 标量字段(string, number, boolean, enum, 自定义类型)
-- `children` — 关联的子实体(1:1 或 1:N)
-- `required: true` — 必填字段,序列化时必须存在
-- `default` — 缺省值(可选字段未提供时使用)
-- `unit` — 单位标注(仅文档用途)
+### 几何原语
-### 6. 判别联合体(Discriminated Union)
+- `Point3D` — 三维坐标 (x, y, z)
+- `Face3D` — 平面多边形(boundary + holes + plane)
+- `Mesh3D` — 三角/四边形网格(vertices + faces + colors)
+- `Plane` — 平面(法线 n + 原点 o + x 轴)
+- `Color` — RGBA 颜色
-当一个实体存在多种形态时,使用 `variants` 表达:
+### 边界条件
-```json
-"Room": {
- "discriminator": "creationMethod",
- "variants": {
- "planar_extrude": { ... },
- "mass_slice": { ... },
- "manual": { ... }
- }
-}
-```
+- `Outdoors` / `Surface` / `Ground` / `Adiabatic` / `OtherSideTemperature`
+- Aperture/Door 仅支持 Outdoors 和 Surface 两种
-不同变体可包含不同的必填字段。判别字段的值决定了使用哪个变体。当前使用判别联合体的实体:
-- `Room` — 判别字段 `creationMethod`,变体:`planar_extrude`、`mass_slice`、`manual`
-- `Aperture` — 判别字段 `sourceType`,变体:`hosted`、`declarative`
+### 标识符规范
-### 7. 枚举
+- `identifier`:`^[.A-Za-z0-9_-]+$`,1-100 字符
+- `display_name`:无限制(仅用于 UI 展示)
+- `user_data`:可选字典
-枚举定义在 `enums` 段,每个枚举列出所有允许值。
+## schema-energy.json:能耗模拟参数
-### 8. 尺度与模拟类型标签(tags)
+覆盖 HBJSON energy properties 核心实体:材料、构造、时间表、负荷、HVAC、构造集、程序类型。
-每个字段可标注两个维度的标签:
+### 材料
-**尺度(scale):**
-| 标签 | 说明 |
-|------|------|
-| `building` | 建筑尺度 |
-| `community` | 社区/街区尺度 |
-| `urban` | 城市尺度 |
+- `EnergyMaterial` — 有质量材料
+- `EnergyMaterialNoMass` — 无质量材料
+- `EnergyMaterialVegetation` — 植被材料
+- `EnergyWindowMaterialGlazing` / `Gas` / `GasCustom` / `GasMixture` / `SimpleGlazSys` — 窗材料
+- `EnergyWindowMaterialBlind` / `Shade` — 百叶/遮阳
+- `EnergyWindowFrame` — 窗框
-**模拟类型(simulation):**
-| 标签 | 说明 |
-|------|------|
-| `energy` | 能耗模拟 |
-| `daylight` | 采光分析 |
-| `solar` | 日照分析 |
-| `thermal_comfort` | 热舒适分析 |
-| `carbon` | 碳排放核算 |
-| `wind` | 风环境模拟 |
-| `general` | 通用(不特定于某种模拟) |
+### 构造
-标签用于快速筛选特定尺度或某类模拟分析所需的字段。例如:
+- `OpaqueConstruction` / `WindowConstruction` / `AirBoundaryConstruction` / `ShadeConstruction`
+- 各自 Abridged 版本(identifier 引用)
+- `WindowConstructionShade` / `WindowConstructionDynamic` — 含动态遮阳的窗构造
-```json
-"northAngle": {
- "type": "number",
- "tags": { "simulation": ["energy", "daylight", "solar", "thermal_comfort", "wind"] }
-}
-```
+### 时间表
-表示 `northAngle` 对能耗、采光、日照、热舒适、风环境模拟均有影响。
+- `ScheduleTypeLimit` / `ScheduleDay` / `ScheduleFixedInterval` / `ScheduleRulesetAbridged` / `ScheduleRule`
-```json
-"embodiedCarbon": {
- "type": "number",
- "tags": { "scale": ["building", "community", "urban"], "simulation": ["carbon"] }
-}
-```
+### 负荷与设定值
-表示 `embodiedCarbon` 适用于建筑/社区/城市三个尺度,仅用于碳排放核算。
+- `PeopleAbridged` / `LightingAbridged` / `ElectricEquipmentAbridged` / `GasEquipmentAbridged`
+- `ServiceHotWaterAbridged` / `InfiltrationAbridged` / `VentilationAbridged`
+- `SetpointAbridged` / `InternalMassAbridged` / `ProcessAbridged`
-### 9. 只描述数据本身
+### 程序类型 / 构造集 / HVAC
-Schema 只描述**建筑数据本身**,不描述数据的生成方式。
+- `ProgramTypeAbridged` / `ConstructionSetAbridged`
+- `DefaultProgramTypesAbridged` / `DefaultConstructionSetAbridged`
+- `IdealAirSystemAbridged`
+
+## schema-radiance.json:采光模拟参数
+
+兼容 HBJSON radiance properties,覆盖 Radiance 材质、构造集、传感器网格、视角。
+
+### 材质(Modifiers)
+
+- `Plastic` — 塑料材质(RGB 反射率 + 镜面度 + 粗糙度)
+- `Metal` — 金属材质(继承 Plastic,镜面度默认 0.9)
+- `Trans` — 半透明材质(透射漫反射比 + 透射镜面比)
+- `Glass` — 玻璃材质(RGB 透射率 + 折射率)
+- `Mirror` — 镜面材质(RGB 反射率)
+- `Light` / `Glow` — 发光材质(RGB 发射率)
+- `BSDF` — 双向散射分布函数材质(BSDF XML 数据 + 朝向)
+- `Void` — 空材质
+
+### 材质集(Modifier Sets)
+
+- `WallModifierSetAbridged` / `FloorModifierSetAbridged` / `RoofCeilingModifierSetAbridged`
+- `ApertureModifierSetAbridged` / `DoorModifierSetAbridged` / `ShadeModifierSetAbridged`
+- `ModifierSet` — 材质集聚合
+
+### 传感器与视角
+
+- `Sensor` / `SensorGrid` — 传感器网格
+- `View` — Radiance 视角(6 种视角类型)
+
+## schema-cfd.json:CFD 风环境模拟
+
+独立领域(非 HBJSON),覆盖 CFD 建筑风环境分析的完整参数体系。
+
+### 核心参数
+
+- `WindProfile` — 风剖面(4 种剖面 + 地形类别 + 风向)
+- `CFDDomain` — 计算域定义
+- `MeshParameters` — 网格设置(基础网格 + 局部加密 + 壁面层)
+- `TurbulenceParameters` — 湍流设置(6 种模型 + 壁面函数)
+- `BoundaryConditions` — 进出口/顶部/侧面/地面/建筑墙面边界类型
+- `SolverSettings` — 求解器设置(稳态/瞬态 + SIMPLE/PISO + 收敛准则)
+
+## schema-community*.json:社区尺度
+
+### 几何(schema-community.json)
+
+- `Site` — 场地顶级实体,含 2D 边界
+- `TerrainGrid` / `TerrainTIN` — 高程网格或三角网
+- `Road` / `GreenSpace` / `WaterBody` — 基础设施
+
+### 区域能源(schema-community-energy.json)
+
+- `DistrictEnergy` — 区域能源系统顶级实体
+- `Plant` — 源站(CHP / Boiler / HeatPump / Chiller / PV 等)
+- `Network` — 管网(CHW / HW / Steam / Electricity)
+- `Pipe` / `BuildingConnection` — 管段与建筑接入
+
+### 风环境(schema-community-cfd.json)
+
+- `CFDDomain` — 社区尺度计算域
+- `MeshParameters` — 含局部加密区域
+- `SolverSettings` / `TurbulenceParameters` / `BoundaryConditions`
+
+## schema-urban*.json:城市尺度
+
+### 几何(schema-urban.json)
+
+- `ClimateZone` — 气候分区(边界 + 气候区代码 + 度日数)
+- `LandUse` — 用地性质(边界 + 用地类型 + 容积率 + 建筑密度)
+
+### 能源(schema-urban-energy.json)
+
+- `UrbanEnergyDemand` — 各用地类型年度能耗
+- `RenewablePotential` — 屋顶/立面/地面可再生能源潜力
+- `UrbanEnergyBalance` — 城市能源平衡(自给率 / 碳排放 / EUI)
+
+### 风环境(schema-urban-cfd.json)
+
+- `UrbanCFDSettings` — 城市级 CFD 设置
+- `WindComfortAssessment` — 行人风舒适评估(Laws / NEN_8100 / COST_732 标准)
+- `MeshParameters` — 含行人高度加密层
## 使用方式
-各项目从 JSON schema 生成对应语言的类型代码:
+### 数据验证
```bash
-# TypeScript(示例)
-python3 scripts/gen-ts.py schema-building.json > dist/building.d.ts
-
-# Python Pydantic(示例)
-python3 scripts/gen-py.py schema-building.json > archgen_schema/building.py
+pip install jsonschema
+python3 -c "
+import json, jsonschema
+with open('schema-building.json') as f:
+ schema = json.load(f)
+with open('model.hbjson') as f:
+ data = json.load(f)
+jsonschema.validate(data, schema)
+"
```
-具体生成器暂时不在本仓库维护。
+### TypeScript 类型生成
----
+```bash
+npx quicktype schema-building.json -o dist/building.d.ts --lang typescript
+npx quicktype schema-energy.json -o dist/energy.d.ts --lang typescript
+npx quicktype schema-radiance.json -o dist/radiance.d.ts --lang typescript
+npx quicktype schema-cfd.json -o dist/cfd.d.ts --lang typescript
+```
-## TODO
+### Python Pydantic 生成
-- [ ] 定义 building / community / urban 每个尺度的最小字段集合
-- [ ] 制定 `required` 与 `default` 的判定规则文档
-- [ ] 梳理影响模拟性能的字段并标注影响等级
-- [ ] 明确"智能优化"的定义和 scope(形态优化 vs 性能目标驱动)
-- [ ] 确定优化变量、约束条件在 schema 中的表达方式
-- [ ] 完善 schema 的 tags 系统(如需新增 `minScale` / `maxScale` / `performanceImpact` / `optimizable` 等属性)
+```bash
+pip install datamodel-code-generator
+datamodel-codegen --input schema-building.json --output dist/building.py --output-model-type pydantic_v2.BaseModel
+datamodel-codegen --input schema-energy.json --output dist/energy.py --output-model-type pydantic_v2.BaseModel
+```
diff --git a/docs/multiscale-hbjson-extension.md b/docs/multiscale-hbjson-extension.md
new file mode 100644
index 0000000..264437d
--- /dev/null
+++ b/docs/multiscale-hbjson-extension.md
@@ -0,0 +1,349 @@
+# 基于 HBJSON 扩展多尺度数据模型:方案设计
+
+> 日期:2026-05-28
+> 来源:HBJSON Schema 分析与多尺度扩展讨论
+
+---
+
+## 一、背景
+
+HBJSON(Honeybee Schema)是 Ladybug Tools 生态中建筑单体性能模拟的标准数据交换格式。它以 Room → Face → Aperture/Door 的层级结构表达建筑三维几何,并通过 `properties` 扩展点挂载 EnergyPlus/Radiance/DOE-2 的模拟参数。
+
+本课题"多尺度绿色性能云端模拟"需要在建筑单体之上,覆盖社区和城市尺度的模拟需求。本文先解读 HBJSON 结构,再分析 Ladybug Tools 现有方案(Dragonfly)的能力与局限,最后提出多尺度扩展方案。
+
+---
+
+## 二、HBJSON Schema 结构解读
+
+### 2.1 整体文件结构
+
+HBJSON 是一个自包含的 JSON 文件,由一个顶层 `Model` 对象统领所有数据。文件不依赖外部引用,所有几何、构造、材料、负荷、时间表均内嵌或通过 identifier 引用。
+
+### 2.2 顶层 Model 对象
+
+`Model` 是文件的根节点,核心字段如下:
+
+| 字段 | 类型 | 说明 |
+|---|---|---|
+| `type` | string | 固定为 `"Model"` |
+| `version` | string | Schema 版本号,格式 `x.y.z` |
+| `rooms[]` | Room[] | 建筑房间列表,每个 Room 是一个封闭三维空间 |
+| `orphaned_faces[]` | Face[] | 无父 Room 的面(不可用于能耗模拟导出) |
+| `orphaned_apertures[]` | Aperture[] | 无父 Face 的窗 |
+| `orphaned_doors[]` | Door[] | 无父 Face 的门 |
+| `orphaned_shades[]` | Shade[] | 无父对象的独立遮阳 |
+| `shade_meshes[]` | ShadeMesh[] | 网格遮阳(周边建筑、地形) |
+| `units` | enum | 几何单位:`Meters` / `Millimeters` / `Feet` / `Inches` / `Centimeters` |
+| `tolerance` | float | 顶点容差(米制默认 0.01),用于几何容差检查 |
+| `angle_tolerance` | float | 角度容差(默认 1.0 度),用于共线/共面检查 |
+| `properties` | ModelProperties | 模型级扩展属性(Energy / Radiance / DOE-2) |
+
+### 2.3 几何层级与嵌套关系
+
+几何对象按严格的层级嵌套:
+
+```
+Model
+├── rooms[]
+│ ├── faces[] ← 包围 Room 的面(≥4 个形成封闭体积)
+│ │ ├── apertures[] ← 窗(开洞,透光)
+│ │ │ ├── indoor_shades[] ← 室内遮阳(窗帘、窗台)
+│ │ │ └── outdoor_shades[] ← 室外遮阳(百叶、格栅)
+│ │ ├── doors[] ← 门
+│ │ ├── indoor_shades[]
+│ │ └── outdoor_shades[] ← 室外遮阳(阳台、挑檐)
+│ ├── indoor_shades[] ← 室内家具/隔断
+│ └── outdoor_shades[] ← 室外树木/景观
+└── shade_meshes[] ← 独立网格遮阳
+```
+
+各对象核心字段:
+- `Room`:`faces[]`(面列表)、`multiplier`(标准层复用系数)、`zone`(热区标识)、`story`(楼层标识)、`exclude_floor_area`(是否排除楼板面积)
+- `Face`:`face_type`(`Wall` / `Floor` / `RoofCeiling` / `AirBoundary`)、`boundary_condition`(边界条件)
+- `Aperture` / `Door`:`is_operable`(可开启)、`is_glass`(玻璃门)
+- `Shade`:`is_detached`(是否脱离主体)
+
+### 2.4 几何原语
+
+所有 3D 几何基于以下原语构建:
+
+**Point3D**:三维坐标点
+```json
+{ "type": "Point3D", "x": 0.0, "y": 0.0, "z": 0.0 }
+```
+
+**Face3D**:平面多边形(Face/Aperture/Door 的几何基础)
+```json
+{
+ "type": "Face3D",
+ "boundary": [[x,y,z], [x,y,z], ...], // 外轮廓顶点,≥3 个
+ "holes": [[...], ...], // 孔洞轮廓(可选)
+ "plane": { "n": [0,0,1], "o": [0,0,0] } // 法线 + 原点(可选,自动推导)
+}
+```
+
+**Mesh3D**:三角/四边形网格(ShadeMesh 的几何基础)
+```json
+{
+ "type": "Mesh3D",
+ "vertices": [[x,y,z], ...], // 顶点池
+ "faces": [[0,1,2], [1,3,2]], // 面索引(3 或 4 个索引)
+ "colors": [{ "r":255, "g":0, "b":0, "a":255 }] // 顶点/面着色(可选)
+}
+```
+
+### 2.5 边界条件(Boundary Conditions)
+
+Face 的 `boundary_condition` 字段定义面与外部环境的关系,共 5 种类型:
+
+| 类型 | 适用场景 | 核心参数 |
+|---|---|---|
+| `Outdoors` | 外表面暴露于室外 | `sun_exposure`、`wind_exposure`、`view_factor`(对地视角系数) |
+| `Surface` | 与另一表面对接 | `boundary_condition_objects`(相邻对象 identifier 列表,Face 为 2 个,SubFace 为 3 个) |
+| `Ground` | 接地面 | 无附加参数 |
+| `Adiabatic` | 绝热面(相邻空间温湿度相同) | 无附加参数 |
+| `OtherSideTemperature` | 给定外侧温度边界 | `heat_transfer_coefficient`(W/m²K)、`temperature`(℃) |
+
+约束:`AirBoundary` 类型的 Face **必须**有 `Surface` 边界条件,校验器会强制检查。
+
+### 2.6 Abridged(简写)模式
+
+HBJSON 的核心设计特征。每个 properties 对象均有两种形态:
+
+| 模式 | 结构 | 用途 |
+|---|---|---|
+| `XXXProperties` | 内嵌完整对象(含所有 Material、Construction 定义) | 运行时内存对象 |
+| `XXXPropertiesAbridged` | 仅存 identifier 字符串引用 | 序列化到 JSON 文件 |
+
+工作机制:
+```
+Room.properties.energy.construction_set: "Generic2005Construction"
+ │
+ ▼
+Model.properties.energy.construction_sets: [
+ { "identifier": "Generic2005Construction",
+ "wall_construction": "WallCons_Generic", ... }
+]
+Model.properties.energy.constructions: [
+ { "identifier": "WallCons_Generic", "layers": ["mat_1", "mat_2"] }
+]
+Model.properties.energy.materials: [
+ { "identifier": "mat_1", "type": "EnergyMaterial", ... }
+]
+```
+
+这种"外键引用"模式避免了几何层级的循环嵌套,大幅减小文件体积,是处理大型建筑模型的关键优化。
+
+### 2.7 扩展属性系统(Properties Extension)
+
+每个几何层级都通过 `properties` 字段挂载多引擎数据,采用插件式架构:
+
+```
+properties:
+├── energy — EnergyPlus(构造、负荷、HVAC、时间表)
+├── radiance — Radiance(材质、动态遮阳状态、传感器网格)
+└── doe2 — DOE-2(历史兼容)
+```
+
+各层级的 Energy 属性举例:
+- `Model` 级:`constructions[]`、`materials[]`、`programs[]`(使用模式)、`schedules[]`、`hvacs[]`
+- `Room` 级:`construction_set`(引用)、`program_type`(引用)、`hvac`(引用)、`shw`(引用),以及逐条覆盖的 `people`、`lighting`、`equipment`、`infiltration`、`ventilation`、`setpoint`
+- `Face` 级:`construction`(引用)、`vent_crack`(AirflowNetwork 裂缝)
+- `Aperture` 级:`construction`(引用)、`vent_opening`
+- `Shade` 级:`construction`(引用)、`transmittance_schedule`(透射率时间表)、`pv_properties`(光伏)
+
+### 2.8 标识符与元数据
+
+所有对象继承 `IDdBaseModel`,统一标识规范:
+
+| 字段 | 约束 | 说明 |
+|---|---|---|
+| `identifier` | `^[.A-Za-z0-9_-]+$`,1-100 字符 | 唯一标识,序列化/引用/跨引擎传递均使用此字段 |
+| `display_name` | 无限制 | 仅用于 UI 展示,可含中文、空格、特殊字符 |
+| `user_data` | 可选字典 | 用户自定义附加数据,键值需为基本类型 |
+
+### 2.9 容差机制
+
+HBJSON 通过两个参数处理 CAD 几何导入时的浮点误差:
+
+- `tolerance`(距离容差):顶点坐标差值小于此值视为重合,用于封闭体积检查、法线校正
+- `angle_tolerance`(角度容差):边方向夹角小于此值视为共线,用于冗余顶点清理
+
+EnergyPlus 要求几何单位为米且封闭体积,因此 `units: "Meters"` + 合理的 `tolerance` 是导出成功的必要条件。
+
+---
+
+## 三、Ladybug Tools 现有方案:Dragonfly
+
+Dragonfly 是 Ladybug Tools 生态中面向社区/城市尺度的独立项目,schema 定义在 `dragonfly-schema`。
+
+### 3.1 Dragonfly 层级结构
+
+```
+Dragonfly Model
+├── buildings[]
+│ ├── unique_stories[]
+│ │ ├── room_2ds[] ← 2D 楼层板 + 参数化立面
+│ │ └── multiplier ← 标准层复用
+│ ├── room_3ds[] ← 可选的完整 Honeybee Room(3D)
+│ └── roof ← 屋顶几何
+├── context_shades[] ← 周边建筑/地形(Face3D / Mesh3D)
+├── units / tolerance / angle_tolerance
+└── properties ← Energy / Radiance / DOE-2 / Comparison
+```
+
+### 3.2 Dragonfly 与 Honeybee 的关系
+
+```
+Dragonfly (社区/城市尺度)
+ │ 几何: 2D 楼层板 + 参数化窗户/遮阳/屋顶
+ │ ↓ translate_to_honeybee()
+ ▼
+Honeybee (建筑单体尺度)
+ │ 几何: 完整 3D Face3D
+ │ ↓ to_idf() / to_rad()
+ ▼
+EnergyPlus / Radiance
+```
+
+关键事实:Dragonfly 不是 HBJSON 的"上层扩展",而是一个**独立的 schema**,通过 `translate_to_honeybee()` 降维生成 HBJSON。
+
+### 3.3 Dragonfly 的能力与局限
+
+| 尺度 | 能力 | 局限 |
+|---|---|---|
+| 建筑单体 | Room2D(2D 楼板+参数化立面)→ 可转 Honeybee | 非 3D 精确几何 |
+| 建筑群 | Building 列表 + ContextShade | 仅遮阳关系,无交互 |
+| 社区 | 多 Building + reference_vector 定位 | 无管网/微气候/能源系统 |
+
+### 3.4 缺失层(社区 → 城市之间)
+
+- **区域能源系统**(District Energy)——冷热源站、管网拓扑、换热站
+- **场地要素**——道路、绿地、水体、地形
+- **微气候**——UHI(城市热岛)、风环境耦合
+- **城市尺度**——土地利用分区、交通、人口密度
+- **跨建筑交互**——阴影投射、反射辐射、废热排放
+
+---
+
+## 四、扩展方案对比
+
+### 4.1 方案对比
+
+| 方案 | 核心思路 | 优势 | 劣势 |
+|---|---|---|---|
+| 一:HBJSON 之上增加 Site 层 | 包裹 MultiScaleModel,内嵌 HBJSON | 完全向后兼容,单文件云端模拟 | 文件体积较大 |
+| 二:扩展 Dragonfly properties | 在 Dragonfly Model 增加城市扩展 | 与 Ladybug Tools 原生兼容 | Room2D 几何精度不足,HBJSON 反向映射不完美 |
+| 三:独立格式 + HBJSON 引用 | CityModel 引用外部 hbjson 文件 | 解耦,可版本控制 | 多文件依赖,不适合云端一键模拟 |
+
+### 4.2 推荐方案:方案一的增强版
+
+在 HBJSON 之上增加 `MultiScaleModel` 容器,保持 HBJSON 结构不变,新增 Site 和 Urban 层级。
+
+设计原则:
+1. 完全向后兼容——`sites[].buildings[]` 是标准 HBJSON Model,现有工具无需修改
+2. 增量扩展——只增加 Site 和 Urban 两个新层级
+3. 可分级模拟——可只取一个 Site 做社区模拟,也可取全部做城市模拟
+
+---
+
+## 五、MultiScaleModel Schema 设计
+
+### 5.1 顶层结构
+
+```json
+{
+ "type": "MultiScaleModel",
+ "version": "0.1.0",
+ "units": "Meters",
+ "tolerance": 0.01,
+ "sites": [...],
+ "properties": { "urban": {...} }
+}
+```
+
+### 5.2 Site 结构(社区/街区尺度)
+
+```
+Site
+├── identifier ← 场地标识
+├── boundary ← 2D 边界 [[x,y], ...]
+├── buildings[] ← HBJSON Model(内嵌)
+├── context_shades[] ← 周边建筑/地形
+│
+├── terrain ← 地形
+│ ├── type: "Grid" | "TIN"
+│ └── data ← 高程网格或三角网
+│
+├── infrastructure ← 基础设施
+│ ├── roads[] ← 道路中心线 + 断面
+│ ├── green_spaces[] ← 绿地(Face3D + 植被类型)
+│ └── water_bodies[] ← 水体
+│
+├── district_energy ← 区域能源系统
+│ ├── plants[] ← 源站(CHP、地源热泵、锅炉房)
+│ │ ├── type, capacity, cop, fuel_type
+│ │ └── location [x, y, z]
+│ ├── networks[] ← 管网
+│ │ ├── type: "CHW" | "HW" | "Steam"
+│ │ ├── pipes[] ← 管段(起点、终点、管径、保温)
+│ │ └── supply_temp, return_temp
+│ └── connections[] ← 建筑-管网接入
+│ ├── building_ref, network_ref, flow_rate
+│
+└── properties
+ ├── energy
+ └── microclimate ← 微气候
+ ├── uhi_model ← 热岛强度参数
+ └── wind_model ← 风场参数
+```
+
+### 5.3 Urban 结构(城市尺度)
+
+```
+properties.urban
+├── climate_zones[] ← 气候分区
+├── land_use[] ← 用地性质
+└── schedule ← 城市级时间表(交通、人口)
+```
+
+---
+
+## 六、关键技术决策
+
+| 决策点 | 推荐 | 理由 |
+|---|---|---|
+| 建筑几何引用 | 内嵌 HBJSON | 保持与 HBJSON 自包含格式的一致性,减少解析复杂度;多文件方案需额外处理文件依赖和版本一致性 |
+| 几何精度 | 社区用 Dragonfly Room2D,城市用简模 | 城市尺度不需要 Face 级精度,简化计算 |
+| 微气候耦合 | 参数化而非 CFD | CFD 耦合计算量过大,用 UHI 修正系数 |
+| 区域能源 | 拓扑网络 + 简化水力模型 | 不需要详细水力计算,关注热平衡 |
+| 向后兼容 | 完全保留 HBJSON 结构 | 现有 honeybee 工具链零修改 |
+
+---
+
+## 七、下一步:新增 community/urban 尺度实体
+
+当前 `schema-building.json` 已完全对齐 HBJSON(建筑单体几何尺度)。社区和城市尺度的实体定义需要新建独立的 `schema-community.json` / `schema-urban.json`,不应直接混入 schema-building.json,以保持与 HBJSON 的严格兼容。
+
+除几何外,各模拟领域均已独立建库,且按尺度拆分:
+
+- 建筑尺度:`schema-building.json`(几何)/ `schema-energy.json` / `schema-radiance.json` / `schema-cfd.json`
+- 社区尺度:`schema-community.json`(几何)/ `schema-community-energy.json` / `schema-community-cfd.json` / `schema-community-microclimate.json`
+- 城市尺度:`schema-urban.json`(几何)/ `schema-urban-energy.json` / `schema-urban-cfd.json`
+
+新增实体规划:
+
+| 层级 | 文件 | 实体 |
+|---|---|---|
+| Site 几何 | `schema-community.json` | Site / TerrainGrid / TerrainTIN / Road / GreenSpace / WaterBody |
+| 区域能源 | `schema-community-energy.json` | DistrictEnergy / Plant / Network / Pipe / BuildingConnection |
+| 社区 CFD | `schema-community-cfd.json` | CommunityCFDSettings / WindProfile / CFDDomain / Mesh / Turbulence |
+| 微气候 | `schema-community-microclimate.json` | MicroClimate |
+| 城市几何 | `schema-urban.json` | ClimateZone / LandUse |
+| 城市能源 | `schema-urban-energy.json` | UrbanEnergyDemand / RenewablePotential / UrbanEnergyBalance |
+| 城市 CFD | `schema-urban-cfd.json` | UrbanCFDSettings / WindComfortAssessment |
+
+MultiScaleModel 作为顶层容器,通过引用方式关联三个尺度:
+- `sites[].buildings[]` → 引用 bps/building 的 HBJSON Model
+- `sites[].terrain/infrastructure` → 由 bps/community 定义
+- `properties.urban` → 由 bps/urban 定义
diff --git a/pres/assets/base.css b/pres/assets/base.css
new file mode 100644
index 0000000..a65418b
--- /dev/null
+++ b/pres/assets/base.css
@@ -0,0 +1,1285 @@
+/**
+ * base.css — CCTC-CADG 16:9 固定比例基础样式
+ *
+ * 策略:
+ * 1. body 填充视口,flex 居中,深灰背景
+ * 2. .deck 锁定 16:9,通过 width/max-height 自动适配视口
+ * 3. 所有内部尺寸(字体/间距/布局)统一用 vmin
+ */
+
+/* ============================================
+ 1. 设计令牌(Design Tokens)
+ ============================================ */
+:root {
+ --text-pri: #222;
+ --text-body: #444;
+ --text-muted: #777;
+ --text-light: #bbb;
+ --border: #e8e8e8;
+ --border-light: #ccc;
+ --bg-card: #f8f8f8;
+ --bg-alt: #fafafa;
+ --bg-white: #fff;
+ --danger: #b91c1c;
+ --success: #047857;
+ --accent: #C00000;
+ --accent-alt: #555555;
+ --accent-light: rgba(192, 0, 0, 0.06);
+ --accent-mid: rgba(192, 0, 0, 0.12);
+ --gray-seal: rgba(180, 180, 180, 0.18);
+ --gray-pattern: rgba(180, 180, 180, 0.12);
+ --red-bar-w: 2.5vmin;
+
+ --hero: 7.5vmin;
+ --subtitle: 3.5vmin;
+ --display: 5.5vmin;
+ --heading: 4vmin;
+ --body: 3vmin;
+ --small: 2.8vmin;
+ --tag: 2vmin;
+ --mini: 1.6vmin;
+ --kpi: 6vmin;
+ --icon-lg: 8vmin;
+ --thanks: 8vmin;
+ --seal: 20vmin;
+ --section-num: 12vmin;
+
+ --space-xs: 0.8vmin;
+ --space-sm: 1.5vmin;
+ --space: 2vmin;
+ --space-lg: 3vmin;
+ --space-xl: 5vmin;
+
+ --header-h: 14vmin;
+ --footer-h: 8vmin;
+ --body-pad-x: 8vmin;
+ --body-pad-y: 3vmin;
+
+ --hair: 0.1vmin;
+ --border-w: 0.15vmin;
+ --med: 0.2vmin;
+ --strong: 0.6vmin;
+
+ --content-h: 78vmin;
+ --img-max-showcase: 52vmin;
+ --img-max-wide: 42vmin;
+ --img-max-standard: 33vmin;
+ --img-max-compare: 40vmin;
+ --img-max-triple: 35vmin;
+ --img-max-grid: 22vmin;
+
+ --accent-1: var(--accent);
+ --accent-2: var(--accent-alt);
+}
+
+/* ============================================
+ 2. 幻灯片骨架 — 16:9 固定比例容器
+ ============================================ */
+/* body 填充视口,居中,深色背景 */
+body, html {
+ margin: 0;
+ padding: 0;
+ width: 100vw;
+ height: 100vh;
+ overflow: hidden;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ text-rendering: optimizeLegibility;
+}
+body {
+ background: #1a1a1a;
+}
+
+/* 全屏容器:deck 填满视口,所有内部尺寸用 vmin 同步缩放 */
+.deck.tpl-cctc-cadg {
+ position: relative;
+ width: 100vw;
+ height: 100vh;
+ overflow: hidden;
+ font-family: "Microsoft YaHei", "Times New Roman", "PingFang SC", "Helvetica Neue", Arial, sans-serif;
+ background: var(--bg-white);
+}
+
+.deck.tpl-cctc-cadg .slide {
+ position: absolute !important;
+ inset: 0 !important;
+ padding: 0 !important;
+ justify-content: flex-start !important;
+ align-items: stretch !important;
+ overflow: hidden;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.5s ease, transform 0.5s ease;
+ transform: translateX(30px);
+}
+.deck.tpl-cctc-cadg .slide.is-active {
+ opacity: 1;
+ pointer-events: auto;
+ transform: translateX(0);
+ z-index: 2;
+}
+.deck.tpl-cctc-cadg .slide.is-prev {
+ transform: translateX(-30px);
+}
+
+/* 全屏模式防文字重影 */
+.slide {
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+}
+:fullscreen .slide {
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ transform: translateZ(0);
+}
+
+/* ============================================
+ 3. 页眉页脚
+ ============================================ */
+.deck.tpl-cctc-cadg .page-header {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: var(--red-bar-w);
+ height: var(--header-h);
+ background: var(--accent-1);
+ z-index: 2;
+}
+.deck.tpl-cctc-cadg .page-title {
+ position: absolute;
+ top: var(--space-xl);
+ left: var(--body-pad-x);
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--accent-1);
+ letter-spacing: var(--space-xs);
+ z-index: 3;
+}
+.deck.tpl-cctc-cadg .page-subtitle {
+ position: absolute;
+ top: 10.5vmin;
+ left: var(--body-pad-x);
+ font-size: var(--small);
+ color: var(--text-muted);
+ z-index: 3;
+}
+.deck.tpl-cctc-cadg .page-footer {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: var(--footer-h);
+ border-top: var(--border-w) solid var(--border);
+ z-index: 2;
+}
+.deck.tpl-cctc-cadg .page-footer .footer-logo {
+ position: absolute;
+ bottom: var(--space-sm);
+ left: var(--body-pad-x);
+ height: var(--space-lg);
+ opacity: 0.85;
+}
+.deck.tpl-cctc-cadg .page-footer .footer-url {
+ position: absolute;
+ bottom: var(--space);
+ right: 5vmin;
+ font-size: var(--mini);
+ color: var(--text-light);
+}
+.deck.tpl-cctc-cadg .page-body {
+ position: absolute;
+ top: var(--header-h);
+ bottom: var(--footer-h);
+ left: 0;
+ right: 0;
+ padding: var(--space-lg) var(--body-pad-x);
+ z-index: 2;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: stretch;
+}
+.deck.tpl-cctc-cadg .page-body ul {
+ padding-left: var(--space-lg);
+ font-size: var(--body);
+ line-height: 1.6;
+}
+.deck.tpl-cctc-cadg .page-body li {
+ margin-bottom: var(--space-sm);
+ font-size: var(--body);
+ line-height: 1.5;
+}
+.deck.tpl-cctc-cadg .page-body li::marker {
+ color: var(--accent-1);
+}
+.deck.tpl-cctc-cadg .page-body h3 {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--text-pri);
+ margin-bottom: var(--space);
+}
+.deck.tpl-cctc-cadg .page-body p {
+ font-size: var(--body);
+ color: var(--text-body);
+ line-height: 1.7;
+}
+.deck.tpl-cctc-cadg .page-body table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: var(--small);
+}
+.deck.tpl-cctc-cadg .page-body th {
+ background: var(--accent-1);
+ color: var(--bg-white);
+ padding: var(--space-sm) 2vmin;
+ text-align: left;
+ font-weight: bold;
+}
+.deck.tpl-cctc-cadg .page-body td {
+ padding: var(--space-sm) 2vmin;
+ border-bottom: var(--border-w) solid var(--border);
+}
+.deck.tpl-cctc-cadg .page-body tr:nth-child(even) {
+ background: var(--bg-alt);
+}
+
+/* ============================================
+ 4. 封面
+ ============================================ */
+.deck.tpl-cctc-cadg .slide-cover {
+ background: var(--bg-white);
+}
+.deck.tpl-cctc-cadg .slide-cover::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ width: var(--red-bar-w);
+ background: var(--accent-1);
+ z-index: 1;
+}
+.deck.tpl-cctc-cadg .slide-cover .dot-grid {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ width: 50%;
+ height: 55%;
+ background-image: radial-gradient(circle, var(--border-light) 1.2px, transparent 1.2px);
+ background-size: var(--space) var(--space);
+ z-index: 0;
+ -webkit-mask-image: linear-gradient(to top left, rgba(0,0,0,0.7) 20%, transparent 70%);
+ mask-image: linear-gradient(to top left, rgba(0,0,0,0.7) 20%, transparent 70%);
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-content {
+ position: absolute;
+ left: calc(var(--red-bar-w) + 4.5vmin);
+ top: 22%;
+ z-index: 2;
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-org {
+ font-size: var(--body);
+ color: var(--text-light);
+ margin-bottom: var(--space-lg);
+ letter-spacing: var(--space-xs);
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-title {
+ font-size: var(--hero);
+ font-weight: bold;
+ color: var(--text-pri);
+ margin-bottom: var(--space-lg);
+ line-height: 1.25;
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-subtitle {
+ font-size: var(--subtitle);
+ color: var(--accent-1);
+ font-weight: bold;
+ margin-bottom: 15vmin;
+ line-height: 1.4;
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-presenter {
+ font-size: var(--body);
+ color: var(--text-muted);
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-presenter p {
+ margin: var(--space-sm) 0;
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-logo {
+ position: absolute;
+ top: var(--space-xl);
+ right: 5vmin;
+ z-index: 3;
+ height: var(--space-xl);
+}
+.deck.tpl-cctc-cadg .slide-cover .cover-url {
+ position: absolute;
+ bottom: var(--space-lg);
+ right: 5vmin;
+ font-size: var(--mini);
+ color: var(--text-light);
+ z-index: 2;
+}
+
+/* ============================================
+ 5. 目录页
+ ============================================ */
+.deck.tpl-cctc-cadg .slide-toc {
+ background: var(--bg-white);
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+}
+.deck.tpl-cctc-cadg .slide-toc .seal-left,
+.deck.tpl-cctc-cadg .slide-toc .seal-right {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ font-family: "KaiTi", "STKaiti", serif;
+ font-size: var(--seal);
+ color: var(--gray-seal);
+ writing-mode: vertical-rl;
+ letter-spacing: var(--space-sm);
+ z-index: 0;
+ user-select: none;
+}
+.deck.tpl-cctc-cadg .slide-toc .seal-left { left: 5%; }
+.deck.tpl-cctc-cadg .slide-toc .seal-right { right: 5%; }
+.deck.tpl-cctc-cadg .slide-toc .toc-title {
+ font-size: var(--display);
+ font-weight: bold;
+ color: var(--text-body);
+ margin-top: 13vmin;
+ margin-bottom: var(--space-xl);
+ z-index: 2;
+ padding-left: var(--space-xl);
+ letter-spacing: var(--space-xs);
+}
+.deck.tpl-cctc-cadg .slide-toc .toc-list {
+ list-style: none;
+ padding: 0 var(--space-xl);
+ z-index: 2;
+ width: 50%;
+}
+.deck.tpl-cctc-cadg .slide-toc .toc-list li {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--text-pri);
+ padding: var(--space) 0;
+ border-bottom: var(--border-w) solid var(--border);
+}
+.deck.tpl-cctc-cadg .slide-toc .toc-list li .toc-num {
+ color: var(--accent-1);
+ margin-right: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .slide-toc .toc-list li .toc-sub {
+ font-size: var(--tag);
+ font-weight: normal;
+ color: var(--text-light);
+ margin-left: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .slide-toc .toc-logo {
+ position: absolute;
+ bottom: var(--space-xl);
+ left: 50%;
+ transform: translateX(-50%);
+ height: var(--space-lg);
+ z-index: 2;
+}
+
+/* ============================================
+ 6. 节标题页
+ ============================================ */
+.deck.tpl-cctc-cadg .slide-section {
+ background: var(--bg-white);
+ align-items: flex-start;
+ justify-content: flex-start;
+}
+.deck.tpl-cctc-cadg .slide-section::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: var(--red-bar-w);
+ height: var(--header-h);
+ background: var(--accent-1);
+ z-index: 2;
+}
+.deck.tpl-cctc-cadg .slide-section .section-body {
+ position: absolute;
+ top: var(--header-h);
+ bottom: var(--footer-h);
+ left: 19vmin;
+ right: 0;
+ padding: var(--space-xl) var(--body-pad-x);
+ z-index: 2;
+}
+.deck.tpl-cctc-cadg .slide-section .section-num {
+ font-size: var(--section-num);
+ font-weight: bold;
+ color: var(--accent-1);
+ opacity: 0.12;
+ position: absolute;
+ left: -10vmin;
+ top: 0;
+ z-index: 1;
+}
+.deck.tpl-cctc-cadg .slide-section .section-main-title {
+ font-size: var(--display);
+ font-weight: bold;
+ color: var(--accent-1);
+ margin-bottom: var(--space);
+ z-index: 2;
+ position: relative;
+}
+.deck.tpl-cctc-cadg .slide-section .section-main-title::after {
+ content: "";
+ display: block;
+ width: var(--space-xl);
+ height: var(--med);
+ background: var(--accent-2);
+ margin-top: var(--space);
+}
+.deck.tpl-cctc-cadg .slide-section .section-subtitle {
+ font-size: var(--body);
+ color: var(--text-muted);
+ z-index: 2;
+ position: relative;
+ margin-top: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .slide-section .page-footer {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: var(--footer-h);
+ border-top: var(--border-w) solid var(--border);
+ z-index: 2;
+}
+.deck.tpl-cctc-cadg .slide-section .page-footer .footer-url {
+ position: absolute;
+ bottom: var(--space);
+ right: 5vmin;
+ font-size: var(--mini);
+ color: var(--text-light);
+}
+
+/* ============================================
+ 7. 感谢页
+ ============================================ */
+.deck.tpl-cctc-cadg .slide-thanks {
+ background: var(--bg-white);
+ flex-direction: column;
+}
+.deck.tpl-cctc-cadg .slide-thanks::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: var(--red-bar-w);
+ height: auto;
+ min-height: 28vmin;
+ background: var(--accent-1);
+ z-index: 1;
+}
+.deck.tpl-cctc-cadg .slide-thanks .thanks-logo {
+ position: absolute;
+ top: var(--space-xl);
+ right: 5vmin;
+ z-index: 3;
+ height: var(--space-xl);
+}
+.deck.tpl-cctc-cadg .slide-thanks .thanks-pattern {
+ position: absolute;
+ bottom: var(--header-h);
+ left: calc(var(--red-bar-w) + 4vmin);
+ right: 5vmin;
+ height: 13vmin;
+ background:
+ repeating-linear-gradient(45deg, transparent, transparent 3.5vmin, var(--gray-pattern) 3.5vmin, var(--gray-pattern) calc(3.5vmin + 1px)),
+ repeating-linear-gradient(-45deg, transparent, transparent 3.5vmin, var(--gray-pattern) 3.5vmin, var(--gray-pattern) calc(3.5vmin + 1px));
+ z-index: 1;
+}
+.deck.tpl-cctc-cadg .slide-thanks .thanks-text {
+ font-size: var(--thanks);
+ font-weight: bold;
+ color: var(--text-muted);
+ z-index: 2;
+ position: absolute;
+ left: 0;
+ right: 0;
+ text-align: center;
+ bottom: 20vmin;
+}
+.deck.tpl-cctc-cadg .slide-thanks .thanks-url {
+ position: absolute;
+ bottom: var(--space-lg);
+ right: 5vmin;
+ font-size: var(--mini);
+ color: var(--text-light);
+ z-index: 2;
+}
+
+/* ============================================
+ 8. 运行时 UI 样式
+ ============================================ */
+.deck.tpl-cctc-cadg .progress-bar {
+ background: var(--accent-1);
+}
+.deck.tpl-cctc-cadg .deck-footer { display: none; }
+.notes-overlay { display: none; }
+.notes-overlay.open { display: block; }
+.overview { display: none; }
+.overview.open { display: block; }
+
+/* ============================================
+ 9. 布局组件
+ ============================================ */
+.deck.tpl-cctc-cadg .two-col {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-lg);
+ min-height: 28vmin;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .three-col {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: var(--space);
+ min-height: 18vmin;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .four-col {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: var(--space);
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .step-flow {
+ display: flex;
+ align-items: center;
+ gap: var(--space-sm);
+ margin: var(--space) 0;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .step-item {
+ background: var(--bg-card);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ text-align: center;
+ border: var(--border-w) solid var(--border);
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .step-item .step-num {
+ font-size: 4vmin;
+ font-weight: bold;
+ color: var(--accent-1);
+ display: block;
+ margin-bottom: 1vmin;
+}
+.deck.tpl-cctc-cadg .step-item .step-label {
+ font-size: var(--body);
+ font-weight: bold;
+ color: var(--text-pri);
+ display: block;
+}
+.deck.tpl-cctc-cadg .step-item .step-desc {
+ font-size: var(--tag);
+ color: var(--text-muted);
+ margin-top: var(--space-xs);
+ display: block;
+}
+.deck.tpl-cctc-cadg .step-arrow {
+ font-size: var(--body);
+ color: var(--border-light);
+}
+.deck.tpl-cctc-cadg .center-layout {
+ text-align: center;
+ max-width: 70%;
+ margin: 0 auto;
+}
+.deck.tpl-cctc-cadg .center-layout .cl-icon {
+ font-size: 8vmin;
+ margin-bottom: var(--space);
+}
+.deck.tpl-cctc-cadg .center-layout .cl-title {
+ font-size: 4vmin;
+ font-weight: bold;
+ color: var(--text-pri);
+ margin-bottom: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .center-layout .cl-desc {
+ font-size: var(--body);
+ color: #555;
+ line-height: 1.6;
+}
+
+/* ============================================
+ 10. 图文布局
+ ============================================ */
+.deck.tpl-cctc-cadg .illustration-left,
+.deck.tpl-cctc-cadg .illustration-right {
+ display: flex;
+ gap: var(--space-lg);
+ align-items: center;
+}
+.deck.tpl-cctc-cadg .illustration-left .image-container,
+.deck.tpl-cctc-cadg .illustration-right .image-container {
+ flex: 0 0 45%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 0.4vmin;
+}
+.deck.tpl-cctc-cadg .illustration-left .image-container img,
+.deck.tpl-cctc-cadg .illustration-right .image-container img {
+ max-height: var(--img-max-standard);
+ width: auto;
+ object-fit: contain;
+}
+.deck.tpl-cctc-cadg .illustration-left .text-container,
+.deck.tpl-cctc-cadg .illustration-right .text-container {
+ flex: 1;
+}
+
+.deck.tpl-cctc-cadg .illustration-left.wide,
+.deck.tpl-cctc-cadg .illustration-right.wide {
+ display: flex;
+ gap: var(--space-lg);
+ align-items: center;
+}
+.deck.tpl-cctc-cadg .illustration-left.wide .image-container,
+.deck.tpl-cctc-cadg .illustration-right.wide .image-container {
+ flex: 0 0 55%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 0.4vmin;
+}
+.deck.tpl-cctc-cadg .illustration-left.wide .image-container img,
+.deck.tpl-cctc-cadg .illustration-right.wide .image-container img {
+ max-height: var(--img-max-wide);
+ width: 100%;
+ object-fit: contain;
+}
+.deck.tpl-cctc-cadg .illustration-left.wide .text-container,
+.deck.tpl-cctc-cadg .illustration-right.wide .text-container {
+ flex: 1;
+}
+
+.deck.tpl-cctc-cadg .showcase-image {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ flex: 1;
+ gap: var(--space);
+}
+.deck.tpl-cctc-cadg .showcase-image .image-container {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+.deck.tpl-cctc-cadg .showcase-image .image-container img {
+ max-height: var(--img-max-showcase);
+ width: 100%;
+ object-fit: contain;
+}
+.deck.tpl-cctc-cadg .showcase-image .image-caption {
+ font-size: var(--tag);
+ color: var(--text-muted);
+ text-align: center;
+}
+
+.deck.tpl-cctc-cadg .dual-image-compare {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-lg);
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .dual-image-compare .compare-panel {
+ display: flex;
+ flex-direction: column;
+ background: var(--bg-card);
+ border-radius: 0.8vmin;
+ border: 1px solid var(--border-light);
+ overflow: hidden;
+}
+.deck.tpl-cctc-cadg .dual-image-compare .compare-label {
+ font-size: var(--tag);
+ font-weight: bold;
+ color: var(--accent-1);
+ padding: 1vmin 1.5vmin;
+ background: var(--accent-light);
+ text-align: center;
+}
+.deck.tpl-cctc-cadg .dual-image-compare .image-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 1vmin;
+}
+.deck.tpl-cctc-cadg .dual-image-compare .image-container img {
+ max-height: var(--img-max-compare);
+ width: 100%;
+ object-fit: contain;
+}
+
+/* ============================================
+ 多图网格布局
+ ============================================ */
+.deck.tpl-cctc-cadg .image-grid-1x3 {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1.5vmin;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .image-grid-1x4 {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 0.8vmin;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .image-grid-1x5 {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 0.6vmin;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .image-grid-1x3 .grid-img-item,
+.deck.tpl-cctc-cadg .image-grid-1x4 .grid-img-item,
+.deck.tpl-cctc-cadg .image-grid-1x5 .grid-img-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ overflow: hidden;
+}
+.deck.tpl-cctc-cadg .image-grid-1x3 .grid-img-item img,
+.deck.tpl-cctc-cadg .image-grid-1x4 .grid-img-item img,
+.deck.tpl-cctc-cadg .image-grid-1x5 .grid-img-item img {
+ max-height: var(--img-max-grid);
+ width: 100%;
+ object-fit: contain;
+}
+.deck.tpl-cctc-cadg .image-grid-1x3 .grid-img-caption,
+.deck.tpl-cctc-cadg .image-grid-1x4 .grid-img-caption,
+.deck.tpl-cctc-cadg .image-grid-1x5 .grid-img-caption {
+ font-size: 1.4vmin;
+ color: var(--text-muted);
+ text-align: center;
+ margin-top: 0.2vmin;
+ line-height: 1.2;
+}
+
+.deck.tpl-cctc-cadg .hybrid-text-grid {
+ display: flex;
+ gap: 1.5vmin;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-text {
+ flex: 0 0 38%;
+ display: flex;
+ flex-direction: column;
+ gap: 0.8vmin;
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-text p,
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-text li {
+ font-size: 2.4vmin;
+ line-height: 1.4;
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-grid {
+ flex: 1;
+ display: grid;
+ gap: 0.8vmin;
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-grid.grid-2col {
+ grid-template-columns: repeat(2, 1fr);
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-grid.grid-3col {
+ grid-template-columns: repeat(3, 1fr);
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-grid .grid-img-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ overflow: hidden;
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-grid .grid-img-item img {
+ max-height: 20vmin;
+ width: 100%;
+ object-fit: contain;
+}
+.deck.tpl-cctc-cadg .hybrid-text-grid .hybrid-grid .grid-img-item .grid-img-caption {
+ font-size: 1.3vmin;
+ color: var(--text-muted);
+ text-align: center;
+ margin-top: 0.2vmin;
+ line-height: 1.2;
+}
+
+/* 图注 */
+.image-caption {
+ margin-top: 0.4vmin;
+ font-size: 1.6vmin;
+ color: #555;
+ text-align: center;
+ line-height: 1.35;
+ font-style: normal;
+}
+.showcase-image .image-caption {
+ margin-top: 0.6vmin;
+}
+
+/* ============================================
+ 11. 卡片组件
+ ============================================ */
+.deck.tpl-cctc-cadg .kpi-card {
+ background: var(--bg-card);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ text-align: center;
+ border: var(--border-w) solid var(--border);
+}
+.deck.tpl-cctc-cadg .kpi-card .kpi-value {
+ font-size: var(--kpi);
+ font-weight: bold;
+ color: var(--accent-1);
+ display: block;
+ margin-bottom: 1vmin;
+}
+.deck.tpl-cctc-cadg .kpi-card .kpi-label {
+ font-size: var(--body);
+ font-weight: bold;
+ color: var(--text-pri);
+ display: block;
+}
+.deck.tpl-cctc-cadg .kpi-card .kpi-desc {
+ font-size: var(--tag);
+ color: var(--text-muted);
+ margin-top: var(--space-xs);
+ display: block;
+}
+
+.deck.tpl-cctc-cadg .content-card {
+ background: var(--bg-card);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ margin-bottom: var(--space);
+ border: var(--border-w) solid var(--border);
+ font-size: var(--small);
+ color: var(--text-body);
+ line-height: 1.6;
+}
+.deck.tpl-cctc-cadg .content-card .card-title {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--accent-1);
+ margin-bottom: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .content-card .card-body {
+ font-size: var(--body);
+ line-height: 1.6;
+}
+
+.deck.tpl-cctc-cadg .comp-box {
+ background: var(--bg-card);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ border: var(--border-w) solid var(--border);
+ font-size: var(--small);
+ color: var(--text-body);
+ line-height: 1.6;
+ align-self: start;
+}
+.deck.tpl-cctc-cadg .comp-box .comp-title {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--accent-1);
+ margin-bottom: var(--space-sm);
+ text-align: center;
+}
+.deck.tpl-cctc-cadg .comp-box .comp-desc {
+ font-size: var(--body);
+ line-height: 1.6;
+}
+.deck.tpl-cctc-cadg .comp-box .comp-features {
+ margin-top: var(--space-sm);
+ padding-left: 2vmin;
+}
+.deck.tpl-cctc-cadg .comp-box .comp-features li {
+ font-size: var(--body);
+ margin-bottom: var(--space-xs);
+ line-height: 1.5;
+}
+.deck.tpl-cctc-cadg .comp-box h3 {
+ font-size: var(--heading);
+ margin-bottom: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .comp-box ul {
+ font-size: var(--body);
+ padding-left: var(--space-xl);
+}
+.deck.tpl-cctc-cadg .comp-box.bad { border-color: var(--danger); }
+.deck.tpl-cctc-cadg .comp-box.good { border-color: var(--success); }
+.deck.tpl-cctc-cadg .comp-box.neutral { border-color: var(--text-muted); background: var(--bg-alt); }
+
+.deck.tpl-cctc-cadg .quote-box {
+ background: var(--accent-light);
+ border-left: var(--med) solid var(--accent-1);
+ padding: var(--space) 2vmin;
+ margin: var(--space) 0;
+ border-radius: 0 0.8vmin 0.8vmin 0;
+ font-size: var(--small);
+ color: var(--text-body);
+ line-height: 1.6;
+}
+.deck.tpl-cctc-cadg .quote-box .quote-text {
+ font-size: var(--body);
+ font-style: italic;
+ line-height: 1.6;
+}
+.deck.tpl-cctc-cadg .quote-box .quote-source {
+ font-size: var(--tag);
+ color: var(--text-muted);
+ margin-top: var(--space-xs);
+}
+
+.deck.tpl-cctc-cadg .conclusion-box {
+ background: var(--accent-light);
+ border: var(--border-w) solid var(--accent-1);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ margin: var(--space) 0;
+}
+.deck.tpl-cctc-cadg .conclusion-box .conclusion-title {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--accent-1);
+ margin-bottom: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .conclusion-box .conclusion-body {
+ font-size: var(--body);
+ line-height: 1.6;
+}
+
+.deck.tpl-cctc-cadg .ref-block {
+ background: var(--bg-card);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ border: var(--border-w) solid var(--border);
+ margin: var(--space) 0;
+}
+.deck.tpl-cctc-cadg .ref-block .ref-title {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--accent-1);
+ margin-bottom: var(--space-sm);
+}
+.deck.tpl-cctc-cadg .ref-block .ref-body {
+ font-size: var(--body);
+ line-height: 1.6;
+}
+
+.deck.tpl-cctc-cadg .data-panel {
+ background: var(--bg-card);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ border: var(--border-w) solid var(--border);
+}
+.deck.tpl-cctc-cadg .data-panel .panel-title {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--accent-1);
+ margin-bottom: var(--space-sm);
+ text-align: center;
+}
+.deck.tpl-cctc-cadg .data-panel .panel-body {
+ font-size: var(--body);
+ line-height: 1.6;
+}
+
+.deck.tpl-cctc-cadg .param-cards {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(25vmin, 1fr));
+ gap: var(--space);
+ margin: var(--space) 0;
+}
+.deck.tpl-cctc-cadg .param-card {
+ background: var(--bg-card);
+ padding: var(--space) 2vmin;
+ border-radius: 0.8vmin;
+ border: var(--border-w) solid var(--border);
+ text-align: center;
+}
+.deck.tpl-cctc-cadg .param-card .param-name {
+ font-size: var(--body);
+ font-weight: bold;
+ color: var(--text-pri);
+ margin-bottom: var(--space-xs);
+}
+.deck.tpl-cctc-cadg .param-card .param-value {
+ font-size: var(--heading);
+ font-weight: bold;
+ color: var(--accent-1);
+}
+.deck.tpl-cctc-cadg .param-card .param-unit {
+ font-size: var(--tag);
+ color: var(--text-muted);
+ margin-left: var(--space-xs);
+}
+
+/* ============================================
+ 12. 图表组件
+ ============================================ */
+.deck.tpl-cctc-cadg .system-diagram {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-sm);
+ min-height: 28vmin;
+ flex: 1;
+}
+.deck.tpl-cctc-cadg .diagram-layer {
+ padding: var(--space);
+ border-radius: 0.8vmin;
+ text-align: center;
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: var(--tag);
+ line-height: 1.6;
+ box-sizing: border-box;
+}
+.deck.tpl-cctc-cadg .diagram-layer.input {
+ background: var(--accent-light);
+ border-left: var(--med) solid var(--accent-1);
+ font-size: var(--body);
+}
+.deck.tpl-cctc-cadg .diagram-layer.core {
+ background: var(--accent-mid);
+ border-left: var(--med) solid var(--accent-1);
+ font-weight: bold;
+ font-size: var(--body);
+}
+.deck.tpl-cctc-cadg .diagram-layer.output {
+ background: var(--bg-card);
+ border-left: var(--med) solid var(--text-light);
+ font-size: var(--body);
+}
+
+.deck.tpl-cctc-cadg .research-framework {
+ display: flex;
+ gap: var(--space-sm);
+ align-items: stretch;
+}
+.deck.tpl-cctc-cadg .research-framework .rf-column {
+ flex: 1;
+ background: var(--bg-card);
+ border-radius: 0.8vmin;
+ padding: var(--space);
+ display: flex;
+ flex-direction: column;
+}
+.deck.tpl-cctc-cadg .research-framework .rf-header {
+ font-size: var(--body);
+ font-weight: bold;
+ color: var(--accent-1);
+ margin-bottom: var(--space-sm);
+ padding-bottom: var(--space-sm);
+ border-bottom: var(--border-w) solid var(--border);
+}
+.deck.tpl-cctc-cadg .research-framework .rf-body {
+ flex: 1;
+ font-size: var(--body);
+ color: var(--text-body);
+ line-height: 1.6;
+}
+.deck.tpl-cctc-cadg .research-framework .rf-arrow {
+ flex: 0 0 var(--space);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: var(--body);
+ color: var(--border-light);
+}
+
+.deck.tpl-cctc-cadg .equation-block {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space);
+ padding: var(--space) 0;
+}
+.deck.tpl-cctc-cadg .equation-block .equation-text {
+ font-size: var(--heading);
+ font-family: "Times New Roman", "STSong", serif;
+}
+.deck.tpl-cctc-cadg .equation-block .equation-num {
+ font-size: var(--small);
+ color: var(--text-muted);
+}
+.deck.tpl-cctc-cadg .equation-notes {
+ font-size: var(--tag);
+ color: var(--text-muted);
+ margin-top: var(--space-sm);
+ padding-left: var(--space-xl);
+}
+
+/* ============================================
+ 13. 工具类
+ ============================================ */
+.deck.tpl-cctc-cadg .sci-table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: var(--body);
+}
+.deck.tpl-cctc-cadg .sci-table thead tr {
+ border-top: var(--med) solid var(--text-pri);
+ border-bottom: var(--border-w) solid var(--text-pri);
+}
+.deck.tpl-cctc-cadg .sci-table th {
+ background: none;
+ color: var(--text-pri);
+ padding: var(--space-sm) 2vmin;
+ text-align: left;
+ font-weight: bold;
+}
+.deck.tpl-cctc-cadg .sci-table td {
+ padding: var(--space-sm) 2vmin;
+ border-bottom: var(--hair) solid var(--border);
+}
+.deck.tpl-cctc-cadg .sci-table tbody tr:last-child {
+ border-bottom: var(--med) solid var(--text-pri);
+}
+
+.deck.tpl-cctc-cadg .text-small { font-size: var(--small); }
+.deck.tpl-cctc-cadg .text-body { font-size: var(--body); }
+.deck.tpl-cctc-cadg .text-heading { font-size: var(--heading); }
+.deck.tpl-cctc-cadg .text-display { font-size: var(--display); }
+.deck.tpl-cctc-cadg .text-bold { font-weight: bold; }
+.deck.tpl-cctc-cadg .icon-lg { font-size: var(--display); margin-bottom: 1.5vmin; }
+
+.deck.tpl-cctc-cadg .text-accent { color: var(--accent-1); }
+.deck.tpl-cctc-cadg .text-muted { color: var(--text-muted); }
+.deck.tpl-cctc-cadg .text-danger { color: var(--danger); }
+.deck.tpl-cctc-cadg .text-success { color: var(--success); }
+.deck.tpl-cctc-cadg .text-center { text-align: center; }
+.deck.tpl-cctc-cadg .text-left { text-align: left; }
+.deck.tpl-cctc-cadg .text-right { text-align: right; }
+.deck.tpl-cctc-cadg .bg-accent-light { background: var(--accent-light); }
+
+.deck.tpl-cctc-cadg .flex { display: flex; }
+.deck.tpl-cctc-cadg .flex-1 { flex: 1; }
+.deck.tpl-cctc-cadg .flex-1-2 { flex: 1.2; }
+.deck.tpl-cctc-cadg .flex-col { flex-direction: column; }
+.deck.tpl-cctc-cadg .items-center { align-items: center; }
+.deck.tpl-cctc-cadg .items-stretch { align-items: stretch; }
+.deck.tpl-cctc-cadg .justify-center { justify-content: center; }
+.deck.tpl-cctc-cadg .justify-start { justify-content: flex-start; }
+.deck.tpl-cctc-cadg .justify-end { justify-content: flex-end; }
+
+.deck.tpl-cctc-cadg .mb-3 { margin-bottom: 3vmin; }
+.deck.tpl-cctc-cadg .mb-2 { margin-bottom: 2vmin; }
+.deck.tpl-cctc-cadg .mb-1-5 { margin-bottom: 1.5vmin; }
+.deck.tpl-cctc-cadg .mb-1-2 { margin-bottom: 1.2vmin; }
+.deck.tpl-cctc-cadg .mb-1 { margin-bottom: 1vmin; }
+.deck.tpl-cctc-cadg .mb-0-5 { margin-bottom: 0.5vmin; }
+.deck.tpl-cctc-cadg .mb-0-4 { margin-bottom: 0.4vmin; }
+.deck.tpl-cctc-cadg .mt-3 { margin-top: 3vmin; }
+.deck.tpl-cctc-cadg .mt-2 { margin-top: 2vmin; }
+.deck.tpl-cctc-cadg .mt-1-5 { margin-top: 1.5vmin; }
+.deck.tpl-cctc-cadg .mt-1 { margin-top: 1vmin; }
+.deck.tpl-cctc-cadg .m-0 { margin: 0; }
+.deck.tpl-cctc-cadg .p-2 { padding: 2vmin; }
+.deck.tpl-cctc-cadg .pl-1-5 { padding-left: 1.5vmin; }
+.deck.tpl-cctc-cadg .gap-3 { gap: 3vmin; }
+.deck.tpl-cctc-cadg .gap-1-5 { gap: 1.5vmin; }
+.deck.tpl-cctc-cadg .gap-1 { gap: 1vmin; }
+.deck.tpl-cctc-cadg .gap-0-8 { gap: 0.8vmin; }
+
+.deck.tpl-cctc-cadg .border-accent { border: var(--med) solid var(--accent-1); }
+.deck.tpl-cctc-cadg .border-top-accent { border-top: 0.4vmin solid var(--accent-1); }
+.deck.tpl-cctc-cadg .border-top-success { border-top: 0.4vmin solid var(--success); }
+.deck.tpl-cctc-cadg .rounded-sm { border-radius: 0.8vmin; }
+
+.deck.tpl-cctc-cadg .overflow-hidden { overflow: hidden; }
+.deck.tpl-cctc-cadg .w-80 { width: 80%; }
+.deck.tpl-cctc-cadg .w-full { width: 100%; }
+.deck.tpl-cctc-cadg .max-h-32 { max-height: 32vmin; }
+.deck.tpl-cctc-cadg .leading-4 { line-height: 1.4; }
+.deck.tpl-cctc-cadg .leading-6 { line-height: 1.6; }
+.deck.tpl-cctc-cadg .leading-8 { line-height: 1.8; }
+
+/* 紧凑变体 */
+.deck.tpl-cctc-cadg .text-compact { font-size: 2.4vmin !important; line-height: 1.4 !important; }
+.deck.tpl-cctc-cadg .text-compact-sm { font-size: 2vmin !important; line-height: 1.3 !important; }
+.deck.tpl-cctc-cadg .heading-compact { font-size: 3.2vmin !important; line-height: 1.3 !important; }
+.deck.tpl-cctc-cadg .comp-box.compact { padding: 1vmin 1.5vmin !important; }
+.deck.tpl-cctc-cadg .comp-box.compact .comp-title { font-size: 2.6vmin !important; margin-bottom: 0.3vmin !important; }
+.deck.tpl-cctc-cadg .comp-box.compact .comp-desc,
+.deck.tpl-cctc-cadg .comp-box.compact ul,
+.deck.tpl-cctc-cadg .comp-box.compact li { font-size: 2.2vmin !important; line-height: 1.35 !important; }
+.deck.tpl-cctc-cadg .comp-box.compact ul { padding-left: 1.5vmin !important; }
+.deck.tpl-cctc-cadg .comp-box.compact li { margin-bottom: 0.2vmin !important; }
+.deck.tpl-cctc-cadg .gap-compact { gap: 0.8vmin !important; }
+.deck.tpl-cctc-cadg .mb-compact { margin-bottom: 0.8vmin !important; }
+
+/* 溢出检测 */
+.deck.tpl-cctc-cadg .page-body.overflow-warning {
+ outline: 1px dashed var(--danger);
+}
+
+/* ===== 打印 / 导出 PDF ===== */
+/* 使用 Chrome headless:
+ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
+ --headless=new --disable-gpu \
+ --print-to-pdf="/path/to/output.pdf" \
+ "file:///path/to/presentation.html"
+*/
+@page { size: 10in 5.625in; margin: 0; }
+@media print {
+ html, body {
+ width: 10in; height: auto; margin: 0; padding: 0;
+ -webkit-print-color-adjust: exact; print-color-adjust: exact;
+ background: white;
+ }
+ .deck.tpl-cctc-cadg {
+ position: static; width: 10in; height: auto; overflow: visible;
+ background: white;
+ }
+ .deck.tpl-cctc-cadg .slide {
+ position: relative !important;
+ width: 10in; height: auto;
+ max-height: 5.625in; aspect-ratio: 16 / 9;
+ opacity: 1 !important; transform: none !important;
+ display: flex !important; flex-direction: column;
+ page-break-after: always; page-break-inside: avoid;
+ margin: 0; padding: 0; overflow: hidden;
+ box-sizing: border-box;
+ -webkit-print-color-adjust: exact; print-color-adjust: exact;
+ background: var(--bg-white);
+ z-index: auto; pointer-events: auto !important;
+ }
+ .deck.tpl-cctc-cadg .slide.is-active,
+ .deck.tpl-cctc-cadg .slide.is-prev {
+ transform: none; opacity: 1;
+ }
+ /* Override absolute positioning on slide sub-types */
+ .deck.tpl-cctc-cadg .slide-cover,
+ .deck.tpl-cctc-cadg .slide-toc,
+ .deck.tpl-cctc-cadg .slide-section,
+ .deck.tpl-cctc-cadg .slide-content,
+ .deck.tpl-cctc-cadg .slide-thanks {
+ position: relative !important;
+ }
+ /* Hide runtime chrome */
+ .progress-bar, .notes-overlay, .overview, aside.notes { display: none !important; }
+ /* Kill animations */
+ * { animation: none !important; transition: none !important; }
+}
diff --git a/pres/assets/images/cctc-cadg/banner.png b/pres/assets/images/cctc-cadg/banner.png
new file mode 100644
index 0000000..e35a015
Binary files /dev/null and b/pres/assets/images/cctc-cadg/banner.png differ
diff --git a/pres/assets/images/cctc-cadg/contents-bg.jpg b/pres/assets/images/cctc-cadg/contents-bg.jpg
new file mode 100644
index 0000000..2125e19
Binary files /dev/null and b/pres/assets/images/cctc-cadg/contents-bg.jpg differ
diff --git a/pres/assets/images/cctc-cadg/cover-bg.jpg b/pres/assets/images/cctc-cadg/cover-bg.jpg
new file mode 100644
index 0000000..06c73c9
Binary files /dev/null and b/pres/assets/images/cctc-cadg/cover-bg.jpg differ
diff --git a/pres/assets/images/cctc-cadg/header-bg.jpg b/pres/assets/images/cctc-cadg/header-bg.jpg
new file mode 100644
index 0000000..a9d0c36
Binary files /dev/null and b/pres/assets/images/cctc-cadg/header-bg.jpg differ
diff --git a/pres/assets/images/cctc-cadg/header.jpg b/pres/assets/images/cctc-cadg/header.jpg
new file mode 100644
index 0000000..a9d0c36
Binary files /dev/null and b/pres/assets/images/cctc-cadg/header.jpg differ
diff --git a/pres/assets/images/cctc-cadg/logo.png b/pres/assets/images/cctc-cadg/logo.png
new file mode 100644
index 0000000..e8f7cbe
Binary files /dev/null and b/pres/assets/images/cctc-cadg/logo.png differ
diff --git a/pres/assets/runtime.js b/pres/assets/runtime.js
new file mode 100644
index 0000000..9d9ee95
--- /dev/null
+++ b/pres/assets/runtime.js
@@ -0,0 +1,1003 @@
+/* html-ppt :: runtime.js
+ * Keyboard-driven deck runtime. Zero dependencies.
+ *
+ * Features:
+ * ← → / space / PgUp PgDn / Home End navigation
+ * F fullscreen
+ * S presenter mode (opens a NEW WINDOW with current/next slide preview + notes + timer)
+ * The original window stays as audience view, synced via BroadcastChannel.
+ * Slide previews use CSS transform:scale() at design resolution for pixel-perfect layout.
+ * N quick notes overlay (bottom drawer)
+ * O slide overview grid
+ * T cycle themes (reads data-themes on or
)
+ * A cycle demo animation on current slide
+ * URL hash #/N deep-link to slide N (1-based)
+ * Progress bar auto-managed
+ */
+(function () {
+ 'use strict';
+
+ const ANIMS = ['fade-up','fade-down','fade-left','fade-right','rise-in','drop-in',
+ 'zoom-pop','blur-in','glitch-in','typewriter','neon-glow','shimmer-sweep',
+ 'gradient-flow','stagger-list','counter-up','path-draw','parallax-tilt',
+ 'card-flip-3d','cube-rotate-3d','page-turn-3d','perspective-zoom',
+ 'marquee-scroll','kenburns','confetti-burst','spotlight','morph-shape','ripple-reveal'];
+
+ function ready(fn){ if(document.readyState!='loading')fn(); else document.addEventListener('DOMContentLoaded',fn);}
+
+ /* ========== Parse URL for preview-only mode ==========
+ * When loaded as iframe.src = "index.html?preview=3", runtime enters a
+ * locked single-slide mode: only slide N is visible, no chrome, no keys,
+ * no hash updates. This is how the presenter window shows pixel-perfect
+ * previews — by loading the actual deck file in an iframe and telling it
+ * to display only a specific slide.
+ */
+ function getPreviewIdx() {
+ const m = /[?&]preview=(\d+)/.exec(location.search || '');
+ return m ? parseInt(m[1], 10) - 1 : -1;
+ }
+
+ ready(function () {
+ const deck = document.querySelector('.deck');
+ if (!deck) return;
+ const slides = Array.from(deck.querySelectorAll('.slide'));
+ if (!slides.length) return;
+
+ const previewOnlyIdx = getPreviewIdx();
+ const isPreviewMode = previewOnlyIdx >= 0 && previewOnlyIdx < slides.length;
+
+ /* ===== Preview-only mode: show one slide, hide everything else ===== */
+ if (isPreviewMode) {
+ function showSlide(i) {
+ slides.forEach((s, j) => {
+ const active = (j === i);
+ s.classList.toggle('is-active', active);
+ s.style.display = active ? '' : 'none';
+ if (active) {
+ s.style.opacity = '1';
+ s.style.transform = 'none';
+ s.style.pointerEvents = 'auto';
+ }
+ });
+ }
+ showSlide(previewOnlyIdx);
+ /* Hide chrome that the presenter shouldn't see in preview */
+ const hideSel = '.progress-bar, .notes-overlay, .overview, .notes, aside.notes, .speaker-notes';
+ document.querySelectorAll(hideSel).forEach(el => { el.style.display = 'none'; });
+ document.documentElement.setAttribute('data-preview', '1');
+ document.body.setAttribute('data-preview', '1');
+ /* Auto-detect theme base path for theme switching in preview mode */
+ function getPreviewThemeBase() {
+ const base = document.documentElement.getAttribute('data-theme-base');
+ if (base) return base;
+ const tl = document.getElementById('theme-link');
+ if (tl) {
+ const raw = tl.getAttribute('href') || '';
+ const ls = raw.lastIndexOf('/');
+ if (ls >= 0) return raw.substring(0, ls + 1);
+ }
+ return 'assets/themes/';
+ }
+ const previewThemeBase = getPreviewThemeBase();
+
+ /* Listen for postMessage from parent presenter window:
+ * - preview-goto: switch visible slide WITHOUT reloading
+ * - preview-theme: switch theme CSS link to match audience window */
+ window.addEventListener('message', function(e) {
+ if (!e.data) return;
+ if (e.data.type === 'preview-goto') {
+ const n = parseInt(e.data.idx, 10);
+ if (n >= 0 && n < slides.length) showSlide(n);
+ } else if (e.data.type === 'preview-theme' && e.data.name) {
+ let link = document.getElementById('theme-link');
+ if (!link) {
+ link = document.createElement('link');
+ link.rel = 'stylesheet';
+ link.id = 'theme-link';
+ document.head.appendChild(link);
+ }
+ link.href = previewThemeBase + e.data.name + '.css';
+ document.documentElement.setAttribute('data-theme', e.data.name);
+ }
+ });
+ /* Signal to parent that preview iframe is ready */
+ try { window.parent && window.parent.postMessage({ type: 'preview-ready' }, '*'); } catch(e) {}
+ return;
+ }
+
+ let idx = 0;
+ const total = slides.length;
+
+ /* ===== BroadcastChannel for presenter sync ===== */
+ const CHANNEL_NAME = 'html-ppt-presenter-' + location.pathname;
+ let bc;
+ try { bc = new BroadcastChannel(CHANNEL_NAME); } catch(e) { bc = null; }
+
+ // Are we running inside the presenter popup? (legacy flag, now unused)
+ const isPresenterWindow = false;
+
+ /* ===== progress bar ===== */
+ let bar = document.querySelector('.progress-bar');
+ if (!bar) {
+ bar = document.createElement('div');
+ bar.className = 'progress-bar';
+ bar.innerHTML = '';
+ document.body.appendChild(bar);
+ }
+ const barFill = bar.querySelector('span');
+
+ /* ===== notes overlay (N key) ===== */
+ let notes = document.querySelector('.notes-overlay');
+ if (!notes) {
+ notes = document.createElement('div');
+ notes.className = 'notes-overlay';
+ document.body.appendChild(notes);
+ }
+
+ /* ===== overview grid (O key) ===== */
+ let overview = document.querySelector('.overview');
+ if (!overview) {
+ overview = document.createElement('div');
+ overview.className = 'overview';
+ slides.forEach((s, i) => {
+ const t = document.createElement('div');
+ t.className = 'thumb';
+ // Force 16:9 aspect ratio robustly
+ t.style.padding = '0 0 56.25% 0';
+ t.style.height = '0';
+ t.style.position = 'relative';
+ t.style.overflow = 'hidden';
+
+ const title = s.getAttribute('data-title') ||
+ (s.querySelector('h1,h2,h3')||{}).textContent || ('Slide '+(i+1));
+
+ // Create a container for the mini-slide
+ const mini = document.createElement('div');
+ mini.className = 'mini-slide';
+ mini.style.position = 'absolute';
+ mini.style.top = '0';
+ mini.style.left = '0';
+ mini.style.width = '1920px';
+ mini.style.height = '1080px';
+ mini.style.transformOrigin = 'top left';
+ mini.style.pointerEvents = 'none';
+ mini.style.background = 'var(--bg)';
+
+ // Clone the slide content
+ const clone = s.cloneNode(true);
+ clone.className = 'slide is-active'; // force active styles
+ clone.style.position = 'absolute';
+ clone.style.inset = '0';
+ clone.style.transform = 'none';
+ clone.style.opacity = '1';
+ clone.style.padding = '72px 96px'; // ensure padding is kept
+
+ mini.appendChild(clone);
+ t.appendChild(mini);
+
+ // Add the number and title overlay
+ const overlay = document.createElement('div');
+ overlay.style.position = 'absolute';
+ overlay.style.inset = '0';
+ overlay.style.background = 'linear-gradient(to bottom, rgba(0,0,0,0.2) 0%, transparent 40%, transparent 60%, rgba(0,0,0,0.8) 100%)';
+ overlay.style.color = '#fff';
+ overlay.style.zIndex = '10';
+ overlay.style.pointerEvents = 'none';
+
+ const n = document.createElement('div');
+ n.className = 'n';
+ n.textContent = i + 1;
+ n.style.position = 'absolute';
+ n.style.top = '12px';
+ n.style.left = '16px';
+ n.style.fontWeight = '700';
+ n.style.fontSize = '16px';
+ n.style.color = '#fff';
+ n.style.textShadow = '0 1px 4px rgba(0,0,0,0.8)';
+
+ const text = document.createElement('div');
+ text.className = 't';
+ text.textContent = title.trim().slice(0,80);
+ text.style.position = 'absolute';
+ text.style.bottom = '12px';
+ text.style.left = '16px';
+ text.style.right = '16px';
+ text.style.fontWeight = '600';
+ text.style.fontSize = '14px';
+ text.style.color = '#fff';
+ text.style.textShadow = '0 1px 4px rgba(0,0,0,0.8)';
+
+ overlay.appendChild(n);
+ overlay.appendChild(text);
+ t.appendChild(overlay);
+
+ t.addEventListener('click', () => { go(i); toggleOverview(false); });
+ overview.appendChild(t);
+ });
+ document.body.appendChild(overview);
+ }
+
+ /* ===== 排版溢出检测 =====
+ * 检测 .page-body 内容是否超出可用高度,输出控制台警告。
+ * 不自动缩放,避免元素重叠。
+ */
+ function checkOverflow(n) {
+ var slide = slides[n];
+ if (!slide) return;
+ var body = slide.querySelector('.page-body');
+ if (!body) return;
+
+ var availH = body.clientHeight;
+ var contentH = body.scrollHeight;
+
+ if (contentH > availH) {
+ var overflow = contentH - availH;
+ var pct = ((contentH / availH) - 1) * 100;
+ var title = slide.getAttribute('data-title') || ('Slide ' + (n + 1));
+ console.warn(
+ '[CCTC 排版警告] 幻灯片 "' + title + '" 内容溢出: ' +
+ overflow.toFixed(0) + 'px (' + pct.toFixed(0) + '% 超出). ' +
+ '建议精简内容或拆分到多页。详情见 layout-rules.md'
+ );
+ // 可选:在页面上添加红色边框标记溢出
+ body.style.outline = '2px dashed rgba(185,28,28,0.5)';
+ } else {
+ // 清除之前的标记
+ var body2 = slide.querySelector('.page-body');
+ if (body2 && body2.style.outline) {
+ body2.style.outline = '';
+ }
+ }
+ }
+
+ /* ===== navigation ===== */
+ function go(n, fromRemote){
+ n = Math.max(0, Math.min(total-1, n));
+ slides.forEach((s,i) => {
+ s.classList.toggle('is-active', i===n);
+ s.classList.toggle('is-prev', i checkOverflow(n));
+
+ // re-trigger entry animations (skip during fullscreen transition)
+ if (!document.documentElement.classList.contains('fs-transition')) {
+ slides[n].querySelectorAll('[data-anim]').forEach(el => {
+ const a = el.getAttribute('data-anim');
+ el.classList.remove('anim-'+a);
+ void el.offsetWidth;
+ el.classList.add('anim-'+a);
+ });
+ }
+
+ // counter-up
+ slides[n].querySelectorAll('.counter').forEach(el => {
+ const target = parseFloat(el.getAttribute('data-to')||el.textContent);
+ const dur = parseInt(el.getAttribute('data-dur')||'1200',10);
+ const start = performance.now();
+ const from = 0;
+ function tick(now){
+ const t = Math.min(1,(now-start)/dur);
+ const v = from + (target-from)*(1-Math.pow(1-t,3));
+ el.textContent = (target % 1 === 0) ? Math.round(v) : v.toFixed(1);
+ if (t<1) requestAnimationFrame(tick);
+ }
+ requestAnimationFrame(tick);
+ });
+
+ // Broadcast to other window (audience ↔ presenter)
+ if (!fromRemote && bc) {
+ bc.postMessage({ type: 'go', idx: n });
+ }
+ }
+
+ /* ===== listen for remote navigation / theme changes ===== */
+ if (bc) {
+ bc.onmessage = function(e) {
+ if (!e.data) return;
+ if (e.data.type === 'go' && typeof e.data.idx === 'number') {
+ go(e.data.idx, true);
+ } else if (e.data.type === 'theme' && e.data.name) {
+ /* Sync theme across windows */
+ const i = themes.indexOf(e.data.name);
+ if (i >= 0) themeIdx = i;
+ applyTheme(e.data.name);
+ }
+ };
+ }
+
+ function toggleNotes(force){ notes.classList.toggle('open', force!==undefined?force:!notes.classList.contains('open')); }
+ function toggleOverview(force){
+ const isOpen = force!==undefined ? force : !overview.classList.contains('open');
+ overview.classList.toggle('open', isOpen);
+ if (isOpen) {
+ requestAnimationFrame(() => {
+ const thumbs = overview.querySelectorAll('.thumb');
+ if (thumbs.length) {
+ const scale = thumbs[0].clientWidth / 1920;
+ overview.querySelectorAll('.mini-slide').forEach(m => {
+ m.style.transform = 'scale(' + scale + ')';
+ });
+ }
+ });
+ }
+ }
+
+ /* ========== PRESENTER MODE — Magnetic-card popup window ========== */
+ /* Opens a new window with 4 draggable, resizable cards:
+ * CURRENT — iframe(?preview=N) pixel-perfect preview of current slide
+ * NEXT — iframe(?preview=N+1) pixel-perfect preview of next slide
+ * SCRIPT — large speaker notes (逐字稿)
+ * TIMER — elapsed timer + page counter + controls
+ * Cards remember position/size in localStorage.
+ * Two windows sync via BroadcastChannel.
+ */
+ let presenterWin = null;
+
+ function openPresenterWindow() {
+ if (presenterWin && !presenterWin.closed) {
+ presenterWin.focus();
+ return;
+ }
+
+ // Build absolute URL of THIS deck file (without hash/query)
+ const deckUrl = location.protocol + '//' + location.host + location.pathname;
+
+ // Collect slide titles + notes (HTML strings)
+ const slideMeta = slides.map((s, i) => {
+ const note = s.querySelector('.notes, aside.notes, .speaker-notes');
+ return {
+ title: s.getAttribute('data-title') ||
+ (s.querySelector('h1,h2,h3')||{}).textContent || ('Slide '+(i+1)),
+ notes: note ? note.innerHTML : ''
+ };
+ });
+
+ /* Capture current theme so presenter previews match the audience */
+ const currentTheme = root.getAttribute('data-theme') || (themes[themeIdx] || '');
+ const presenterHTML = buildPresenterHTML(deckUrl, slideMeta, total, idx, CHANNEL_NAME, currentTheme);
+
+ presenterWin = window.open('', 'html-ppt-presenter', 'width=1280,height=820,menubar=no,toolbar=no');
+ if (!presenterWin) {
+ alert('请允许弹出窗口以使用演讲者视图');
+ return;
+ }
+ presenterWin.document.open();
+ presenterWin.document.write(presenterHTML);
+ presenterWin.document.close();
+ }
+
+ function buildPresenterHTML(deckUrl, slideMeta, total, startIdx, channelName, currentTheme) {
+ const metaJSON = JSON.stringify(slideMeta);
+ const deckUrlJSON = JSON.stringify(deckUrl);
+ const channelJSON = JSON.stringify(channelName);
+ const themeJSON = JSON.stringify(currentTheme || '');
+ const storageKey = 'html-ppt-presenter:' + location.pathname;
+
+ // Build the document as a single template string for clarity
+ return `
+
+
+
+Presenter View
+
+
+
+
+
+
+
+
+ CURRENT
+ —
+
+
+
+
+
+
+
+
+
+
+ SPEAKER SCRIPT · 逐字稿
+
+
+
+
+
+
+
+
+ TIMER
+
+
+
00:00
+
+ Slide
+ 1 / ${total}
+
+
+
+
+
+
+
+
+
+
+
+
+ ← → 翻页
+ R 重置计时
+ Esc 关闭
+ 拖动卡片头部移动 · 拖动右下角调整大小
+
+
+
+
+
+
diff --git a/pres/bps-schema-intro.pdf b/pres/bps-schema-intro.pdf
new file mode 100644
index 0000000..c7a07fd
Binary files /dev/null and b/pres/bps-schema-intro.pdf differ
diff --git a/pres/slide-01.jpg b/pres/slide-01.jpg
new file mode 100644
index 0000000..174fbb3
Binary files /dev/null and b/pres/slide-01.jpg differ
diff --git a/pres/slide-02.jpg b/pres/slide-02.jpg
new file mode 100644
index 0000000..a96ab28
Binary files /dev/null and b/pres/slide-02.jpg differ
diff --git a/pres/slide-03.jpg b/pres/slide-03.jpg
new file mode 100644
index 0000000..a833437
Binary files /dev/null and b/pres/slide-03.jpg differ
diff --git a/pres/slide-04.jpg b/pres/slide-04.jpg
new file mode 100644
index 0000000..c8c8500
Binary files /dev/null and b/pres/slide-04.jpg differ
diff --git a/pres/slide-05.jpg b/pres/slide-05.jpg
new file mode 100644
index 0000000..ff2de0c
Binary files /dev/null and b/pres/slide-05.jpg differ
diff --git a/pres/slide-06.jpg b/pres/slide-06.jpg
new file mode 100644
index 0000000..8e06435
Binary files /dev/null and b/pres/slide-06.jpg differ
diff --git a/pres/slide-07.jpg b/pres/slide-07.jpg
new file mode 100644
index 0000000..bcd614c
Binary files /dev/null and b/pres/slide-07.jpg differ
diff --git a/pres/slide-08.jpg b/pres/slide-08.jpg
new file mode 100644
index 0000000..dbed4ea
Binary files /dev/null and b/pres/slide-08.jpg differ
diff --git a/pres/slide-09.jpg b/pres/slide-09.jpg
new file mode 100644
index 0000000..9841d7d
Binary files /dev/null and b/pres/slide-09.jpg differ
diff --git a/pres/slide-10.jpg b/pres/slide-10.jpg
new file mode 100644
index 0000000..8c69155
Binary files /dev/null and b/pres/slide-10.jpg differ
diff --git a/pres/slide-11.jpg b/pres/slide-11.jpg
new file mode 100644
index 0000000..bb81b8e
Binary files /dev/null and b/pres/slide-11.jpg differ
diff --git a/pres/slide-12.jpg b/pres/slide-12.jpg
new file mode 100644
index 0000000..cecec79
Binary files /dev/null and b/pres/slide-12.jpg differ
diff --git a/pres/slide-13.jpg b/pres/slide-13.jpg
new file mode 100644
index 0000000..537c6a7
Binary files /dev/null and b/pres/slide-13.jpg differ
diff --git a/pres/slide-14.jpg b/pres/slide-14.jpg
new file mode 100644
index 0000000..52eb27a
Binary files /dev/null and b/pres/slide-14.jpg differ
diff --git a/pres/slide-15.jpg b/pres/slide-15.jpg
new file mode 100644
index 0000000..b377d13
Binary files /dev/null and b/pres/slide-15.jpg differ
diff --git a/pres/slide-16.jpg b/pres/slide-16.jpg
new file mode 100644
index 0000000..4b54b46
Binary files /dev/null and b/pres/slide-16.jpg differ
diff --git a/schema-all.json b/schema-all.json
new file mode 100644
index 0000000..89e8cd1
--- /dev/null
+++ b/schema-all.json
@@ -0,0 +1,41 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/all",
+ "title": "All-Scale Schema Aggregation",
+ "description": "Aggregation entry point that references all scale-specific schemas organized by geometry and simulation domain.",
+ "$defs": {
+ "building": {
+ "$ref": "./schema-building.json"
+ },
+ "energy": {
+ "$ref": "./schema-energy.json"
+ },
+ "radiance": {
+ "$ref": "./schema-radiance.json"
+ },
+ "cfd": {
+ "$ref": "./schema-cfd.json"
+ },
+ "community": {
+ "$ref": "./schema-community.json"
+ },
+ "community-energy": {
+ "$ref": "./schema-community-energy.json"
+ },
+ "community-cfd": {
+ "$ref": "./schema-community-cfd.json"
+ },
+ "community-microclimate": {
+ "$ref": "./schema-community-microclimate.json"
+ },
+ "urban": {
+ "$ref": "./schema-urban.json"
+ },
+ "urban-energy": {
+ "$ref": "./schema-urban-energy.json"
+ },
+ "urban-cfd": {
+ "$ref": "./schema-urban-cfd.json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-building.json b/schema-building.json
index 01323a9..530ccae 100644
--- a/schema-building.json
+++ b/schema-building.json
@@ -1,388 +1,962 @@
{
- "archgen": {
- "version": "0.1.0",
- "description": "ArchGen Schema — 建筑几何与核心实体",
- "tags": {
- "scale": {
- "building": "建筑尺度",
- "community": "社区/街区尺度",
- "urban": "城市尺度"
- },
- "simulation": {
- "energy": "能耗模拟",
- "daylight": "采光分析",
- "solar": "日照分析",
- "thermal_comfort": "热舒适分析",
- "carbon": "碳排放核算",
- "wind": "风环境模拟",
- "general": "通用(不特定于某种模拟)"
- }
- }
- },
-
- "types": {
- "Point3d": {
- "description": "三维点坐标",
- "fields": {
- "x": { "type": "number", "default": 0 },
- "y": { "type": "number", "default": 0 },
- "z": { "type": "number", "default": 0 }
- }
- },
- "Polyline3d": {
- "description": "三维多段线(点列表)",
- "fields": {
- "points": { "type": "Point3d[]", "default": [] }
- }
- },
- "Vector3d": {
- "description": "三维向量",
- "fields": {
- "x": { "type": "number", "default": 0 },
- "y": { "type": "number", "default": 0 },
- "z": { "type": "number", "default": 0 }
- }
- },
- "Line3d": {
- "description": "直线(起点+终点)",
- "fields": {
- "from": { "type": "Point3d" },
- "to": { "type": "Point3d" }
- }
- },
- "TimePoint": {
- "description": "时刻点 [时, 分]",
- "fields": {
- "hour": { "type": "integer", "default": 0 },
- "minute": { "type": "integer", "default": 0 }
- }
- },
- "DatePoint": {
- "description": "日期点 [月, 日]",
- "fields": {
- "month": { "type": "integer", "default": 1 },
- "day": { "type": "integer", "default": 1 }
- }
- },
- "Period": {
- "description": "时间范围",
- "fields": {
- "start": { "type": "DatePoint" },
- "end": { "type": "DatePoint" }
- }
- },
- "UVRect": {
- "description": "UV 矩形坐标 [u, v, 宽比, 高比]",
- "fields": {
- "u": { "type": "number" },
- "v": { "type": "number" },
- "widthRatio": { "type": "number" },
- "heightRatio": { "type": "number" }
- }
- }
- },
-
- "enums": {
- "Direction": {
- "description": "朝向",
- "values": ["N", "NE", "E", "SE", "S", "SW", "W", "NW"]
- },
- "BoundaryType": {
- "description": "边界类型",
- "values": [
- "exterior_wall", "interior_wall", "curtain_wall",
- "roof", "floor", "slab", "foundation"
- ]
- },
- "ElementType": {
- "description": "结构构件类型",
- "values": [
- "column", "beam", "slab", "wall",
- "foundation", "stair", "ramp"
- ]
- },
- "ApertureGeometryType": {
- "description": "洞口几何类型",
- "values": ["window", "door", "curtain_wall", "generic"]
- },
- "ApertureContextType": {
- "description": "洞口内外上下文",
- "values": ["EXTERIOR", "INTERIOR"]
- },
- "RoomCreationMethod": {
- "description": "房间创建方式",
- "values": ["planar_extrude", "mass_slice", "manual"]
- },
- "RelationType": {
- "description": "拓扑关系类型",
- "values": ["adjacent", "contains", "crosses", "flows", "touches", "sight"]
- }
- },
-
- "entities": {
- "Building": {
- "description": "建筑顶级实体",
- "tags": { "scale": ["building", "community", "urban"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "description": "唯一标识符", "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "description": "显示名称", "tags": { "simulation": ["general"] } },
- "schemaVersion": { "type": "string", "required": true, "description": "archgen-schema 版本", "tags": { "simulation": ["general"] } },
- "siteBasePoint": { "type": "Point3d", "required": true, "description": "建筑基准点", "tags": { "simulation": ["general"] } },
- "northAngle": { "type": "number", "required": true, "default": 0, "description": "建筑正北角度", "tags": { "simulation": ["energy", "daylight", "solar", "thermal_comfort", "wind"] } },
- "globalSettings": { "type": "object", "description": "全局设置", "tags": { "simulation": ["general"] } },
- "metadata": { "type": "object", "description": "自定义元数据", "tags": { "simulation": ["general"] } }
- },
- "children": {
- "floors": { "type": "Floor", "multiple": true, "description": "楼层列表", "tags": { "scale": ["building", "community"], "simulation": ["general"] } },
- "masses": { "type": "MassEntity", "multiple": true, "description": "参数化体量", "tags": { "scale": ["building"], "simulation": ["general"] } },
- "shafts": { "type": "Shaft", "multiple": true, "description": "竖井", "tags": { "scale": ["building"], "simulation": ["general"] } },
- "shades": { "type": "Shade", "multiple": true, "description": "遮阳", "tags": { "scale": ["building", "community"], "simulation": ["energy", "daylight", "solar", "thermal_comfort"] } },
- "siteShades": { "type": "Shade", "multiple": true, "description": "外部遮阳(树木、邻楼)", "tags": { "scale": ["building", "community", "urban"], "simulation": ["energy", "daylight", "solar", "wind"] } },
- "gridSystem": { "type": "GridSystem", "description": "轴网系统", "tags": { "scale": ["building"], "simulation": ["general"] } },
- "relations": { "type": "Relation", "multiple": true, "description": "拓扑关系", "tags": { "scale": ["building", "community", "urban"], "simulation": ["general"] } }
- }
- },
-
- "Floor": {
- "description": "楼层",
- "tags": { "scale": ["building", "community"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "description": "唯一标识符", "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "description": "显示名称", "tags": { "simulation": ["general"] } },
- "elevation": { "type": "number", "required": true, "description": "楼层标高 Z", "tags": { "simulation": ["general"] } },
- "height": { "type": "number", "required": true, "description": "层高", "unit": "m", "tags": { "simulation": ["energy", "daylight", "thermal_comfort", "carbon"] } },
- "story": { "type": "integer", "required": true, "description": "楼层序号", "tags": { "simulation": ["general"] } },
- "outline": { "type": "Polyline3d", "description": "楼板轮廓", "tags": { "simulation": ["general"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- },
- "children": {
- "rooms": { "type": "Room", "multiple": true, "description": "房间" },
- "apertures": { "type": "Aperture", "multiple": true, "description": "楼层级洞口", "tags": { "scale": ["building"], "simulation": ["energy", "daylight", "wind"] } },
- "elements": { "type": "Element", "multiple": true, "description": "结构构件", "tags": { "scale": ["building"], "simulation": ["general"] } }
- }
- },
-
- "Room": {
- "description": "房间",
- "tags": { "scale": ["building", "community"] },
- "discriminator": "creationMethod",
- "variants": {
- "planar_extrude": {
- "description": "平面轮廓拉伸创建",
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "creationMethod": { "type": "RoomCreationMethod", "required": true, "default": "planar_extrude", "tags": { "simulation": ["general"] } },
- "programType": { "type": "string", "description": "房间功能类型", "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "region": { "type": "Polyline3d", "required": true, "description": "房间轮廓", "tags": { "simulation": ["energy", "daylight", "solar", "wind", "thermal_comfort"] } },
- "height": { "type": "number", "required": true, "description": "房间高度", "tags": { "simulation": ["energy", "daylight", "thermal_comfort"] } },
- "elevation": { "type": "number", "description": "楼层内 Z 偏移", "tags": { "simulation": ["general"] } },
- "boundaries": { "type": "Boundary[]", "description": "房间边界/墙体", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "apertures": { "type": "string[]", "description": "关联洞口 ID 列表", "tags": { "scale": ["building"], "simulation": ["energy", "daylight", "wind"] } },
- "elements": { "type": "Element[]", "description": "房间内构件", "tags": { "scale": ["building"], "simulation": ["general"] } },
- "geometryDriver": { "type": "object", "description": "几何驱动参数", "tags": { "simulation": ["general"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/building",
+ "title": "HBJSON Compatible Building Schema",
+ "description": "Building-scale geometry schema, fully compatible with honeybee-schema (HBJSON). Defines the core hierarchy: Model \u2192 Room \u2192 Face \u2192 Aperture/Door \u2192 Shade.",
+ "$defs": {
+ "Point3D": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Point3D"
},
- "mass_slice": {
- "description": "体量切片创建",
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "creationMethod": { "type": "RoomCreationMethod", "required": true, "default": "mass_slice", "tags": { "simulation": ["general"] } },
- "programType": { "type": "string", "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "region": { "type": "Polyline3d", "required": true, "tags": { "simulation": ["energy", "daylight", "solar", "wind", "thermal_comfort"] } },
- "height": { "type": "number", "required": true, "tags": { "simulation": ["energy", "daylight", "thermal_comfort"] } },
- "elevation": { "type": "number", "tags": { "simulation": ["general"] } },
- "boundaries": { "type": "Boundary[]", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "apertures": { "type": "string[]", "tags": { "scale": ["building"], "simulation": ["energy", "daylight", "wind"] } },
- "elements": { "type": "Element[]", "tags": { "scale": ["building"], "simulation": ["general"] } },
- "driverRef": {
- "type": "object", "required": true, "description": "体量引用",
- "tags": { "simulation": ["general"] },
- "attributes": {
- "massId": { "type": "string", "required": true },
- "sliceZ": { "type": "number", "required": true }
- }
+ "x": {
+ "type": "number"
+ },
+ "y": {
+ "type": "number"
+ },
+ "z": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "x",
+ "y",
+ "z"
+ ],
+ "additionalProperties": false
+ },
+ "Plane": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Plane"
+ },
+ "n": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "o": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "x": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "n",
+ "o"
+ ],
+ "additionalProperties": false
+ },
+ "Face3D": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Face3D"
+ },
+ "boundary": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
},
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "minItems": 3
+ },
+ "holes": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "minItems": 3
}
},
- "manual": {
- "description": "手动绘制",
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "creationMethod": { "type": "RoomCreationMethod", "required": true, "default": "manual", "tags": { "simulation": ["general"] } },
- "programType": { "type": "string", "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "region": { "type": "Polyline3d", "required": true, "tags": { "simulation": ["energy", "daylight", "solar", "wind", "thermal_comfort"] } },
- "height": { "type": "number", "required": true, "tags": { "simulation": ["energy", "daylight", "thermal_comfort"] } },
- "elevation": { "type": "number", "tags": { "simulation": ["general"] } },
- "boundaries": { "type": "Boundary[]", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "apertures": { "type": "string[]", "tags": { "scale": ["building"], "simulation": ["energy", "daylight", "wind"] } },
- "elements": { "type": "Element[]", "tags": { "scale": ["building"], "simulation": ["general"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
+ "plane": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/Plane"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "boundary"
+ ],
+ "additionalProperties": false
+ },
+ "Color": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Color"
+ },
+ "r": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ },
+ "g": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ },
+ "b": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ },
+ "a": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255,
+ "default": 255
+ }
+ },
+ "required": [
+ "r",
+ "g",
+ "b"
+ ],
+ "additionalProperties": false
+ },
+ "Mesh3D": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Mesh3D"
+ },
+ "vertices": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "minItems": 3
+ },
+ "faces": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "minItems": 3,
+ "maxItems": 4
+ },
+ "minItems": 1
+ },
+ "colors": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Color"
}
}
- }
+ },
+ "required": [
+ "vertices",
+ "faces"
+ ],
+ "additionalProperties": false
},
-
- "Aperture": {
- "description": "建筑洞口",
- "tags": { "scale": ["building"], "simulation": ["energy", "daylight", "solar", "wind"] },
- "discriminator": "sourceType",
- "variants": {
- "hosted": {
- "description": "绑定到特定形体面",
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "sourceType": { "type": "string", "required": true, "default": "hosted", "tags": { "simulation": ["general"] } },
- "geometryType": { "type": "ApertureGeometryType", "required": true, "tags": { "simulation": ["energy", "daylight", "solar", "wind"] } },
- "width": { "type": "number", "tags": { "simulation": ["energy", "daylight"] } },
- "height": { "type": "number", "tags": { "simulation": ["energy", "daylight"] } },
- "sillHeight": { "type": "number", "description": "窗台高", "tags": { "simulation": ["energy", "daylight"] } },
- "parent": { "type": "string", "description": "父实体 ID", "tags": { "simulation": ["general"] } },
- "rooms": { "type": "string[]", "description": "相邻房间 ID", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "openRatio": { "type": "number", "default": 0, "description": "开启比", "tags": { "simulation": ["energy", "wind", "thermal_comfort"] } },
- "operable": { "type": "boolean", "default": false, "tags": { "simulation": ["energy", "wind", "thermal_comfort"] } },
- "hosting": {
- "type": "object", "required": true, "description": "宿主绑定信息",
- "tags": { "simulation": ["general"] },
- "attributes": {
- "hostId": { "type": "string", "required": true },
- "faceIndex": { "type": "integer", "required": true },
- "uvRect": { "type": "UVRect", "required": true },
- "context": { "type": "ApertureContextType", "required": true }
- }
- },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "UserData": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "description": "Optional dictionary of user data. All keys and values should be standard data types."
+ },
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
},
- "declarative": {
- "description": "声明式放置",
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "sourceType": { "type": "string", "required": true, "default": "declarative", "tags": { "simulation": ["general"] } },
- "geometryType": { "type": "ApertureGeometryType", "required": true, "tags": { "simulation": ["energy", "daylight", "solar", "wind"] } },
- "width": { "type": "number", "tags": { "simulation": ["energy", "daylight"] } },
- "height": { "type": "number", "tags": { "simulation": ["energy", "daylight"] } },
- "sillHeight": { "type": "number", "tags": { "simulation": ["energy", "daylight"] } },
- "parent": { "type": "string", "tags": { "simulation": ["general"] } },
- "rooms": { "type": "string[]", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "openRatio": { "type": "number", "default": 0, "tags": { "simulation": ["energy", "wind", "thermal_comfort"] } },
- "operable": { "type": "boolean", "default": false, "tags": { "simulation": ["energy", "wind", "thermal_comfort"] } },
- "placement": {
- "type": "object", "description": "放置描述",
- "tags": { "simulation": ["general"] },
- "attributes": {
- "boundaryId": { "type": "string" },
- "position": { "type": "string", "description": "center, start, end 或距离" },
- "orientation": { "type": "Direction" }
- }
- },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "default": null
+ },
+ "user_data": {
+ "$ref": "#/$defs/UserData"
}
- }
+ },
+ "required": [
+ "identifier"
+ ]
},
-
- "Boundary": {
- "description": "空间边界/墙体",
- "tags": { "scale": ["building", "community"], "simulation": ["energy", "thermal_comfort", "carbon"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "type": { "type": "BoundaryType", "required": true, "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "region": { "type": "Polyline3d", "required": true, "description": "边界线段或多边形", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "thickness": { "type": "number", "description": "墙厚", "unit": "m", "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "height": { "type": "number", "description": "墙高", "unit": "m", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "direction": { "type": "Direction", "description": "朝向", "tags": { "simulation": ["energy", "daylight", "solar"] } },
- "pitch": { "type": "number", "description": "倾斜角度", "unit": "deg", "tags": { "simulation": ["energy", "solar"] } },
- "hostRoomId": { "type": "string", "description": "所属房间 ID", "tags": { "simulation": ["general"] } },
- "constructionId": { "type": "string", "description": "构造 ID", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "sharedBy": { "type": "string[]", "description": "共享此边界的房间 ID 列表", "tags": { "simulation": ["thermal_comfort"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "Outdoors": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Outdoors"
+ },
+ "sun_exposure": {
+ "type": "boolean",
+ "default": true
+ },
+ "wind_exposure": {
+ "type": "boolean",
+ "default": true
+ },
+ "view_factor": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "const": "autocalculate"
+ }
+ ],
+ "default": "autocalculate"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
},
-
- "Element": {
- "description": "结构构件",
- "tags": { "scale": ["building"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "type": { "type": "ElementType", "required": true, "tags": { "simulation": ["general"] } },
- "region": { "type": "Polyline3d", "description": "截面轮廓", "tags": { "simulation": ["general"] } },
- "height": { "type": "number", "unit": "m", "tags": { "simulation": ["general"] } },
- "materialId": { "type": "string", "description": "材料 ID", "tags": { "simulation": ["carbon"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "Surface": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Surface"
+ },
+ "boundary_condition_objects": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 2,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "type",
+ "boundary_condition_objects"
+ ],
+ "additionalProperties": false
},
-
- "MassEntity": {
- "description": "参数化体量",
- "tags": { "scale": ["building"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "region": { "type": "Polyline3d", "tags": { "simulation": ["general"] } },
- "height": { "type": "number", "unit": "m", "tags": { "simulation": ["general"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "Ground": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Ground"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
},
-
- "Shaft": {
- "description": "竖井(楼梯/电梯/管道)",
- "tags": { "scale": ["building"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "type": { "type": "string", "description": "stair/elevator/duct", "tags": { "simulation": ["general"] } },
- "spanLevels": { "type": "string[]", "description": "穿越的楼层 ID", "tags": { "simulation": ["general"] } },
- "region": { "type": "Polyline3d", "description": "竖井截面", "tags": { "simulation": ["general"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "Adiabatic": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Adiabatic"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "OtherSideTemperature": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "OtherSideTemperature"
+ },
+ "heat_transfer_coefficient": {
+ "type": "number",
+ "minimum": 0,
+ "default": 0
+ },
+ "temperature": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "const": "autocalculate"
+ }
+ ],
+ "default": "autocalculate"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "BoundaryCondition": {
+ "description": "Face boundary condition: Outdoors, Surface, Ground, Adiabatic, or OtherSideTemperature.",
+ "oneOf": [
+ {
+ "$ref": "#/$defs/Outdoors"
+ },
+ {
+ "$ref": "#/$defs/Surface"
+ },
+ {
+ "$ref": "#/$defs/Ground"
+ },
+ {
+ "$ref": "#/$defs/Adiabatic"
+ },
+ {
+ "$ref": "#/$defs/OtherSideTemperature"
+ }
+ ]
+ },
+ "ApertureBoundaryCondition": {
+ "description": "Aperture/Door boundary condition: Outdoors or Surface only.",
+ "oneOf": [
+ {
+ "$ref": "#/$defs/Outdoors"
+ },
+ {
+ "$ref": "#/$defs/Surface"
+ }
+ ]
+ },
+ "FaceType": {
+ "type": "string",
+ "enum": [
+ "Wall",
+ "Floor",
+ "RoofCeiling",
+ "AirBoundary"
+ ]
+ },
+ "Units": {
+ "type": "string",
+ "enum": [
+ "Meters",
+ "Millimeters",
+ "Feet",
+ "Inches",
+ "Centimeters"
+ ],
+ "default": "Meters"
+ },
+ "ShadePropertiesAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ShadePropertiesAbridged"
+ },
+ "energy": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "radiance": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "additionalProperties": false
},
-
"Shade": {
- "description": "遮阳构件",
- "tags": { "scale": ["building", "community"], "simulation": ["energy", "daylight", "solar", "thermal_comfort"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "region": { "type": "Polyline3d", "description": "遮阳轮廓", "tags": { "simulation": ["energy", "daylight", "solar", "thermal_comfort"] } },
- "height": { "type": "number", "unit": "m", "tags": { "simulation": ["energy", "daylight", "solar"] } },
- "transmittance": { "type": "number", "default": 0, "description": "透射率 0-1", "tags": { "simulation": ["energy", "daylight", "solar"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Shade"
+ },
+ "geometry": {
+ "$ref": "#/$defs/Face3D"
+ },
+ "properties": {
+ "$ref": "#/$defs/ShadePropertiesAbridged"
+ },
+ "is_detached": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "required": [
+ "type",
+ "geometry",
+ "properties"
+ ],
+ "additionalProperties": false
+ }
+ ]
},
-
- "GridSystem": {
- "description": "轴网系统",
- "tags": { "scale": ["building"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "axisX": { "type": "string[]", "description": "X 向轴线名", "tags": { "simulation": ["general"] } },
- "axisY": { "type": "string[]", "description": "Y 向轴线名", "tags": { "simulation": ["general"] } },
- "spacingsX": { "type": "number[]", "description": "X 向跨距", "unit": "m", "tags": { "simulation": ["general"] } },
- "spacingsY": { "type": "number[]", "description": "Y 向跨距", "unit": "m", "tags": { "simulation": ["general"] } },
- "origin": { "type": "Point3d", "required": true, "description": "轴网原点", "tags": { "simulation": ["general"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "AperturePropertiesAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "AperturePropertiesAbridged"
+ },
+ "energy": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "radiance": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "additionalProperties": false
},
-
- "Relation": {
- "description": "拓扑关系边",
- "tags": { "scale": ["building", "community", "urban"] },
- "attributes": {
- "type": { "type": "RelationType", "required": true, "tags": { "simulation": ["general"] } },
- "source": { "type": "string", "required": true, "description": "源实体 ID", "tags": { "simulation": ["general"] } },
- "target": { "type": "string", "required": true, "description": "目标实体 ID", "tags": { "simulation": ["general"] } },
- "metadata": { "type": "object", "tags": { "simulation": ["general"] } }
- }
+ "Aperture": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Aperture"
+ },
+ "geometry": {
+ "$ref": "#/$defs/Face3D"
+ },
+ "boundary_condition": {
+ "$ref": "#/$defs/ApertureBoundaryCondition"
+ },
+ "is_operable": {
+ "type": "boolean",
+ "default": false
+ },
+ "indoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "outdoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "properties": {
+ "$ref": "#/$defs/AperturePropertiesAbridged"
+ }
+ },
+ "required": [
+ "type",
+ "geometry",
+ "boundary_condition",
+ "properties"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "DoorPropertiesAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "DoorPropertiesAbridged"
+ },
+ "energy": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "radiance": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "Door": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Door"
+ },
+ "geometry": {
+ "$ref": "#/$defs/Face3D"
+ },
+ "boundary_condition": {
+ "$ref": "#/$defs/ApertureBoundaryCondition"
+ },
+ "is_glass": {
+ "type": "boolean",
+ "default": false
+ },
+ "indoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "outdoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "properties": {
+ "$ref": "#/$defs/DoorPropertiesAbridged"
+ }
+ },
+ "required": [
+ "type",
+ "geometry",
+ "boundary_condition",
+ "properties"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "FacePropertiesAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "FacePropertiesAbridged"
+ },
+ "energy": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "radiance": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "Face": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Face"
+ },
+ "geometry": {
+ "$ref": "#/$defs/Face3D"
+ },
+ "face_type": {
+ "$ref": "#/$defs/FaceType"
+ },
+ "boundary_condition": {
+ "$ref": "#/$defs/BoundaryCondition"
+ },
+ "apertures": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Aperture"
+ }
+ },
+ "doors": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Door"
+ }
+ },
+ "indoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "outdoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "properties": {
+ "$ref": "#/$defs/FacePropertiesAbridged"
+ }
+ },
+ "required": [
+ "type",
+ "geometry",
+ "face_type",
+ "boundary_condition",
+ "properties"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ShadeMeshPropertiesAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ShadeMeshPropertiesAbridged"
+ },
+ "energy": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "radiance": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "ShadeMesh": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ShadeMesh"
+ },
+ "geometry": {
+ "$ref": "#/$defs/Mesh3D"
+ },
+ "properties": {
+ "$ref": "#/$defs/ShadeMeshPropertiesAbridged"
+ },
+ "is_detached": {
+ "type": "boolean",
+ "default": true
+ }
+ },
+ "required": [
+ "type",
+ "geometry",
+ "properties"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "RoomPropertiesAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "RoomPropertiesAbridged"
+ },
+ "energy": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "radiance": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "doe2": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "Room": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Room"
+ },
+ "faces": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/Face"
+ },
+ "minItems": 4
+ },
+ "indoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "outdoor_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "multiplier": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ },
+ "exclude_floor_area": {
+ "type": "boolean",
+ "default": false
+ },
+ "zone": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "story": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "properties": {
+ "$ref": "#/$defs/RoomPropertiesAbridged"
+ }
+ },
+ "required": [
+ "type",
+ "faces",
+ "properties"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ModelProperties": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ModelProperties"
+ },
+ "energy": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "radiance": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "doe2": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "Model": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Model"
+ },
+ "version": {
+ "type": "string",
+ "pattern": "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$",
+ "default": "0.0.0"
+ },
+ "rooms": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Room"
+ }
+ },
+ "orphaned_faces": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Face"
+ }
+ },
+ "orphaned_apertures": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Aperture"
+ }
+ },
+ "orphaned_doors": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Door"
+ }
+ },
+ "orphaned_shades": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/Shade"
+ }
+ },
+ "shade_meshes": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "$ref": "#/$defs/ShadeMesh"
+ }
+ },
+ "units": {
+ "$ref": "#/$defs/Units"
+ },
+ "tolerance": {
+ "type": "number",
+ "minimum": 0,
+ "default": 0.01
+ },
+ "angle_tolerance": {
+ "type": "number",
+ "minimum": 0,
+ "default": 1.0
+ },
+ "properties": {
+ "$ref": "#/$defs/ModelProperties"
+ }
+ },
+ "required": [
+ "type",
+ "properties"
+ ],
+ "additionalProperties": false
+ }
+ ]
}
- }
-}
+ },
+ "$ref": "#/$defs/Model"
+}
\ No newline at end of file
diff --git a/schema-cfd.json b/schema-cfd.json
new file mode 100644
index 0000000..a1ceafa
--- /dev/null
+++ b/schema-cfd.json
@@ -0,0 +1,735 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/cfd",
+ "title": "CFD Wind Environment Simulation Schema",
+ "description": "Computational Fluid Dynamics simulation parameters for building wind environment analysis. Covers domain definition, mesh parameters, turbulence models, boundary conditions, and solver settings. Not part of HBJSON; provided as a parallel simulation domain.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "WindProfileType": {
+ "type": "string",
+ "enum": [
+ "power_law",
+ "log_law",
+ "uniform",
+ "atmospheric_boundary_layer"
+ ]
+ },
+ "TerrainCategory": {
+ "type": "string",
+ "enum": [
+ "open_sea",
+ "open_country",
+ "suburban",
+ "urban_center",
+ "dense_urban"
+ ]
+ },
+ "TurbulenceModel": {
+ "type": "string",
+ "enum": [
+ "k_epsilon_standard",
+ "k_epsilon_realizable",
+ "k_epsilon_RNG",
+ "k_omega_SST",
+ "LES",
+ "DES"
+ ]
+ },
+ "SolverType": {
+ "type": "string",
+ "enum": [
+ "steady",
+ "transient"
+ ]
+ },
+ "WindProfile": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindProfile"
+ },
+ "profile_type": {
+ "$ref": "#/$defs/WindProfileType",
+ "default": "power_law"
+ },
+ "reference_wind_speed": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "m/s at reference height"
+ },
+ "reference_height": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 10,
+ "description": "m"
+ },
+ "power_law_exponent": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Alpha for power law profile, terrain-dependent"
+ },
+ "roughness_length": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "z0 in meters for log law profile"
+ },
+ "ground_elevation": {
+ "type": "number",
+ "default": 0,
+ "description": "Ground elevation in meters"
+ },
+ "terrain_category": {
+ "$ref": "#/$defs/TerrainCategory",
+ "default": "suburban"
+ },
+ "wind_direction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 360,
+ "default": 0,
+ "description": "Wind direction in degrees, 0=N, 90=E"
+ }
+ },
+ "required": [
+ "type",
+ "reference_wind_speed"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "CFDDomain": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "CFDDomain"
+ },
+ "domain_size": {
+ "type": "object",
+ "properties": {
+ "x_min": {
+ "type": "number"
+ },
+ "x_max": {
+ "type": "number"
+ },
+ "y_min": {
+ "type": "number"
+ },
+ "y_max": {
+ "type": "number"
+ },
+ "z_min": {
+ "type": "number"
+ },
+ "z_max": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "x_min",
+ "x_max",
+ "y_min",
+ "y_max",
+ "z_min",
+ "z_max"
+ ],
+ "additionalProperties": false
+ },
+ "upstream_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "Distance from building to inlet, typically 5H"
+ },
+ "downstream_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "Distance from building to outlet, typically 15H"
+ },
+ "lateral_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "Distance from building to side walls, typically 5H"
+ },
+ "height_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "Distance from building top to domain top, typically 5H"
+ }
+ },
+ "required": [
+ "type",
+ "domain_size"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "MeshParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "MeshParameters"
+ },
+ "base_cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "Background mesh cell size in meters"
+ },
+ "refinement_zones": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "zone_name": {
+ "type": "string"
+ },
+ "cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "extent": {
+ "type": "object",
+ "properties": {
+ "x_min": {
+ "type": "number"
+ },
+ "x_max": {
+ "type": "number"
+ },
+ "y_min": {
+ "type": "number"
+ },
+ "y_max": {
+ "type": "number"
+ },
+ "z_min": {
+ "type": "number"
+ },
+ "z_max": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "x_min",
+ "x_max",
+ "y_min",
+ "y_max",
+ "z_min",
+ "z_max"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "zone_name",
+ "cell_size",
+ "extent"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "wall_layer_first_cell_height": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "First cell height at wall boundaries in meters"
+ },
+ "wall_layer_growth_rate": {
+ "type": "number",
+ "exclusiveMinimum": 1,
+ "maximum": 1.5,
+ "default": 1.2
+ },
+ "wall_layer_total_layers": {
+ "type": "integer",
+ "minimum": 3,
+ "default": 10
+ },
+ "mesh_type": {
+ "type": "string",
+ "enum": [
+ "hexahedral",
+ "polyhedral",
+ "tetrahedral",
+ "snappy_hex"
+ ],
+ "default": "snappy_hex"
+ },
+ "total_cells_estimate": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "type",
+ "base_cell_size"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "TurbulenceParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "TurbulenceParameters"
+ },
+ "turbulence_model": {
+ "$ref": "#/$defs/TurbulenceModel",
+ "default": "k_epsilon_RNG"
+ },
+ "turbulence_intensity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "description": "Inlet turbulence intensity (0-1)"
+ },
+ "turbulent_length_scale": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "Characteristic turbulent length scale in meters"
+ },
+ "wall_function_type": {
+ "type": "string",
+ "enum": [
+ "standard_wall_function",
+ "non_equilibrium",
+ "enhanced_wall_treatment",
+ "scalable_wall_function"
+ ],
+ "default": "standard_wall_function"
+ },
+ "y_plus_target": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "Target y+ value for wall-adjacent cells"
+ }
+ },
+ "required": [
+ "type",
+ "turbulence_model"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "BoundaryConditions": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "BoundaryConditions"
+ },
+ "inlet_type": {
+ "type": "string",
+ "enum": [
+ "velocity_inlet",
+ "pressure_inlet"
+ ],
+ "default": "velocity_inlet"
+ },
+ "outlet_type": {
+ "type": "string",
+ "enum": [
+ "pressure_outlet",
+ "outflow"
+ ],
+ "default": "pressure_outlet"
+ },
+ "top_boundary_type": {
+ "type": "string",
+ "enum": [
+ "symmetry",
+ "slip_wall",
+ "velocity_inlet"
+ ],
+ "default": "symmetry"
+ },
+ "side_boundary_type": {
+ "type": "string",
+ "enum": [
+ "symmetry",
+ "slip_wall"
+ ],
+ "default": "symmetry"
+ },
+ "ground_type": {
+ "type": "string",
+ "enum": [
+ "no_slip_wall",
+ "rough_wall"
+ ],
+ "default": "no_slip_wall"
+ },
+ "building_wall_type": {
+ "type": "string",
+ "enum": [
+ "no_slip_wall",
+ "rough_wall"
+ ],
+ "default": "no_slip_wall"
+ },
+ "surface_roughness_height": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001,
+ "description": "Physical roughness height in meters for wall boundaries"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "SolverSettings": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "SolverSettings"
+ },
+ "solver_type": {
+ "$ref": "#/$defs/SolverType",
+ "default": "steady"
+ },
+ "pressure_velocity_coupling": {
+ "type": "string",
+ "enum": [
+ "SIMPLE",
+ "SIMPLEC",
+ "PISO",
+ "Coupled"
+ ],
+ "default": "SIMPLE"
+ },
+ "spatial_discretization": {
+ "type": "string",
+ "enum": [
+ "first_order",
+ "second_order",
+ "QUICK",
+ "MUSCL"
+ ],
+ "default": "second_order"
+ },
+ "max_iterations": {
+ "type": "integer",
+ "minimum": 100,
+ "default": 1000
+ },
+ "convergence_criteria": {
+ "type": "object",
+ "properties": {
+ "continuity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "x_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "y_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "z_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "k": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "epsilon": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "omega": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ }
+ },
+ "additionalProperties": false
+ },
+ "under_relaxation_factors": {
+ "type": "object",
+ "properties": {
+ "pressure": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.3
+ },
+ "momentum": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ },
+ "turbulent_kinetic_energy": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.8
+ },
+ "turbulent_dissipation": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.8
+ }
+ },
+ "additionalProperties": false
+ },
+ "time_step": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "exclusiveMinimum": 0,
+ "description": "Time step in seconds (for transient only)"
+ },
+ "total_time": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "exclusiveMinimum": 0,
+ "description": "Total simulation time in seconds (for transient only)"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "OutputParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "OutputParameters"
+ },
+ "output_variables": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "velocity",
+ "pressure",
+ "turbulent_kinetic_energy",
+ "turbulent_dissipation",
+ "wall_shear_stress",
+ "vorticity"
+ ]
+ },
+ "default": [
+ "velocity",
+ "pressure"
+ ]
+ },
+ "monitoring_points": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "point_name": {
+ "type": "string"
+ },
+ "position": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "point_name",
+ "position"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "output_format": {
+ "type": "string",
+ "enum": [
+ "ensight",
+ "paraview",
+ "tecplot",
+ "csv",
+ "vtk"
+ ],
+ "default": "vtk"
+ },
+ "output_interval": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 100,
+ "description": "Write output every N iterations"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "CFDSettings": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "CFDSettings"
+ },
+ "wind_profiles": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/WindProfile"
+ }
+ },
+ "domain": {
+ "$ref": "#/$defs/CFDDomain"
+ },
+ "mesh": {
+ "$ref": "#/$defs/MeshParameters"
+ },
+ "turbulence": {
+ "$ref": "#/$defs/TurbulenceParameters"
+ },
+ "boundary_conditions": {
+ "$ref": "#/$defs/BoundaryConditions"
+ },
+ "solver": {
+ "$ref": "#/$defs/SolverSettings"
+ },
+ "output": {
+ "$ref": "#/$defs/OutputParameters"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ModelCFDProperties": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ModelCFDProperties"
+ },
+ "cfd_settings": {
+ "$ref": "#/$defs/CFDSettings"
+ },
+ "building_surfaces": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of building surface identifiers to be used as wall boundaries"
+ },
+ "terrain_surfaces": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of terrain/ground surface identifiers"
+ },
+ "porous_surfaces": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of surface identifiers treated as porous media (trees, screens)"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-community-cfd.json b/schema-community-cfd.json
new file mode 100644
index 0000000..12cebe7
--- /dev/null
+++ b/schema-community-cfd.json
@@ -0,0 +1,662 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/community-cfd",
+ "title": "Community-Scale CFD Wind Environment Schema",
+ "description": "CFD parameters for community/site wind environment analysis. Covers domain setup, mesh, turbulence, boundary conditions, and solver settings for neighborhood-scale simulations.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "WindProfileType": {
+ "type": "string",
+ "enum": [
+ "power_law",
+ "log_law",
+ "uniform",
+ "atmospheric_boundary_layer"
+ ]
+ },
+ "TerrainCategory": {
+ "type": "string",
+ "enum": [
+ "open_sea",
+ "open_country",
+ "suburban",
+ "urban_center",
+ "dense_urban"
+ ]
+ },
+ "TurbulenceModel": {
+ "type": "string",
+ "enum": [
+ "k_epsilon_standard",
+ "k_epsilon_realizable",
+ "k_epsilon_RNG",
+ "k_omega_SST",
+ "LES",
+ "DES"
+ ]
+ },
+ "SolverType": {
+ "type": "string",
+ "enum": [
+ "steady",
+ "transient"
+ ]
+ },
+ "WindProfile": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindProfile"
+ },
+ "profile_type": {
+ "$ref": "#/$defs/WindProfileType",
+ "default": "power_law"
+ },
+ "reference_wind_speed": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "reference_height": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 10
+ },
+ "power_law_exponent": {
+ "type": "number",
+ "minimum": 0
+ },
+ "roughness_length": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "ground_elevation": {
+ "type": "number",
+ "default": 0
+ },
+ "terrain_category": {
+ "$ref": "#/$defs/TerrainCategory",
+ "default": "suburban"
+ },
+ "wind_direction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 360,
+ "default": 0
+ }
+ },
+ "required": [
+ "type",
+ "reference_wind_speed"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "CFDDomain": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "CFDDomain"
+ },
+ "domain_size": {
+ "type": "object",
+ "properties": {
+ "x_min": {
+ "type": "number"
+ },
+ "x_max": {
+ "type": "number"
+ },
+ "y_min": {
+ "type": "number"
+ },
+ "y_max": {
+ "type": "number"
+ },
+ "z_min": {
+ "type": "number"
+ },
+ "z_max": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "x_min",
+ "x_max",
+ "y_min",
+ "y_max",
+ "z_min",
+ "z_max"
+ ],
+ "additionalProperties": false
+ },
+ "upstream_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 5H"
+ },
+ "downstream_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 15H"
+ },
+ "lateral_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 5H"
+ },
+ "height_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 5H"
+ }
+ },
+ "required": [
+ "type",
+ "domain_size"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "MeshParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "MeshParameters"
+ },
+ "base_cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "refinement_zones": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "zone_name": {
+ "type": "string"
+ },
+ "cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "extent": {
+ "type": "object",
+ "properties": {
+ "x_min": {
+ "type": "number"
+ },
+ "x_max": {
+ "type": "number"
+ },
+ "y_min": {
+ "type": "number"
+ },
+ "y_max": {
+ "type": "number"
+ },
+ "z_min": {
+ "type": "number"
+ },
+ "z_max": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "x_min",
+ "x_max",
+ "y_min",
+ "y_max",
+ "z_min",
+ "z_max"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "zone_name",
+ "cell_size",
+ "extent"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "wall_layer_first_cell_height": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "wall_layer_growth_rate": {
+ "type": "number",
+ "exclusiveMinimum": 1,
+ "maximum": 1.5,
+ "default": 1.2
+ },
+ "wall_layer_total_layers": {
+ "type": "integer",
+ "minimum": 3,
+ "default": 10
+ },
+ "mesh_type": {
+ "type": "string",
+ "enum": [
+ "hexahedral",
+ "polyhedral",
+ "tetrahedral",
+ "snappy_hex"
+ ],
+ "default": "snappy_hex"
+ }
+ },
+ "required": [
+ "type",
+ "base_cell_size"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "TurbulenceParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "TurbulenceParameters"
+ },
+ "turbulence_model": {
+ "$ref": "#/$defs/TurbulenceModel",
+ "default": "k_epsilon_RNG"
+ },
+ "turbulence_intensity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "turbulent_length_scale": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "wall_function_type": {
+ "type": "string",
+ "enum": [
+ "standard_wall_function",
+ "non_equilibrium",
+ "enhanced_wall_treatment",
+ "scalable_wall_function"
+ ],
+ "default": "standard_wall_function"
+ },
+ "y_plus_target": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ }
+ },
+ "required": [
+ "type",
+ "turbulence_model"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "BoundaryConditions": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "BoundaryConditions"
+ },
+ "inlet_type": {
+ "type": "string",
+ "enum": [
+ "velocity_inlet",
+ "pressure_inlet"
+ ],
+ "default": "velocity_inlet"
+ },
+ "outlet_type": {
+ "type": "string",
+ "enum": [
+ "pressure_outlet",
+ "outflow"
+ ],
+ "default": "pressure_outlet"
+ },
+ "top_boundary_type": {
+ "type": "string",
+ "enum": [
+ "symmetry",
+ "slip_wall",
+ "velocity_inlet"
+ ],
+ "default": "symmetry"
+ },
+ "side_boundary_type": {
+ "type": "string",
+ "enum": [
+ "symmetry",
+ "slip_wall"
+ ],
+ "default": "symmetry"
+ },
+ "ground_type": {
+ "type": "string",
+ "enum": [
+ "no_slip_wall",
+ "rough_wall"
+ ],
+ "default": "no_slip_wall"
+ },
+ "building_wall_type": {
+ "type": "string",
+ "enum": [
+ "no_slip_wall",
+ "rough_wall"
+ ],
+ "default": "no_slip_wall"
+ },
+ "surface_roughness_height": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "SolverSettings": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "SolverSettings"
+ },
+ "solver_type": {
+ "$ref": "#/$defs/SolverType",
+ "default": "steady"
+ },
+ "pressure_velocity_coupling": {
+ "type": "string",
+ "enum": [
+ "SIMPLE",
+ "SIMPLEC",
+ "PISO",
+ "Coupled"
+ ],
+ "default": "SIMPLE"
+ },
+ "spatial_discretization": {
+ "type": "string",
+ "enum": [
+ "first_order",
+ "second_order",
+ "QUICK",
+ "MUSCL"
+ ],
+ "default": "second_order"
+ },
+ "max_iterations": {
+ "type": "integer",
+ "minimum": 100,
+ "default": 1000
+ },
+ "convergence_criteria": {
+ "type": "object",
+ "properties": {
+ "continuity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "x_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "y_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "z_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "k": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "epsilon": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ }
+ },
+ "additionalProperties": false
+ },
+ "under_relaxation_factors": {
+ "type": "object",
+ "properties": {
+ "pressure": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.3
+ },
+ "momentum": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ },
+ "k": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.8
+ },
+ "epsilon": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.8
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "OutputParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "OutputParameters"
+ },
+ "output_variables": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "velocity",
+ "pressure",
+ "turbulent_kinetic_energy",
+ "turbulent_dissipation",
+ "wall_shear_stress",
+ "vorticity"
+ ]
+ },
+ "default": [
+ "velocity",
+ "pressure"
+ ]
+ },
+ "monitoring_points": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "point_name": {
+ "type": "string"
+ },
+ "position": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "point_name",
+ "position"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "output_format": {
+ "type": "string",
+ "enum": [
+ "ensight",
+ "paraview",
+ "tecplot",
+ "csv",
+ "vtk"
+ ],
+ "default": "vtk"
+ },
+ "output_interval": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 100
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "CommunityCFDSettings": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "CommunityCFDSettings"
+ },
+ "wind_profiles": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/WindProfile"
+ }
+ },
+ "domain": {
+ "$ref": "#/$defs/CFDDomain"
+ },
+ "mesh": {
+ "$ref": "#/$defs/MeshParameters"
+ },
+ "turbulence": {
+ "$ref": "#/$defs/TurbulenceParameters"
+ },
+ "boundary_conditions": {
+ "$ref": "#/$defs/BoundaryConditions"
+ },
+ "solver": {
+ "$ref": "#/$defs/SolverSettings"
+ },
+ "output": {
+ "$ref": "#/$defs/OutputParameters"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-community-energy.json b/schema-community-energy.json
new file mode 100644
index 0000000..7e0025d
--- /dev/null
+++ b/schema-community-energy.json
@@ -0,0 +1,263 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/community-energy",
+ "title": "Community-Scale Energy Schema",
+ "description": "District energy system parameters for community scale. Covers plants, networks, pipes, and building connections.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "PlantType": {
+ "type": "string",
+ "enum": [
+ "CHP",
+ "GasBoiler",
+ "ElectricBoiler",
+ "GroundSourceHeatPump",
+ "AirSourceHeatPump",
+ "Chiller",
+ "CoolingTower",
+ "ThermalStorage",
+ "SolarThermal",
+ "PV"
+ ]
+ },
+ "NetworkType": {
+ "type": "string",
+ "enum": [
+ "CHW",
+ "HW",
+ "Steam",
+ "Electricity"
+ ]
+ },
+ "Plant": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Plant"
+ },
+ "plant_type": {
+ "$ref": "#/$defs/PlantType"
+ },
+ "rated_capacity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "kW"
+ },
+ "cop": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "fuel_type": {
+ "type": "string",
+ "default": "natural_gas"
+ },
+ "location": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "type",
+ "plant_type",
+ "rated_capacity"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Pipe": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Pipe"
+ },
+ "start_node": {
+ "type": "string"
+ },
+ "end_node": {
+ "type": "string"
+ },
+ "length": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "m"
+ },
+ "diameter": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "m"
+ },
+ "insulation_thickness": {
+ "type": "number",
+ "minimum": 0,
+ "default": 0
+ },
+ "insulation_conductivity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.04
+ }
+ },
+ "required": [
+ "type",
+ "start_node",
+ "end_node",
+ "length",
+ "diameter"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Network": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Network"
+ },
+ "network_type": {
+ "$ref": "#/$defs/NetworkType"
+ },
+ "supply_temperature": {
+ "type": "number",
+ "description": "Celsius"
+ },
+ "return_temperature": {
+ "type": "number",
+ "description": "Celsius"
+ },
+ "pipes": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/Pipe"
+ }
+ }
+ },
+ "required": [
+ "type",
+ "network_type",
+ "pipes"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "BuildingConnection": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "BuildingConnection"
+ },
+ "building_ref": {
+ "type": "string"
+ },
+ "network_ref": {
+ "type": "string"
+ },
+ "design_flow_rate": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ }
+ },
+ "required": [
+ "type",
+ "building_ref",
+ "network_ref"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "DistrictEnergy": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "DistrictEnergy"
+ },
+ "plants": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/Plant"
+ }
+ },
+ "networks": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/Network"
+ }
+ },
+ "connections": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/BuildingConnection"
+ }
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-community-microclimate.json b/schema-community-microclimate.json
new file mode 100644
index 0000000..0cf73a8
--- /dev/null
+++ b/schema-community-microclimate.json
@@ -0,0 +1,68 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/community-microclimate",
+ "title": "Community-Scale Microclimate Schema",
+ "description": "Microclimate parameters for community scale: urban heat island, wind correction, and surface albedo.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "MicroClimate": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "MicroClimate"
+ },
+ "uhi_intensity": {
+ "type": "number",
+ "description": "Urban heat island intensity in degrees Celsius"
+ },
+ "wind_correction_factor": {
+ "type": "number",
+ "default": 1
+ },
+ "albedo": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.2
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-community.json b/schema-community.json
new file mode 100644
index 0000000..991bd95
--- /dev/null
+++ b/schema-community.json
@@ -0,0 +1,321 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/community",
+ "title": "Community-Scale Geometry Schema",
+ "description": "Community/site scale geometry: site boundaries, terrain, roads, green spaces, and water bodies. Energy, CFD, and other simulation parameters are in separate schema-community-*.json files.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "TerrainGrid": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "TerrainGrid"
+ },
+ "grid_origin": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "grid_size_x": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "grid_size_y": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "elevations": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ }
+ }
+ },
+ "required": [
+ "type",
+ "grid_origin",
+ "grid_size_x",
+ "grid_size_y",
+ "cell_size",
+ "elevations"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "TerrainTIN": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "TerrainTIN"
+ },
+ "vertices": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "minItems": 3
+ },
+ "triangles": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "minItems": 1
+ }
+ },
+ "required": [
+ "type",
+ "vertices",
+ "triangles"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Road": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Road"
+ },
+ "centerline": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 2,
+ "maxItems": 3
+ },
+ "minItems": 2
+ },
+ "width": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "surface_material": {
+ "type": "string",
+ "default": "asphalt"
+ }
+ },
+ "required": [
+ "type",
+ "centerline",
+ "width"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "GreenSpace": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "GreenSpace"
+ },
+ "boundary": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "minItems": 3
+ },
+ "vegetation_type": {
+ "type": "string",
+ "default": "grass"
+ },
+ "leaf_area_index": {
+ "type": "number",
+ "minimum": 0,
+ "default": 1
+ }
+ },
+ "required": [
+ "type",
+ "boundary"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "WaterBody": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WaterBody"
+ },
+ "boundary": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "minItems": 3
+ },
+ "depth": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "water_temperature": {
+ "type": "number",
+ "default": 20
+ }
+ },
+ "required": [
+ "type",
+ "boundary"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Site": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Site"
+ },
+ "boundary": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "minItems": 3
+ },
+ "terrain": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/TerrainGrid"
+ },
+ {
+ "$ref": "#/$defs/TerrainTIN"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "roads": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/Road"
+ }
+ },
+ "green_spaces": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/GreenSpace"
+ }
+ },
+ "water_bodies": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/WaterBody"
+ }
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-energy.json b/schema-energy.json
index baa6ab0..8048d2c 100644
--- a/schema-energy.json
+++ b/schema-energy.json
@@ -1,201 +1,2713 @@
{
- "archgen": {
- "version": "0.1.0",
- "description": "ArchGen Schema — 能耗模拟领域",
- "tags": {
- "scale": {
- "building": "建筑尺度",
- "community": "社区/街区尺度",
- "urban": "城市尺度"
- },
- "simulation": {
- "energy": "能耗模拟",
- "daylight": "采光分析",
- "solar": "日照分析",
- "thermal_comfort": "热舒适分析",
- "carbon": "碳排放核算",
- "wind": "风环境模拟",
- "general": "通用"
- }
- }
- },
-
- "types": {
- "TimePoint": {
- "description": "时刻点 [时, 分]",
- "fields": {
- "hour": { "type": "integer", "default": 0 },
- "minute": { "type": "integer", "default": 0 }
- }
- },
- "DatePoint": {
- "description": "日期点 [月, 日]",
- "fields": {
- "month": { "type": "integer", "default": 1 },
- "day": { "type": "integer", "default": 1 }
- }
- },
- "Period": {
- "description": "时间范围",
- "fields": {
- "start": { "type": "DatePoint" },
- "end": { "type": "DatePoint" }
- }
- }
- },
-
- "enums": {
- "MaterialType": {
- "description": "材料类型",
- "values": ["EnergyMaterial", "EnergyMaterialNoMass", "EnergyWindowMaterialSimpleGlazSys"]
- },
- "ConstructionType": {
- "description": "构造类型",
- "values": ["OpaqueConstruction", "WindowConstruction"]
- },
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/energy",
+ "title": "HBJSON Energy Simulation Schema",
+ "description": "EnergyPlus simulation parameters compatible with honeybee-schema energy properties. Covers materials, constructions, schedules, program types, and HVAC.",
+ "$defs": {
"Roughness": {
- "description": "表面粗糙度",
- "values": ["VeryRough", "Rough", "MediumRough", "MediumSmooth", "Smooth", "VerySmooth"]
- }
- },
-
- "entities": {
- "MaterialProps": {
- "description": "材料热工物理属性",
- "tags": { "scale": ["building", "community"], "simulation": ["energy", "thermal_comfort", "carbon"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } },
- "type": { "type": "MaterialType", "default": "EnergyMaterial", "tags": { "simulation": ["energy", "carbon"] } },
- "conductivity": { "type": "number", "default": 1, "unit": "W/m·K", "description": "导热系数", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "specificHeat": { "type": "number", "default": 100, "unit": "J/kg·K", "description": "热容", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "density": { "type": "number", "default": 1000, "unit": "kg/m³", "description": "密度", "tags": { "simulation": ["energy", "carbon"] } },
- "thickness": { "type": "number", "default": 100, "unit": "mm", "description": "厚度", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "roughness": { "type": "Roughness", "default": "MediumRough", "description": "表面粗糙度", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "thermalAbsorptance": { "type": "number", "default": 0.9, "description": "热吸收率", "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort"] } },
- "solarAbsorptance": { "type": "number", "default": 0.9, "description": "太阳吸收率", "tags": { "simulation": ["energy", "daylight", "solar", "thermal_comfort"] } },
- "visibleAbsorptance": { "type": "number", "default": 0.9, "description": "可见光吸收率", "tags": { "scale": ["building"], "simulation": ["daylight"] } },
- "rValue": { "type": "number", "unit": "m²·K/W", "description": "热阻", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "uFactor": { "type": "number", "unit": "W/m²·K", "description": "传热系数", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "shgc": { "type": "number", "default": 0.6, "description": "太阳得热系数", "tags": { "simulation": ["energy", "daylight", "solar", "thermal_comfort"] } },
- "vt": { "type": "number", "default": 0.6, "description": "可见光透射比", "tags": { "simulation": ["daylight"] } },
- "embodiedCarbon": { "type": "number", "default": 0, "unit": "kgCO₂/m²", "description": "隐含碳排放", "tags": { "scale": ["building", "community", "urban"], "simulation": ["carbon"] } },
- "embodiedEnergy": { "type": "number", "default": 0, "unit": "MJ/m²", "description": "隐含能耗", "tags": { "scale": ["building", "community", "urban"], "simulation": ["carbon"] } }
- }
+ "type": "string",
+ "enum": [
+ "VeryRough",
+ "Rough",
+ "MediumRough",
+ "MediumSmooth",
+ "Smooth",
+ "VerySmooth"
+ ]
},
-
- "Construction": {
- "description": "单一构造定义(包含多层材料)",
- "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "type": { "type": "ConstructionType", "default": "OpaqueConstruction", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } }
+ "GasType": {
+ "type": "string",
+ "enum": [
+ "Air",
+ "Argon",
+ "Krypton",
+ "Xenon",
+ "Custom"
+ ]
+ },
+ "ShadeType": {
+ "type": "string",
+ "enum": [
+ "VenetianHorizontal",
+ "VenetianVertical",
+ "VenetianRotated",
+ "Mesh",
+ "Perforated",
+ "Screen",
+ "Blind"
+ ]
+ },
+ "BlindControlType": {
+ "type": "string",
+ "enum": [
+ "AlwaysOff",
+ "AlwaysOn",
+ "Schedule",
+ "OnIfHighSolarOnWindow",
+ "OnIfHighHorizontalSolar",
+ "OnIfHighOutdoorDryBulbTemperature",
+ "OnIfHighOutdoorWetBulbTemperature",
+ "OffIfHighOutdoorDryBulbTemperature",
+ "OffIfHighOutdoorWetBulbTemperature"
+ ]
+ },
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
},
- "children": {
- "materials": { "type": "MaterialProps", "multiple": true, "description": "材料层列表(从外到内)", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } }
- }
+ "required": [
+ "identifier"
+ ]
},
-
- "SubSet": {
- "description": "特定部位的构造组合",
- "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "type": { "type": "string", "tags": { "simulation": ["general"] } },
- "exteriorConstruction": { "type": "Construction", "description": "外部构造", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "interiorConstruction": { "type": "Construction", "description": "内部构造", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "groundConstruction": { "type": "Construction", "description": "地面构造", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "overheadConstruction": { "type": "Construction", "description": "顶棚构造", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "skylightConstruction": { "type": "Construction", "description": "天窗构造", "tags": { "simulation": ["energy", "daylight"] } },
- "operableConstruction": { "type": "Construction", "description": "可开启构造", "tags": { "simulation": ["energy", "wind"] } },
- "windowConstruction": { "type": "Construction", "description": "窗户构造", "tags": { "simulation": ["energy", "daylight", "solar"] } }
- }
+ "EnergyMaterial": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyMaterial"
+ },
+ "roughness": {
+ "$ref": "#/$defs/Roughness",
+ "default": "MediumRough"
+ },
+ "thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.1
+ },
+ "conductivity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "density": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1000
+ },
+ "specific_heat": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1000
+ },
+ "thermal_absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "solar_absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ },
+ "visible_absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ }
+ },
+ "required": [
+ "type",
+ "thickness",
+ "conductivity",
+ "density",
+ "specific_heat"
+ ],
+ "additionalProperties": false
+ }
+ ]
},
-
- "ConstructionSet": {
- "description": "全楼构造合集",
- "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "airBoundaryConstruction": { "type": "string", "description": "空气边界构造 ID", "tags": { "simulation": ["energy"] } },
- "shadeConstruction": { "type": "string", "description": "遮阳构造 ID", "tags": { "simulation": ["energy", "daylight", "solar"] } }
- },
- "children": {
- "wallSet": { "type": "SubSet", "description": "墙体构造", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "floorSet": { "type": "SubSet", "description": "楼板构造", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "roofCeilingSet": { "type": "SubSet", "description": "屋顶/顶棚构造", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "doorSet": { "type": "SubSet", "description": "门构造", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "apertureSet": { "type": "SubSet", "description": "洞口构造", "tags": { "simulation": ["energy", "daylight", "solar"] } }
- }
+ "EnergyMaterialNoMass": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyMaterialNoMass"
+ },
+ "roughness": {
+ "$ref": "#/$defs/Roughness",
+ "default": "MediumRough"
+ },
+ "thermal_resistance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.1
+ },
+ "thermal_absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "solar_absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ },
+ "visible_absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ }
+ },
+ "required": [
+ "type",
+ "thermal_resistance"
+ ],
+ "additionalProperties": false
+ }
+ ]
},
-
- "RoomProgram": {
- "description": "房间功能程序定义(人员、灯光、设备等热增益参数)",
- "tags": { "scale": ["building"], "simulation": ["energy", "thermal_comfort", "carbon"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "peopleDensity": { "type": "number", "default": 0.0333, "unit": "people/m²", "description": "人员密度", "tags": { "simulation": ["energy", "thermal_comfort", "carbon"] } },
- "lightingDensity": { "type": "number", "default": 0, "unit": "W/m²", "description": "照明功率密度", "tags": { "simulation": ["energy", "daylight", "carbon"] } },
- "equipmentDensity": { "type": "number", "default": 0, "unit": "W/m²", "description": "设备功率密度", "tags": { "simulation": ["energy", "carbon"] } },
- "infiltrationCoefficient": { "type": "number", "default": 0.0003, "unit": "m³/s·m²", "description": "渗透风系数", "tags": { "simulation": ["energy", "wind", "thermal_comfort"] } },
- "heatingSetpoint": { "type": "number", "default": 18, "unit": "°C", "description": "采暖设定温度", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "coolingSetpoint": { "type": "number", "default": 26, "unit": "°C", "description": "制冷设定温度", "tags": { "simulation": ["energy", "thermal_comfort"] } }
- },
- "children": {
- "occupancySchedule": { "type": "ScheduleRuleset", "description": "人员在室率排程", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "lightingSchedule": { "type": "ScheduleRuleset", "description": "照明使用率排程", "tags": { "simulation": ["energy", "daylight"] } },
- "equipmentSchedule": { "type": "ScheduleRuleset", "description": "设备使用率排程", "tags": { "simulation": ["energy"] } },
- "infiltrationSchedule": { "type": "ScheduleRuleset", "description": "渗透风排程", "tags": { "simulation": ["energy", "wind"] } },
- "heatingSchedule": { "type": "ScheduleRuleset", "description": "采暖设定温度排程", "tags": { "simulation": ["energy", "thermal_comfort"] } },
- "coolingSchedule": { "type": "ScheduleRuleset", "description": "制冷设定温度排程", "tags": { "simulation": ["energy", "thermal_comfort"] } }
- }
+ "EnergyMaterialVegetation": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyMaterialVegetation"
+ },
+ "roughness": {
+ "$ref": "#/$defs/Roughness",
+ "default": "MediumRough"
+ },
+ "thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.1
+ },
+ "conductivity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.1
+ },
+ "density": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 100
+ },
+ "specific_heat": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1400
+ },
+ "leaf_area_index": {
+ "type": "number",
+ "minimum": 0,
+ "default": 1
+ },
+ "leaf_reflectivity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.2
+ },
+ "leaf_emissivity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "min_stomatal_resistance": {
+ "type": "number",
+ "minimum": 0,
+ "default": 180
+ },
+ "soil_layer_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "thermal_absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ }
+ },
+ "required": [
+ "type",
+ "thickness",
+ "conductivity",
+ "density",
+ "specific_heat",
+ "leaf_area_index"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowMaterialGlazing": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowMaterialGlazing"
+ },
+ "solar_transmittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ },
+ "solar_transmittance_normal_incidence": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "solar_reflectance_front": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.07
+ },
+ "solar_reflectance_back": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.07
+ },
+ "visible_transmittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "visible_transmittance_normal_incidence": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "visible_reflectance_front": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.07
+ },
+ "visible_reflectance_back": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.07
+ },
+ "infrared_transmittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "infrared_hemisissivity_front": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.84
+ },
+ "infrared_hemisissivity_back": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.84
+ },
+ "thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.006
+ },
+ "conductivity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "dirt_correction_factor": {
+ "type": "number",
+ "minimum": 0.8,
+ "maximum": 1,
+ "default": 1
+ },
+ "solar_diffusing": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "required": [
+ "type",
+ "thickness"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowMaterialGas": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowMaterialGas"
+ },
+ "gas_type": {
+ "$ref": "#/$defs/GasType",
+ "default": "Air"
+ },
+ "thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.0127
+ }
+ },
+ "required": [
+ "type",
+ "thickness"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowMaterialGasCustom": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowMaterialGasCustom"
+ },
+ "conductivity_coefficient_A": {
+ "type": "number",
+ "default": 0
+ },
+ "conductivity_coefficient_B": {
+ "type": "number",
+ "default": 0
+ },
+ "viscosity_coefficient_A": {
+ "type": "number",
+ "default": 0
+ },
+ "viscosity_coefficient_B": {
+ "type": "number",
+ "default": 0
+ },
+ "specific_heat_coefficient_A": {
+ "type": "number",
+ "default": 0
+ },
+ "specific_heat_coefficient_B": {
+ "type": "number",
+ "default": 0
+ },
+ "specific_heat_ratio": {
+ "type": "number",
+ "default": 0
+ },
+ "molecular_weight": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0
+ },
+ "thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.0127
+ }
+ },
+ "required": [
+ "type",
+ "thickness"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowMaterialGasMixture": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowMaterialGasMixture"
+ },
+ "gas_key_options": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/GasType"
+ },
+ "minItems": 2,
+ "maxItems": 10
+ },
+ "gas_fractions": {
+ "type": "array",
+ "items": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "minItems": 2,
+ "maxItems": 10
+ },
+ "thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.0127
+ }
+ },
+ "required": [
+ "type",
+ "gas_key_options",
+ "gas_fractions",
+ "thickness"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowMaterialSimpleGlazSys": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowMaterialSimpleGlazSys"
+ },
+ "u_factor": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "shgc": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.6
+ },
+ "visible_transmittance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ }
+ },
+ "required": [
+ "type",
+ "u_factor",
+ "shgc"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowMaterialBlind": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowMaterialBlind"
+ },
+ "shade_type": {
+ "$ref": "#/$defs/ShadeType",
+ "default": "VenetianHorizontal"
+ },
+ "slat_material": {
+ "type": "string",
+ "default": "Aluminum"
+ },
+ "slat_width": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.025
+ },
+ "slat_separation": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.021
+ },
+ "slat_thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.0005
+ },
+ "slat_angle": {
+ "type": "number",
+ "minimum": -90,
+ "maximum": 90,
+ "default": 45
+ },
+ "slat_conductivity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 177
+ },
+ "slat_beam_solar_transmittance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_beam_solar_reflectance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_diffuse_solar_transmittance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_diffuse_solar_reflectance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_beam_visible_transmittance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_beam_visible_reflectance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_diffuse_visible_transmittance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_diffuse_visible_reflectance": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "maximum": 1
+ },
+ "slat_infrared_transmittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "slat_infrared_hemisissivity_front": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "slat_infrared_hemisissivity_back": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "slat_infrared_hemisissivity_holes": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "slat_conductivity_ratio": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "top_opening_multiplier": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "bottom_opening_multiplier": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "side_opening_multiplier": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type",
+ "slat_width",
+ "slat_separation",
+ "slat_thickness",
+ "slat_angle"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowMaterialShade": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowMaterialShade"
+ },
+ "shade_type": {
+ "$ref": "#/$defs/ShadeType",
+ "default": "Mesh"
+ },
+ "solar_transmittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.3
+ },
+ "solar_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.5
+ },
+ "visible_transmittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.3
+ },
+ "visible_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.5
+ },
+ "infrared_hemisissivity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "infrared_transmittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "thickness": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "conductivity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.1
+ }
+ },
+ "required": [
+ "type",
+ "thickness",
+ "conductivity"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EnergyWindowFrame": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "EnergyWindowFrame"
+ },
+ "frame_conductance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "frame_edge_glazing_correction_factor": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.85
+ },
+ "frame_area": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "inside_sill_depth": {
+ "type": "number",
+ "default": 0.0254
+ },
+ "inside_sill_insulation_ratio": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.6
+ },
+ "outside_sill_depth": {
+ "type": "number",
+ "default": 0.0254
+ },
+ "outside_sill_insulation_ratio": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.6
+ },
+ "absorptance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.5
+ }
+ },
+ "required": [
+ "type",
+ "frame_conductance",
+ "frame_area"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "OpaqueConstruction": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "OpaqueConstruction"
+ },
+ "layers": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/EnergyMaterial"
+ },
+ {
+ "$ref": "#/$defs/EnergyMaterialNoMass"
+ },
+ {
+ "$ref": "#/$defs/EnergyMaterialVegetation"
+ }
+ ]
+ },
+ "minItems": 1
+ }
+ },
+ "required": [
+ "type",
+ "layers"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "WindowConstruction": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindowConstruction"
+ },
+ "layers": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialSimpleGlazSys"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGlazing"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGas"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGasCustom"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGasMixture"
+ }
+ ]
+ },
+ "minItems": 1
+ }
+ },
+ "required": [
+ "type",
+ "layers"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "WindowConstructionShade": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindowConstructionShade"
+ },
+ "window_construction": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/WindowConstruction"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialSimpleGlazSys"
+ }
+ ]
+ },
+ "indoor_shade": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialBlind"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialShade"
+ }
+ ]
+ },
+ "outdoor_shade": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialBlind"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialShade"
+ }
+ ]
+ },
+ "blind_control_type": {
+ "$ref": "#/$defs/BlindControlType",
+ "default": "AlwaysOff"
+ },
+ "blind_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "slat_angle_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "outdoor_blind_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "outdoor_slat_angle_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "switchable_glazing_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "outdoor_blind_control_type": {
+ "$ref": "#/$defs/BlindControlType",
+ "default": "AlwaysOff"
+ }
+ },
+ "required": [
+ "type",
+ "window_construction"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "WindowConstructionDynamic": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindowConstructionDynamic"
+ },
+ "window_constructions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/WindowConstruction"
+ },
+ "minItems": 2
+ }
+ },
+ "required": [
+ "type",
+ "window_constructions"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "AirBoundaryConstruction": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "AirBoundaryConstruction"
+ },
+ "mixing_per_room_floor_area": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.00372
+ },
+ "mixing_air_flow_coefficient": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "thermal_resistance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.05
+ }
+ },
+ "required": [
+ "type",
+ "mixing_per_room_floor_area",
+ "mixing_air_flow_coefficient"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ShadeConstruction": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ShadeConstruction"
+ },
+ "solar_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.2
+ },
+ "visible_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.2
+ },
+ "is_specular": {
+ "type": "boolean",
+ "default": false
+ },
+ "transmittance_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "OpaqueConstructionAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "OpaqueConstructionAbridged"
+ },
+ "layers": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1
+ }
+ },
+ "required": [
+ "type",
+ "layers"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "WindowConstructionAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindowConstructionAbridged"
+ },
+ "layers": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1
+ }
+ },
+ "required": [
+ "type",
+ "layers"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "AirBoundaryConstructionAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "AirBoundaryConstructionAbridged"
+ },
+ "mixing_per_room_floor_area": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.00372
+ },
+ "mixing_air_flow_coefficient": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1
+ },
+ "thermal_resistance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.05
+ }
+ },
+ "required": [
+ "type",
+ "mixing_per_room_floor_area",
+ "mixing_air_flow_coefficient"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ScheduleTypeLimit": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ScheduleTypeLimit"
+ },
+ "data_type": {
+ "type": "string",
+ "default": "Continuous"
+ },
+ "unit_type": {
+ "type": "string",
+ "default": "Dimensionless"
+ },
+ "lower_limit": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "upper_limit": {
+ "type": [
+ "number",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
},
-
"ScheduleDay": {
- "description": "单一全天时刻值序列定义",
- "tags": { "simulation": ["general"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "times": { "type": "TimePoint[]", "description": "时刻点列表", "tags": { "simulation": ["general"] } },
- "values": { "type": "number[]", "description": "对应时刻的值列表", "tags": { "simulation": ["general"] } },
- "interpolate": { "type": "boolean", "default": false, "description": "是否插值", "tags": { "simulation": ["general"] } }
- }
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ScheduleDay"
+ },
+ "values": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 1
+ },
+ "times": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "minItems": 1
+ },
+ "interpolate": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "required": [
+ "type",
+ "values",
+ "times"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ScheduleFixedInterval": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ScheduleFixedInterval"
+ },
+ "schedule_type_limit": {
+ "$ref": "#/$defs/ScheduleTypeLimit"
+ },
+ "timestep": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ },
+ "values": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 1
+ },
+ "interpolate": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "required": [
+ "type",
+ "values"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ScheduleRulesetAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ScheduleRulesetAbridged"
+ },
+ "schedule_type_limit": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/ScheduleTypeLimit"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default_day_schedule_id": {
+ "type": "string"
+ },
+ "day_schedules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ScheduleDay"
+ },
+ "minItems": 1
+ },
+ "schedule_rules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ScheduleRule"
+ }
+ },
+ "holiday_schedule_id": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "summer_design_day_schedule_id": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "winter_design_day_schedule_id": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "default_day_schedule_id",
+ "day_schedules"
+ ],
+ "additionalProperties": false
+ }
+ ]
},
-
"ScheduleRule": {
- "description": "基于日期范围与星期的排程应用规则",
- "tags": { "simulation": ["general"] },
- "attributes": {
- "startDate": { "type": "DatePoint", "required": true, "description": "规则开始日期", "tags": { "simulation": ["general"] } },
- "endDate": { "type": "DatePoint", "required": true, "description": "规则结束日期", "tags": { "simulation": ["general"] } },
- "applyMonday": { "type": "boolean", "default": true, "tags": { "simulation": ["general"] } },
- "applyTuesday": { "type": "boolean", "default": true, "tags": { "simulation": ["general"] } },
- "applyWednesday": { "type": "boolean", "default": true, "tags": { "simulation": ["general"] } },
- "applyThursday": { "type": "boolean", "default": true, "tags": { "simulation": ["general"] } },
- "applyFriday": { "type": "boolean", "default": true, "tags": { "simulation": ["general"] } },
- "applySaturday": { "type": "boolean", "default": true, "tags": { "simulation": ["general"] } },
- "applySunday": { "type": "boolean", "default": true, "tags": { "simulation": ["general"] } }
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ScheduleRule"
+ },
+ "start_date": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "end_date": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "apply_monday": {
+ "type": "boolean",
+ "default": true
+ },
+ "apply_tuesday": {
+ "type": "boolean",
+ "default": true
+ },
+ "apply_wednesday": {
+ "type": "boolean",
+ "default": true
+ },
+ "apply_thursday": {
+ "type": "boolean",
+ "default": true
+ },
+ "apply_friday": {
+ "type": "boolean",
+ "default": true
+ },
+ "apply_saturday": {
+ "type": "boolean",
+ "default": true
+ },
+ "apply_sunday": {
+ "type": "boolean",
+ "default": true
+ },
+ "day_schedule_id": {
+ "type": "string"
+ }
},
- "children": {
- "scheduleDay": { "type": "ScheduleDay", "description": "关联的日排程", "tags": { "simulation": ["general"] } }
- }
+ "required": [
+ "type",
+ "day_schedule_id"
+ ],
+ "additionalProperties": false
},
-
- "ScheduleRuleset": {
- "description": "排程规则集(包含默认值与特殊规则)",
- "tags": { "simulation": ["general"] },
- "attributes": {
- "identifier": { "type": "string", "required": true, "tags": { "simulation": ["general"] } },
- "displayName": { "type": "string", "tags": { "simulation": ["general"] } }
+ "PeopleAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "PeopleAbridged"
+ },
+ "people_per_square_meter": {
+ "type": "number",
+ "default": 0
+ },
+ "occupancy_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "activity_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "latent_fraction_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "radiant_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.3
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "LightingAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "LightingAbridged"
+ },
+ "watts_per_square_meter": {
+ "type": "number",
+ "default": 0
+ },
+ "lighting_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "visible_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.2
+ },
+ "radiant_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ },
+ "return_air_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ElectricEquipmentAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ElectricEquipmentAbridged"
+ },
+ "watts_per_square_meter": {
+ "type": "number",
+ "default": 0
+ },
+ "equipment_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "radiant_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.5
+ },
+ "latent_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "lost_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "GasEquipmentAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "GasEquipmentAbridged"
+ },
+ "watts_per_square_meter": {
+ "type": "number",
+ "default": 0
+ },
+ "equipment_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "radiant_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.1
+ },
+ "latent_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.1
+ },
+ "lost_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.4
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ServiceHotWaterAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ServiceHotWaterAbridged"
+ },
+ "liters_per_hour_per_person": {
+ "type": "number",
+ "default": 0
+ },
+ "hot_water_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "hot_water_target_temperature": {
+ "type": "number",
+ "default": 60
+ },
+ "cold_water_temperature": {
+ "type": "number",
+ "default": 10
+ },
+ "hot_water_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.6
+ },
+ "waste_water_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "InfiltrationAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "InfiltrationAbridged"
+ },
+ "air_changes_per_hour": {
+ "type": "number",
+ "default": 0
+ },
+ "infiltration_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "constant_coefficient": {
+ "type": "number",
+ "default": 1
+ },
+ "temperature_coefficient": {
+ "type": "number",
+ "default": 0
+ },
+ "velocity_coefficient": {
+ "type": "number",
+ "default": 0
+ },
+ "temperature_difference_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "velocity_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "VentilationAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "VentilationAbridged"
+ },
+ "outdoor_air_per_person": {
+ "type": "number",
+ "default": 0
+ },
+ "outdoor_air_per_area": {
+ "type": "number",
+ "default": 0
+ },
+ "air_changes_per_hour": {
+ "type": "number",
+ "default": 0
+ },
+ "sum_per_floor_area": {
+ "type": "number",
+ "default": 0
+ },
+ "ventilation_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "SetpointAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "SetpointAbridged"
+ },
+ "heating_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "cooling_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "humidifying_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "dehumidifying_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "minimum_input_ratio_heating_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "minimum_input_ratio_cooling_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "maximum_dry_bulb_temperature_setpoint": {
+ "type": "number",
+ "default": 300
+ },
+ "minimum_dry_bulb_temperature_setpoint": {
+ "type": "number",
+ "default": 0
+ },
+ "delta_temperature": {
+ "type": "number",
+ "default": 0
+ },
+ "delta_temperature_setpoint_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "InternalMassAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "InternalMassAbridged"
+ },
+ "construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "surface_area_per_floor_area": {
+ "type": "number",
+ "default": 0
+ },
+ "surface_area": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "number_of_units": {
+ "type": "number",
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "DaylightingControl": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "DaylightingControl"
+ },
+ "illuminance_setpoint": {
+ "type": "number",
+ "default": 0
+ },
+ "lighting_control_type": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 4,
+ "default": 1
+ },
+ "glare_sensor_azimuth": {
+ "type": "number",
+ "default": 0
+ },
+ "minimum_input_power_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.3
+ },
+ "minimum_light_output_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.2
+ },
+ "setpoint_at_reference_point_1": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "setpoint_at_reference_point_2": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "sensor_position_1": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "sensor_position_2": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "de daylighting_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "availability_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "VentilationOpening": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "VentilationOpening"
+ },
+ "operable_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 1
+ },
+ "discharge_coefficient": {
+ "type": "number",
+ "default": 0.65
+ },
+ "discharge_coefficient_when_no_wind": {
+ "type": "number",
+ "default": 0.65
+ },
+ "opening_factor": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 1
+ }
},
- "children": {
- "defaultDaySchedule": { "type": "ScheduleDay", "description": "默认日排程", "tags": { "simulation": ["general"] } },
- "scheduleRules": { "type": "ScheduleRule", "multiple": true, "description": "特殊规则列表", "tags": { "simulation": ["general"] } },
- "daySchedules": { "type": "ScheduleDay", "multiple": true, "description": "所有日排程列表", "tags": { "simulation": ["general"] } }
- }
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "ProgramTypeAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ProgramTypeAbridged"
+ },
+ "people": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/PeopleAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "lighting": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/LightingAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "electric_equipment": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/ElectricEquipmentAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "gas_equipment": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/GasEquipmentAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "service_hot_water": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/ServiceHotWaterAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "infiltration": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/InfiltrationAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "ventilation": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/VentilationAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "setpoint": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/SetpointAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "internal_mass": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/InternalMassAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "daylighting_control": {
+ "$ref": "#/$defs/DaylightingControl"
+ },
+ "comfort_parameters": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "process": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/ProcessAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ProcessAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ProcessAbridged"
+ },
+ "watts_per_square_meter": {
+ "type": "number",
+ "default": 0
+ },
+ "process_schedule": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "radiant_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.5
+ },
+ "latent_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "lost_fraction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "IdealAirSystemAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "IdealAirSystemAbridged"
+ },
+ "system_air_flow_rate": {
+ "type": "string",
+ "default": "Autosize"
+ },
+ "demand_controlled_ventilation_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "demand_high_altitude_cooling": {
+ "type": "boolean",
+ "default": false
+ },
+ "heat_recovery_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "sensible_heat_recovery": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "latent_heat_recovery": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "economizer_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "economizer_maximum_dry_bulb_temperature": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "economizer_maximum_enthalpy": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "cooling_limit": {
+ "type": "number"
+ },
+ "cooling_air_temperature": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "heating_limit": {
+ "type": "number"
+ },
+ "heating_air_temperature": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "outdoor_air_mixer_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "ventilation_control_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "maximum_outdoor_air_flow_rate": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "minimum_outdoor_air_flow_rate": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "humidifier_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "dehumidifier_type": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "dehumidification_setpoint": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "cooling_setpoint": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "heating_setpoint": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ConstructionSetAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ConstructionSetAbridged"
+ },
+ "wall_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "floor_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "roof_ceiling_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "aperture_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "door_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "skylight_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_wall_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_floor_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_ceiling_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "ground_wall_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "ground_floor_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "ground_ceiling_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "air_boundary_construction": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "BuildingType": {
+ "type": "string",
+ "enum": [
+ "Residential",
+ "SingleFamily",
+ "MultiFamily",
+ "Office",
+ "Retail",
+ "PrimarySchool",
+ "SecondarySchool",
+ "Hospital",
+ "College",
+ "Warehouse",
+ "HotelSmall",
+ "HotelLarge",
+ "Restaurant",
+ "OutPatientHealthCare",
+ "InPatientHealthCare"
+ ]
+ },
+ "DefaultProgramTypesAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "DefaultProgramTypesAbridged"
+ },
+ "program_type": {
+ "type": "object",
+ "patternProperties": {
+ ".*": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/ProgramTypeAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
+ "building_type": {
+ "$ref": "#/$defs/BuildingType"
+ }
+ },
+ "required": [
+ "type",
+ "program_type"
+ ],
+ "additionalProperties": false
+ },
+ "DefaultConstructionSetAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "DefaultConstructionSetAbridged"
+ },
+ "construction_set": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/ConstructionSetAbridged"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "building_type": {
+ "$ref": "#/$defs/BuildingType"
+ }
+ },
+ "required": [
+ "type",
+ "construction_set"
+ ],
+ "additionalProperties": false
+ },
+ "ModelEnergyProperties": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ModelEnergyProperties"
+ },
+ "construction_sets": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ConstructionSetAbridged"
+ }
+ },
+ "materials": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/EnergyMaterial"
+ },
+ {
+ "$ref": "#/$defs/EnergyMaterialNoMass"
+ },
+ {
+ "$ref": "#/$defs/EnergyMaterialVegetation"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialSimpleGlazSys"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGlazing"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGas"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGasCustom"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialGasMixture"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialBlind"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowMaterialShade"
+ },
+ {
+ "$ref": "#/$defs/EnergyWindowFrame"
+ }
+ ]
+ }
+ },
+ "constructions": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/OpaqueConstructionAbridged"
+ },
+ {
+ "$ref": "#/$defs/WindowConstructionAbridged"
+ },
+ {
+ "$ref": "#/$defs/AirBoundaryConstructionAbridged"
+ },
+ {
+ "$ref": "#/$defs/ShadeConstruction"
+ }
+ ]
+ }
+ },
+ "schedules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ScheduleRulesetAbridged"
+ }
+ },
+ "schedule_type_limits": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ScheduleTypeLimit"
+ }
+ },
+ "program_types": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ProgramTypeAbridged"
+ }
+ },
+ "hvac": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/IdealAirSystemAbridged"
+ }
+ ]
+ }
+ },
+ "shw": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "default_program_types": {
+ "$ref": "#/$defs/DefaultProgramTypesAbridged"
+ },
+ "default_construction_sets": {
+ "$ref": "#/$defs/DefaultConstructionSetAbridged"
+ },
+ "climate_base": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "simulation_control": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "shadow_calculation": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "output_conventions": {
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "output_meters": {
+ "type": [
+ "array",
+ "null"
+ ]
+ },
+ "design_days": {
+ "type": [
+ "array",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
}
}
-}
+}
\ No newline at end of file
diff --git a/schema-radiance.json b/schema-radiance.json
new file mode 100644
index 0000000..43981f6
--- /dev/null
+++ b/schema-radiance.json
@@ -0,0 +1,980 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/radiance",
+ "title": "HBJSON Radiance Daylighting Schema",
+ "description": "Radiance daylighting simulation parameters compatible with honeybee-schema radiance properties. Covers modifiers, modifier sets, sensor grids, views, and dynamic states.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "Void": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Void"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "Plastic": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Plastic"
+ },
+ "r_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "g_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "b_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "specularity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "roughness": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Metal": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Metal"
+ },
+ "r_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "g_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "b_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "specularity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0.9
+ },
+ "roughness": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Trans": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Trans"
+ },
+ "r_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "g_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "b_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "specularity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "roughness": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "transmitted_diff": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "transmitted_spec": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Glass": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Glass"
+ },
+ "r_transmissivity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "g_transmissivity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "b_transmissivity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "refraction_index": {
+ "type": "number",
+ "exclusiveMinimum": 1,
+ "default": 1.52
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Mirror": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Mirror"
+ },
+ "r_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 1
+ },
+ "g_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 1
+ },
+ "b_reflectance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 1
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Light": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Light"
+ },
+ "r_emittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "g_emittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "b_emittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Glow": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Glow"
+ },
+ "r_emittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "g_emittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "b_emittance": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1,
+ "default": 0
+ },
+ "max_radius": {
+ "type": "number",
+ "default": 0
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "BSDF": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "BSDF"
+ },
+ "up_orientation": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3,
+ "default": [
+ 0.01,
+ 0.01,
+ 1.0
+ ]
+ },
+ "thickness": {
+ "type": "number",
+ "default": 0
+ },
+ "function_file": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 100,
+ "default": "."
+ },
+ "transform": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "bsdf_data": {
+ "type": "string",
+ "minLength": 1
+ },
+ "front_diffuse_reflectance": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "back_diffuse_reflectance": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "diffuse_transmittance": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "type",
+ "bsdf_data"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Modifier": {
+ "oneOf": [
+ {
+ "$ref": "#/$defs/Plastic"
+ },
+ {
+ "$ref": "#/$defs/Metal"
+ },
+ {
+ "$ref": "#/$defs/Trans"
+ },
+ {
+ "$ref": "#/$defs/Glass"
+ },
+ {
+ "$ref": "#/$defs/Mirror"
+ },
+ {
+ "$ref": "#/$defs/Light"
+ },
+ {
+ "$ref": "#/$defs/Glow"
+ },
+ {
+ "$ref": "#/$defs/BSDF"
+ },
+ {
+ "$ref": "#/$defs/Void"
+ }
+ ]
+ },
+ "WallModifierSetAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WallModifierSetAbridged"
+ },
+ "exterior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "FloorModifierSetAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "FloorModifierSetAbridged"
+ },
+ "exterior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "RoofCeilingModifierSetAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "RoofCeilingModifierSetAbridged"
+ },
+ "exterior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "ApertureModifierSetAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ApertureModifierSetAbridged"
+ },
+ "window_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "skylight_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "operable_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "DoorModifierSetAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "DoorModifierSetAbridged"
+ },
+ "exterior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "ShadeModifierSetAbridged": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ShadeModifierSetAbridged"
+ },
+ "exterior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interior_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ },
+ "ModifierSet": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ModifierSet"
+ },
+ "wall_set": {
+ "$ref": "#/$defs/WallModifierSetAbridged"
+ },
+ "floor_set": {
+ "$ref": "#/$defs/FloorModifierSetAbridged"
+ },
+ "roof_ceiling_set": {
+ "$ref": "#/$defs/RoofCeilingModifierSetAbridged"
+ },
+ "aperture_set": {
+ "$ref": "#/$defs/ApertureModifierSetAbridged"
+ },
+ "door_set": {
+ "$ref": "#/$defs/DoorModifierSetAbridged"
+ },
+ "shade_set": {
+ "$ref": "#/$defs/ShadeModifierSetAbridged"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "RadianceSubFaceStateAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "RadianceSubFaceStateAbridged"
+ },
+ "aperture_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "door_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "RadianceShadeStateAbridged": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "RadianceShadeStateAbridged"
+ },
+ "shade_modifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "Sensor": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "Sensor"
+ },
+ "pos": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "dir": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "type",
+ "pos",
+ "dir"
+ ],
+ "additionalProperties": false
+ },
+ "SensorGrid": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "SensorGrid"
+ },
+ "sensors": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/Sensor"
+ },
+ "minItems": 1
+ },
+ "mesh": {
+ "type": "object"
+ },
+ "base_geometry": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "group_identifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "room_identifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "light_path": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "required": [
+ "type",
+ "sensors"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ViewType": {
+ "type": "string",
+ "enum": [
+ "v",
+ "h",
+ "l",
+ "c",
+ "a",
+ "s"
+ ]
+ },
+ "View": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "View"
+ },
+ "position": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "direction": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "up_vector": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ },
+ "view_type": {
+ "$ref": "#/$defs/ViewType",
+ "default": "v"
+ },
+ "h_size": {
+ "type": "number",
+ "default": 60
+ },
+ "v_size": {
+ "type": "number",
+ "default": 60
+ },
+ "shift": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "lift": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "fore_clip": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "aft_clip": {
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "group_identifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "room_identifier": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "position",
+ "direction",
+ "up_vector"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ModelRadianceProperties": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ModelRadianceProperties"
+ },
+ "modifiers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/Modifier"
+ }
+ },
+ "modifier_sets": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ModifierSet"
+ }
+ },
+ "sensor_grids": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/SensorGrid"
+ }
+ },
+ "views": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/View"
+ }
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-urban-cfd.json b/schema-urban-cfd.json
new file mode 100644
index 0000000..c5abd12
--- /dev/null
+++ b/schema-urban-cfd.json
@@ -0,0 +1,741 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/urban-cfd",
+ "title": "Urban-Scale CFD Wind Environment Schema",
+ "description": "CFD parameters for urban-scale wind environment analysis. Covers larger domains with multiple districts, street canyon effects, pedestrian-level wind comfort assessment.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "WindProfileType": {
+ "type": "string",
+ "enum": [
+ "power_law",
+ "log_law",
+ "uniform",
+ "atmospheric_boundary_layer"
+ ]
+ },
+ "TerrainCategory": {
+ "type": "string",
+ "enum": [
+ "open_sea",
+ "open_country",
+ "suburban",
+ "urban_center",
+ "dense_urban"
+ ]
+ },
+ "TurbulenceModel": {
+ "type": "string",
+ "enum": [
+ "k_epsilon_standard",
+ "k_epsilon_realizable",
+ "k_epsilon_RNG",
+ "k_omega_SST",
+ "LES",
+ "DES"
+ ]
+ },
+ "SolverType": {
+ "type": "string",
+ "enum": [
+ "steady",
+ "transient"
+ ]
+ },
+ "WindComfortCriteria": {
+ "type": "string",
+ "enum": [
+ "Laws",
+ "Davenport",
+ "NEN_8100",
+ "COST_732"
+ ]
+ },
+ "WindProfile": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindProfile"
+ },
+ "profile_type": {
+ "$ref": "#/$defs/WindProfileType",
+ "default": "power_law"
+ },
+ "reference_wind_speed": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "reference_height": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 10
+ },
+ "power_law_exponent": {
+ "type": "number",
+ "minimum": 0
+ },
+ "roughness_length": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "ground_elevation": {
+ "type": "number",
+ "default": 0
+ },
+ "terrain_category": {
+ "$ref": "#/$defs/TerrainCategory",
+ "default": "suburban"
+ },
+ "wind_direction": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 360,
+ "default": 0
+ }
+ },
+ "required": [
+ "type",
+ "reference_wind_speed"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "CFDDomain": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "CFDDomain"
+ },
+ "domain_size": {
+ "type": "object",
+ "properties": {
+ "x_min": {
+ "type": "number"
+ },
+ "x_max": {
+ "type": "number"
+ },
+ "y_min": {
+ "type": "number"
+ },
+ "y_max": {
+ "type": "number"
+ },
+ "z_min": {
+ "type": "number"
+ },
+ "z_max": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "x_min",
+ "x_max",
+ "y_min",
+ "y_max",
+ "z_min",
+ "z_max"
+ ],
+ "additionalProperties": false
+ },
+ "upstream_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 5H"
+ },
+ "downstream_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 15H"
+ },
+ "lateral_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 5H"
+ },
+ "height_distance": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "description": "typically 5H"
+ }
+ },
+ "required": [
+ "type",
+ "domain_size"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "MeshParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "MeshParameters"
+ },
+ "base_cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "refinement_zones": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "zone_name": {
+ "type": "string"
+ },
+ "cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "extent": {
+ "type": "object",
+ "properties": {
+ "x_min": {
+ "type": "number"
+ },
+ "x_max": {
+ "type": "number"
+ },
+ "y_min": {
+ "type": "number"
+ },
+ "y_max": {
+ "type": "number"
+ },
+ "z_min": {
+ "type": "number"
+ },
+ "z_max": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "x_min",
+ "x_max",
+ "y_min",
+ "y_max",
+ "z_min",
+ "z_max"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "zone_name",
+ "cell_size",
+ "extent"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "pedestrian_level_height": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 3,
+ "default": 1.5,
+ "description": "m, height for pedestrian wind assessment"
+ },
+ "pedestrian_cell_size": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 1.0,
+ "description": "m, fine mesh at pedestrian level"
+ },
+ "wall_layer_first_cell_height": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "wall_layer_growth_rate": {
+ "type": "number",
+ "exclusiveMinimum": 1,
+ "maximum": 1.5,
+ "default": 1.2
+ },
+ "wall_layer_total_layers": {
+ "type": "integer",
+ "minimum": 3,
+ "default": 10
+ },
+ "mesh_type": {
+ "type": "string",
+ "enum": [
+ "hexahedral",
+ "polyhedral",
+ "tetrahedral",
+ "snappy_hex"
+ ],
+ "default": "snappy_hex"
+ }
+ },
+ "required": [
+ "type",
+ "base_cell_size"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "TurbulenceParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "TurbulenceParameters"
+ },
+ "turbulence_model": {
+ "$ref": "#/$defs/TurbulenceModel",
+ "default": "k_epsilon_RNG"
+ },
+ "turbulence_intensity": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "turbulent_length_scale": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ },
+ "wall_function_type": {
+ "type": "string",
+ "enum": [
+ "standard_wall_function",
+ "non_equilibrium",
+ "enhanced_wall_treatment",
+ "scalable_wall_function"
+ ],
+ "default": "standard_wall_function"
+ },
+ "y_plus_target": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ }
+ },
+ "required": [
+ "type",
+ "turbulence_model"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "BoundaryConditions": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "BoundaryConditions"
+ },
+ "inlet_type": {
+ "type": "string",
+ "enum": [
+ "velocity_inlet",
+ "pressure_inlet"
+ ],
+ "default": "velocity_inlet"
+ },
+ "outlet_type": {
+ "type": "string",
+ "enum": [
+ "pressure_outlet",
+ "outflow"
+ ],
+ "default": "pressure_outlet"
+ },
+ "top_boundary_type": {
+ "type": "string",
+ "enum": [
+ "symmetry",
+ "slip_wall",
+ "velocity_inlet"
+ ],
+ "default": "symmetry"
+ },
+ "side_boundary_type": {
+ "type": "string",
+ "enum": [
+ "symmetry",
+ "slip_wall"
+ ],
+ "default": "symmetry"
+ },
+ "ground_type": {
+ "type": "string",
+ "enum": [
+ "no_slip_wall",
+ "rough_wall"
+ ],
+ "default": "no_slip_wall"
+ },
+ "building_wall_type": {
+ "type": "string",
+ "enum": [
+ "no_slip_wall",
+ "rough_wall"
+ ],
+ "default": "no_slip_wall"
+ },
+ "surface_roughness_height": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "SolverSettings": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "SolverSettings"
+ },
+ "solver_type": {
+ "$ref": "#/$defs/SolverType",
+ "default": "steady"
+ },
+ "pressure_velocity_coupling": {
+ "type": "string",
+ "enum": [
+ "SIMPLE",
+ "SIMPLEC",
+ "PISO",
+ "Coupled"
+ ],
+ "default": "SIMPLE"
+ },
+ "spatial_discretization": {
+ "type": "string",
+ "enum": [
+ "first_order",
+ "second_order",
+ "QUICK",
+ "MUSCL"
+ ],
+ "default": "second_order"
+ },
+ "max_iterations": {
+ "type": "integer",
+ "minimum": 100,
+ "default": 1000
+ },
+ "convergence_criteria": {
+ "type": "object",
+ "properties": {
+ "continuity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "x_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "y_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "z_velocity": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "k": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ },
+ "epsilon": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "default": 0.001
+ }
+ },
+ "additionalProperties": false
+ },
+ "under_relaxation_factors": {
+ "type": "object",
+ "properties": {
+ "pressure": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.3
+ },
+ "momentum": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.7
+ },
+ "k": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.8
+ },
+ "epsilon": {
+ "type": "number",
+ "exclusiveMinimum": 0,
+ "maximum": 1,
+ "default": 0.8
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "WindComfortAssessment": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "WindComfortAssessment"
+ },
+ "criteria": {
+ "$ref": "#/$defs/WindComfortCriteria",
+ "default": "NEN_8100"
+ },
+ "pedestrian_level_height": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 3,
+ "default": 1.5
+ },
+ "evaluation_points": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "point_name": {
+ "type": "string"
+ },
+ "position": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "point_name",
+ "position"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "OutputParameters": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "OutputParameters"
+ },
+ "output_variables": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "velocity",
+ "pressure",
+ "turbulent_kinetic_energy",
+ "turbulent_dissipation",
+ "wall_shear_stress",
+ "vorticity"
+ ]
+ },
+ "default": [
+ "velocity",
+ "pressure"
+ ]
+ },
+ "monitoring_points": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "point_name": {
+ "type": "string"
+ },
+ "position": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 3,
+ "maxItems": 3
+ }
+ },
+ "required": [
+ "point_name",
+ "position"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "output_format": {
+ "type": "string",
+ "enum": [
+ "ensight",
+ "paraview",
+ "tecplot",
+ "csv",
+ "vtk"
+ ],
+ "default": "vtk"
+ },
+ "output_interval": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 100
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "UrbanCFDSettings": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "UrbanCFDSettings"
+ },
+ "wind_profiles": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/WindProfile"
+ }
+ },
+ "domain": {
+ "$ref": "#/$defs/CFDDomain"
+ },
+ "mesh": {
+ "$ref": "#/$defs/MeshParameters"
+ },
+ "turbulence": {
+ "$ref": "#/$defs/TurbulenceParameters"
+ },
+ "boundary_conditions": {
+ "$ref": "#/$defs/BoundaryConditions"
+ },
+ "solver": {
+ "$ref": "#/$defs/SolverSettings"
+ },
+ "wind_comfort": {
+ "$ref": "#/$defs/WindComfortAssessment"
+ },
+ "output": {
+ "$ref": "#/$defs/OutputParameters"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-urban-energy.json b/schema-urban-energy.json
new file mode 100644
index 0000000..191b1f3
--- /dev/null
+++ b/schema-urban-energy.json
@@ -0,0 +1,234 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/urban-energy",
+ "title": "Urban-Scale Energy Schema",
+ "description": "Urban scale energy parameters: aggregate energy demand, renewable energy potential, and city-level energy systems.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "UrbanEnergyDemand": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "UrbanEnergyDemand"
+ },
+ "land_use_ref": {
+ "type": "string",
+ "description": "Reference to LandUse identifier"
+ },
+ "annual_heating_demand": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year"
+ },
+ "annual_cooling_demand": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year"
+ },
+ "annual_lighting_demand": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year"
+ },
+ "annual_equipment_demand": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year"
+ },
+ "peak_heating_demand": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kW"
+ },
+ "peak_cooling_demand": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kW"
+ },
+ "demand_density": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per square meter per year"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "RenewablePotential": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "RenewablePotential"
+ },
+ "land_use_ref": {
+ "type": "string"
+ },
+ "solar_roof_potential": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year from rooftop PV"
+ },
+ "solar_facade_potential": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year from facade BIPV"
+ },
+ "solar_ground_potential": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year from ground-mounted PV"
+ },
+ "geothermal_potential": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year from ground source"
+ },
+ "wind_potential": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year from small wind turbines"
+ },
+ "available_roof_area": {
+ "type": "number",
+ "minimum": 0,
+ "description": "square meters suitable for PV"
+ },
+ "suitable_facade_area": {
+ "type": "number",
+ "minimum": 0,
+ "description": "square meters suitable for BIPV"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "UrbanEnergyBalance": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "UrbanEnergyBalance"
+ },
+ "annual_total_demand": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year"
+ },
+ "annual_total_renewable_generation": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per year"
+ },
+ "renewable_self_sufficiency_ratio": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "annual_co2_emissions": {
+ "type": "number",
+ "description": "tonnes CO2 per year"
+ },
+ "carbon_intensity": {
+ "type": "number",
+ "description": "kg CO2 per kWh"
+ },
+ "energy_use_intensity": {
+ "type": "number",
+ "minimum": 0,
+ "description": "kWh per square meter per year"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "UrbanEnergyProperties": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "UrbanEnergyProperties"
+ },
+ "demands": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/UrbanEnergyDemand"
+ }
+ },
+ "renewable_potentials": {
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/RenewablePotential"
+ }
+ },
+ "energy_balance": {
+ "$ref": "#/$defs/UrbanEnergyBalance"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/schema-urban.json b/schema-urban.json
new file mode 100644
index 0000000..4fda4aa
--- /dev/null
+++ b/schema-urban.json
@@ -0,0 +1,148 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "bps/urban",
+ "title": "Urban-Scale Geometry Schema",
+ "description": "Urban scale geometry: climate zones and land use boundaries. Energy, CFD, and other simulation parameters are in separate schema-urban-*.json files.",
+ "$defs": {
+ "_IdentifiedObject": {
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "type": "string",
+ "pattern": "^[.A-Za-z0-9_-]+$",
+ "minLength": 1,
+ "maxLength": 100
+ },
+ "display_name": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "user_data": {
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "identifier"
+ ]
+ },
+ "ClimateZone": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "ClimateZone"
+ },
+ "boundary": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "minItems": 3
+ },
+ "climate_zone_code": {
+ "type": "string",
+ "description": "e.g. ASHRAE (1A-8B), Chinese (\u4e25\u5bd2/\u5bd2\u51b7/\u590f\u70ed\u51ac\u51b7/\u590f\u70ed\u51ac\u6696/\u6e29\u548c)"
+ },
+ "heating_degree_days": {
+ "type": "number"
+ },
+ "cooling_degree_days": {
+ "type": "number"
+ },
+ "design_heating_temperature": {
+ "type": "number"
+ },
+ "design_cooling_temperature": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "LandUse": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/$defs/_IdentifiedObject"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "LandUse"
+ },
+ "boundary": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "minItems": 3
+ },
+ "land_use_type": {
+ "type": "string",
+ "enum": [
+ "residential",
+ "commercial",
+ "industrial",
+ "institutional",
+ "agricultural",
+ "park",
+ "water",
+ "transportation",
+ "mixed"
+ ]
+ },
+ "floor_area_ratio": {
+ "type": "number",
+ "minimum": 0
+ },
+ "building_coverage_ratio": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "green_ratio": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "population_density": {
+ "type": "number",
+ "minimum": 0,
+ "description": "people per hectare"
+ }
+ },
+ "required": [
+ "type",
+ "land_use_type"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file