Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions docs/calculation_differences.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Nextの製品版は[`jjjexperiment/release.py`](../packages/pyhees-jjj/src/jjjex
| BRI-01 | 冷房時の居室・非居室間の間仕切熱移動の符号 | `+Q_trs` | `+Q_trs` | 既定OFFは`+Q_trs`、①をONにすると全経路で`-Q_trs` |
| BRI-02 | 全般換気なし時も区画別全般換気量を給気下限に使用 | 使用する | 使用する。最低風量直接入力時は過大値が拡大 | 既定OFFは建研式、②をONにすると換気下限と設備最低風量を分離 |
| VP-01 | RAC活用型の冷房SHFに用いる負荷 | 該当モデルなし(ダクト式は負荷バランス後) | 負荷バランス前のRAC負荷 | 負荷バランス後の全館空調負荷 |
| VP-02 | RAC活用型暖房のデフロスト補正の責務 | 該当モデルなし | ダクト式とRACの係数が重複 | RACの$C_{af}$と$C_{df}$だけをRAC消費電力モデルで適用 |

BRI-01とBRI-02の既定値はOFFである。建研本家との比較照合ではOFF、物理的に正しいと
判断した方法を使う計算ではONにする。①と②は独立して選択できる。
Expand Down Expand Up @@ -234,6 +235,7 @@ Nextでは、次の二つを別の物理量として扱う。
| VAVあり・全般換気なし | サーモOFF・小負荷時の設備下限が不明確 | ②ONでは暖冷房期に設備最低風量を明示的に保証 |
| 全般換気なしの中間期 | 給気またはファン電力が残る経路がある | 給気・ファン電力とも0 |
| RAC活用型の冷房SHF | 負荷バランス前の`L_CS`、`L_CL`から算定 | 負荷バランス後の`L_star_CS`、`L_star_CL`から算定 |
| RAC活用型暖房のデフロスト | ダクト式$C_{df}$で補正済みの能力へRAC式$C_{df}$を重ねて適用 | ダクト式補正をRAC入力境界で戻し、RAC式$C_{af}$・$C_{df}$のみ適用 |

### 6.1 VP-01:RAC活用型の冷房SHF

Expand Down Expand Up @@ -273,6 +275,105 @@ $Q_{\max,CS}$と$Q_{\max,CL}$だけに上記SHFと補正潜熱負荷を使う。
この差は冷房の顕潜熱配分だけに生じる。暖房にはSHFによる顕熱・潜熱分割がなく、
RACの最大暖房能力をそのまま熱源上限へ使うため、同種の問題はない。

### 6.2 VP-02:RAC活用型暖房のデフロスト補正

RAC活用型は、空気側の負荷・風量・温度をダクト式の計算で求め、
消費電力だけをRACモデルで評価する。ダクト式の平均暖房能力計算は、
空気側で実際に搬送された熱量$q_{air}$をダクト式のデフロスト係数で除している。

```math
q_{hs,duct}=\frac{q_{air}}{C_{df,duct}}
```

修正前は、この$q_{hs,duct}$をRACの暖房負荷として渡した後、RACモデル内で
RAC専用の風量補正$C_{af,rac}$とデフロスト補正$C_{df,rac}$を適用していた。
そのため、両方が0.77となる時刻では、機器種別の異なる補正が同じRAC評価へ重なっていた。

修正後はRAC消費電力の入力境界で次のようにダクト式補正を戻す。

```math
L_{H,rac}=q_{hs,duct}C_{df,duct}=q_{air}
```

その後、RACモデルが$C_{af,rac}$と$C_{df,rac}$を1回だけ適用する。
これにより、RAC活用型の暖房消費電力はダクト式の以下の3入力から独立する。

- `C_df_H_d_t_defrost_ductcentral`
- `defrost_temp_ductcentral`
- `defrost_humid_ductcentral`

一方、RAC側の同等の3入力は引き続きRAC活用型の暖房消費電力に影響する。
RAC活用型の空気搬送計算で使う`Q_hs_max_H_d_t`は、RACの最大能力式で
$C_{af,rac}$と$C_{df,rac}$を適用した上限である。今回修正するのは、その上限内で
実際に空気が搬送した熱量をRAC消費電力モデルへ渡す境界であり、上限式自体は変更しない。

検証者から受領した地域2・等級5・RAC活用型条件の年間値は次のとおりである。

| 状態 | 暖房一次エネルギー [MJ/年] | 冷房一次エネルギー [MJ/年] |
| --- | ---: | ---: |
| ver.1.3.0修正前 | 84,222.243989 | 2,010.059118 |
| VP-02修正後 | 70,154.484309 | 2,010.059118 |
| 受領Excelのキャッシュ値 | 74,958.287610 | 2,010.059118と報告 |

VP-02修正により14,067.759679 MJ/年(約16.7%)低下する。ただし、Excel報告値とは
4,803.803301 MJ/年の残差がある。このため、本修正は「デフロスト補正の責務重複を解消」
するものであり、現状Excelのキャッシュ値への一致を意味しない。

#### 6.2.1 受領Excelの追跡結果

比較対象は次のファイルである。

- ファイル名:`第4章第2節ダクト式全館空調_VAV確認済_260816_RAC冷暖房統合.xlsm`
- SHA-256:`0769AF8132D3463A70C3A2B3724183326EA328EE03C4AD4F7B2AFF4D2C65C565`
- 受領日:2026-08-20

受領Excelの年間暖房値74,958.287610 MJ/年は、次の内訳から再現できる。

| 項目 | Excelセル・範囲 | 値 |
| --- | --- | ---: |
| RAC圧縮機電力量 | `インプット!S19 = SUM(計算過程_HT!F8:F8767)` | 6,808.075834 kWh/年 |
| 送風機電力量 | `インプット!S20 = SUM(計算過程_HT!AF8:AF8767)` | 303.312287 kWh/年 |
| 電力の一次エネルギー | `インプット!S22 = (S19+S20)×9.76` | 69,407.148055 MJ/年 |
| 未処理暖房負荷 | `インプット!U19 = 負荷計算!GX1` | 3,802.150380 MJ/年 |
| 未処理負荷の一次エネルギー | `インプット!U22 = U19×1.46` | 5,551.139555 MJ/年 |
| 合計 | `インプット!V22 = S22+U22` | 74,958.287610 MJ/年 |

8760時間系列を照合すると、外気温、ダクト側$C_{df}$、全般換気量および送風機電力は
Nextと一致した。送風機電力量303.312286815 kWh/年は全時刻で一致している。
一方、受領Excelには次の二つの内部不整合がある。

1. **RACシートだけ別の相対湿度系列を使用している。**
`計算過程_HT!Y8:Y8767`は`AL8:AL8767`を参照するが、`AL`列は値貼付けで数式がない。
これに対し、空気搬送計算は`負荷計算!AZ5:AZ8764`で同じ外気データから相対湿度を
計算している。両列は8760時間すべて異なり、最初の時刻は72.521355%と90.375285%である。
外気温は両経路とも-6.9℃で一致するため、この差でRACデフロスト判定が変わる。
2. **RAC消費電力へダクト式補正後の能力を渡している。**
`計算過程_HT!AM8:AM8767`は`付録A!E5:E8764×3.6/1000`である。
`付録A!E`は空気搬送熱量を`負荷計算!DQ`(ダクト式$C_{df}$)で除した
$q_{hs,duct}$であり、さらに`計算過程_HT!S`で$C_{af,rac}C_{df,rac}$により除される。
したがって、機器種別の異なる補正がRAC消費電力評価へ重なる。

なお、`負荷計算!HC`の「最大暖房出力にデフロストをもう一度乗じた係数」は
`HC1 = SUM(HC5:HC8764)`以外から参照されない検算列であり、年間値74,958.287610 MJ/年の
直接の計算経路には入っていない。

Excelの式を、Excel側の負荷・相対湿度系列を使ってPythonで再構成したところ、
`計算過程_HT!F8:F8767`の全8760値と浮動小数点精度で一致した。従って残差は
RAC式の実装差ではなく、Excelが使う入力系列と補正境界の差で説明できる。

ExcelをVP-02と同じ責務へ直す場合は、少なくとも次を同時に行って再計算する必要がある。

1. RAC側相対湿度を`負荷計算!AZ`と同じ気象データ・式から求める。
2. RAC消費電力へ渡す負荷を$q_{hs,duct}$ではなく、
$q_{air}=q_{hs,duct}C_{df,duct}$とする。
3. RAC最大能力と空気搬送計算も、同じ外気温・相対湿度系列から求める。

この3点を別々に変更すると、能力上限、処理負荷、未処理負荷の責務が再びずれるため、
Excel側も一括して再計算・照合する。

Phase 5のRAC代表ケースでは、年間暖房値と、デフロスト影響時刻224時間の
`E_H_d_t`・`E_E_H_d_t`だけが変化した。ダクト式代表ケース、冷房系列、入力条件は不変である。

床下計算全体に関する旧版・Excel床下13・Excel床下14との差は、
[`underfloor_ac_seven_changes.md`](underfloor_ac_seven_changes.md)および
[`underfloor_ac_excel_alignment.md`](underfloor_ac_excel_alignment.md)に記録している。
Expand All @@ -287,6 +388,8 @@ RACの最大暖房能力をそのまま熱源上限へ使うため、同種の
| 全般換気なし・最低風量160/420 m3/h | [`test_section4_2_preparation.py`](../tests/test_section4_2_preparation.py#L923-L1001) |
| VAVあり・全般換気なし | [`test_section4_2_preparation.py`](../tests/test_section4_2_preparation.py#L1004-L1031) |
| RAC活用型冷房の負荷バランス後SHF | [`test_section4_2_preparation.py`](../tests/test_section4_2_preparation.py) |
| RAC活用型とダクト式デフロスト係数の分離 | [`test_not_broken_type2.py`](../packages/pyhees-jjj/src/tests/test_not_broken_type2.py) |
| 地域2・等級5・RAC活用型の年間回帰 | [`test_type2_defrost_responsibility.py`](../packages/pyhees-jjj/src/tests/test_type2_defrost_responsibility.py) |

ver.1.0.2リリース時には、全体pytest、Phase 5、Excel床下14 Golden、
計算エンジン内部試験、RuffおよびGitHub Actionsの成功を確認している。
Expand Down
3 changes: 2 additions & 1 deletion packages/pyhees-jjj/docs/計算フロー_タイプ1・2.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ style Add fill:#e1ffe1
| **送風機電力計算** | **風量比例(換気補正あり)、P_fan_rtd = カタログ値** | **同左、ただし P_fan_rtd = V_hs_dsgn × f_SFP で算出** |
| **圧縮機電力計算** | **理論効率 × 効率比** | **基準入出力関数(表ベース)** |
| 容量制御 | 定格・中間・最小の3点 | 連続可変(dualcompressor時) |
| デフロスト補正 | 条件時のみ適用(外気温 < 5℃ かつ 相対湿度 > 80%)、デフォルト値 0.77(変更可) | 同左 |
| デフロスト補正 | ダクトセントラル専用の$C_{df,duct}$を適用 | RAC専用の$C_{df,rac}$を適用。ダクト式係数はRAC消費電力に重ねない |
| 風量補正 | C_af (専用室・風向固定) | C_af (専用室・風向固定) |
| 特性曲線 | ヒートポンプサイクル理論 | JIS試験データベース |

Expand All @@ -504,3 +504,4 @@ style Add fill:#e1ffe1
- 2026-01-30: 初版作成(暖房・冷房統合版)
- 2026-02-07: Type 2 (ルームエアコン) の処理フローを追加
- 2026-03-02: ドキュメントの説明文を修正
- 2026-08-19: タイプ2のRAC暖房にダクト式デフロスト補正を重ねない責務境界を追記
27 changes: 25 additions & 2 deletions packages/pyhees-jjj/src/jjjexperiment/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,14 +577,36 @@ def _get_heating_electricity_type1_and_type3(heat_ac_setting, E_E_fan_H_d_t, q_h
)
)

def _get_heating_electricity_type2(heat_ac_setting, house, climateFile, E_E_fan_H_d_t, q_hs_H_d_t, heat_CRAC, cool_CRAC):
def _get_type2_rac_heating_load(q_hs_H_d_t, climate):
"""Return delivered heat before the duct-central defrost correction.

``dc_a.get_q_hs_H_d_t`` returns the heat-source average capacity after
dividing the air-side heat by the duct-central defrost coefficient. The
type-2 RAC model accepts an uncorrected heating load and applies its own
RAC-specific ``C_af`` and ``C_df``. Undo the duct-central correction at
this boundary so the two equipment-specific coefficients do not overlap.
"""
return q_hs_H_d_t * climate.get_C_df_H_d_t()


def _get_heating_electricity_type2(
heat_ac_setting,
house,
climateFile,
climate,
E_E_fan_H_d_t,
q_hs_H_d_t,
heat_CRAC,
cool_CRAC,
):
rac_heating_load_d_t = _get_type2_rac_heating_load(q_hs_H_d_t, climate)
return jjj_dc_a.calc_E_E_H_d_t_type2(
*_HeatingType2ElectricityInputs(
heat_ac_setting.type,
house.region,
climateFile,
E_E_fan_H_d_t,
q_hs_H_d_t,
rac_heating_load_d_t,
heat_CRAC.e_rtd,
heat_CRAC.q_rtd,
cool_CRAC.q_rtd,
Expand Down Expand Up @@ -650,6 +672,7 @@ def _select_heating_electricity(
heat_ac_setting,
house,
climateFile,
climate,
E_E_fan_H_d_t,
q_hs_H_d_t,
heat_CRAC,
Expand Down
119 changes: 119 additions & 0 deletions packages/pyhees-jjj/src/test_utils/input_region2_grade5_type2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{
"case_name": "region2_grade5_type2_regression",
"climateFile": "-",
"loadFile": "-",
"Theta_hs_out_max_H_d_t_limit": 45,
"Theta_hs_out_min_C_d_t_limit": 15,
"C_df_H_d_t_defrost_ductcentral": 0.77,
"defrost_temp_ductcentral": 5,
"defrost_humid_ductcentral": 80,
"phi_i": 0.49,
"C_V_fan_dsgn_H": 0.79,
"C_V_fan_dsgn_C": 0.79,
"C_df_H_d_t_defrost_rac": 0.77,
"defrost_temp_rac": 5,
"defrost_humid_rac": 80,
"C_hm_C": 1.15,
"q_rtd_C_limit": 5600,
"change_supply_volume_before_vav_adjust": "1",
"change_heat_source_outlet_required_temperature": "1",
"change_V_supply_d_t_i_max": 1,
"A_A": 120.08,
"A_MR": 29.81,
"A_OR": 51.34,
"region": 2,
"A_env": 307.51,
"U_A": 0.4,
"eta_A_C": 1.9,
"eta_A_H": 2.3,
"underfloor_ventilation": "1",
"r_A_ufvnt": 100,
"underfloor_insulation": "1",
"hs_CAV": "1",
"underfloor_air_conditioning_air_supply": "1",
"change_underfloor_temperature": "1",
"R_g": 0.15,
"input_ufac_consts": 1,
"Theta_g_avg": 15.7,
"U_s_vert": 2.223,
"phi": 0.846,
"carry_over_heat": 1,
"C1_BR_R_i": [893676, 500835, 400667, 325488, 325598],
"C1_NR_R": 1195534,
"H_A": {
"type": 2,
"duct_insulation": 1,
"VAV": 1,
"general_ventilation": 1,
"input_V_hs_dsgn": 1,
"V_hs_dsgn": 1500,
"subtract_ventilation_power": 1,
"input_V_hs_min": 1,
"V_hs_min": 1200,
"input_E_E_fan_min": 1,
"E_E_fan_logic": 1,
"E_E_fan_min": 100,
"input": 1,
"input_f_SFP": 1,
"input_C_af_H2": 1,
"dedicated_chamber2": 1,
"fixed_fin_direction2": 1,
"input_C_af_H3": 1,
"dedicated_chamber3": 1,
"fixed_fin_direction3": 1,
"input_C_af_H4": 1,
"dedicated_chamber4": 1,
"fixed_fin_direction4": 1,
"C_af_H2": 0,
"input_rac_performance": 1,
"q_rac_rtd_H": 2.2,
"q_rac_max_H": 3.3,
"e_rac_rtd_H": 0,
"dualcompressor": 1,
"f_SFP": 0.144,
"input_mode": 1,
"mode": 3,
"correct_cooling_partition_heat_transfer": 1,
"correct_no_general_ventilation_airflow": 1
},
"C_A": {
"type": 2,
"duct_insulation": 1,
"VAV": 1,
"general_ventilation": 1,
"input_V_hs_dsgn": 1,
"V_hs_dsgn": 1500,
"subtract_ventilation_power": 1,
"input_V_hs_min": 1,
"V_hs_min": 1200,
"input_E_E_fan_min": 1,
"E_E_fan_logic": 1,
"E_E_fan_min": 100,
"input": 1,
"input_mode": 1,
"input_f_SFP": 1,
"input_C_af_C2": 1,
"dedicated_chamber2": 1,
"fixed_fin_direction2": 1,
"input_C_af_C3": 1,
"dedicated_chamber3": 1,
"fixed_fin_direction3": 1,
"input_C_af_C4": 1,
"dedicated_chamber4": 1,
"fixed_fin_direction4": 1,
"C_af_C2": 0,
"mode": 3,
"input_rac_performance": 1,
"q_rac_rtd_C": 0,
"q_rac_max_C": 0,
"e_rac_rtd_C": 0,
"dualcompressor": 1,
"f_SFP": 0.144,
"correct_cooling_partition_heat_transfer": 1,
"correct_no_general_ventilation_airflow": 1
},
"HEX": {
"install": 1,
"etr_t": 0.4
}
}
2 changes: 1 addition & 1 deletion packages/pyhees-jjj/src/test_utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def expected_result_type1():
@pytest.fixture
def expected_result_type2():
""" 負荷バランス後の冷房負荷でSHFを算定した場合の期待結果 """
return ResultSummary(E_C=13857.745579445591, E_H=40692.8527046848)
return ResultSummary(E_C=13857.745579445591, E_H=39433.352028185276)

def deep_update(d, u):
for k, v in u.items():
Expand Down
18 changes: 13 additions & 5 deletions packages/pyhees-jjj/src/tests/test_main_refactoring_boundaries.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,21 +391,29 @@ def test_get_heating_electricity_type2_preserves_argument_order(monkeypatch):
)
setting = SimpleNamespace(type='type')
house = SimpleNamespace(region=6)
climate = SimpleNamespace(
get_C_df_H_d_t=lambda: np.array([1.0, 0.77]),
)
q_hs = np.array([1000.0, 2000.0])
heat = SimpleNamespace(
e_rtd='e-rtd-h', q_rtd='q-rtd-h', q_max='q-max-h',
input_C_af='c-af-h', dualcompressor='dual-h',
)
cool = SimpleNamespace(q_rtd='q-rtd-c', q_max='q-max-c')

result = experiment_main._get_heating_electricity_type2(
setting, house, 'climate.csv', 'fan', 'q-h', heat, cool
setting, house, 'climate.csv', climate, 'fan', q_hs, heat, cool
)

assert result == 'electricity'
assert calls == [(
'type', 6, 'climate.csv', 'fan', 'q-h', 'e-rtd-h', 'q-rtd-h',
'q-rtd-c', 'q-max-h', 'q-max-c', 'c-af-h', 'dual-h',
)]
assert len(calls) == 1
args = calls[0]
assert args[:4] == ('type', 6, 'climate.csv', 'fan')
np.testing.assert_array_equal(args[4], np.array([1000.0, 1540.0]))
assert args[5:] == (
'e-rtd-h', 'q-rtd-h', 'q-rtd-c', 'q-max-h', 'q-max-c', 'c-af-h',
'dual-h',
)
def test_get_heating_electricity_type4_preserves_argument_order(monkeypatch):
calls = []
monkeypatch.setattr(
Expand Down
Loading