github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/blrmaceqcf.go (about) 1 //This file is part of EESLISM. 2 // 3 //Foobar is free software : you can redistribute itand /or modify 4 //it under the terms of the GNU General Public License as published by 5 //the Free Software Foundation, either version 3 of the License, or 6 //(at your option) any later version. 7 // 8 //Foobar is distributed in the hope that it will be useful, 9 //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 11 //GNU General Public License for more details. 12 // 13 //You should have received a copy of the GNU General Public License 14 //along with Foobar.If not, see < https://www.gnu.org/licenses/>. 15 16 package eeslism 17 18 import "fmt" 19 20 /* -------------------------------------- */ 21 22 var __Rmhtrcf_count int 23 24 func Rmhtrcf(exs *EXSFS, emrk []rune, rooms []*ROOM, sds []*RMSRF, wd *WDAT) { 25 if rooms != nil { 26 for i := range rooms { 27 room := rooms[i] 28 n := room.N 29 brs := room.Brs 30 sds := sds[brs : brs+n] 31 32 if DEBUG { 33 fmt.Printf("Room Name=%s\n", room.Name) 34 } 35 36 // 放射熱交換係数の計算 37 if __Rmhtrcf_count == 0 || emrk[0] == '*' { 38 radex(n, sds, room.F, room.Wradx) 39 } 40 if DEBUG { 41 fmt.Printf("radex end\n") 42 } 43 44 // 放射熱伝達率の入れ替え 45 Radcf0(room.Tsav, &room.alrbold, n, sds, room.Wradx, room.alr) 46 if DEBUG { 47 fmt.Printf("Radcf0 end\n") 48 } 49 50 Htrcf(room.alc, exs.Alosch, exs.Alotype, exs.Exs, room.Tr, n, room.alr, sds, &room.mrk, wd) 51 if DEBUG { 52 fmt.Printf("Htrcf end\n") 53 } 54 } 55 56 __Rmhtrcf_count++ 57 } 58 59 if sds != nil { 60 for _, sd := range sds { 61 if sd.mwtype == RMSRFMwType_C && sd.mwside == RMSRFMwSideType_i { 62 // 内壁の場合は裏面室の熱伝達率を入れ替える 63 nxsd := sd.nxsd 64 sd.alo = nxsd.ali 65 nxsd.alo = sd.ali 66 } 67 } 68 } 69 } 70 71 /* ----------------------------------------------------------------- */ 72 73 func Rmrdshfc(_Room []*ROOM, Sd []*RMSRF) { 74 if len(_Room) == 0 { 75 return 76 } 77 78 for i := range _Room { 79 Room := _Room[i] 80 brs := Room.Brs 81 sd := Sd[brs:] 82 83 Radshfc(Room.N, Room.FArea, Room.Area, sd, Room.tfsol, Room.eqcv, Room.Name, Room.fsolm) 84 } 85 } 86 87 /* ----------------------------------------------------------------- */ 88 func Rmhtrsmcf(_Sd []*RMSRF) { 89 for n := range _Sd { 90 Sd := _Sd[n] 91 Sd.K = 1.0 / (Sd.Rwall + 1.0/Sd.ali + 1.0/Sd.alo) 92 } 93 } 94 95 /* ----------------------------------------------------------------- */ 96 // 透過日射、相当外気温度の計算 97 func Rmexct(Room []*ROOM, Sd []*RMSRF, Wd *WDAT, Exs []*EXSF, Snbk []*SNBK, Qrm []*QRM, nday, mt int) { 98 if len(Room) == 0 { 99 return 100 } 101 102 // 部位ごとの日射吸収比率のスケジュール対応(比率入力部位の日射入射比率初期化) 103 for _, rm := range Room { 104 105 // 室内部位の日射吸収比率の計算 106 // 2017/12/25毎時計算へ変更 107 // 家具の日射吸収割合 108 if rm.fsolm != nil { 109 rm.tfsol = *(rm.fsolm) 110 } else { 111 rm.tfsol = 0.0 112 } 113 114 for _, rsd := range rm.rsrf[:rm.N] { 115 // 床の場合 116 if rsd.ble == BLE_Floor || rsd.ble == BLE_InnerFloor { 117 // どの部位も日射吸収比率が定義されていない場合 118 if rm.Nfsolfix == 0 { 119 // 床の日射吸収比率は固定 120 rsd.ffix_flg = '*' 121 rsd.fsol = CreateConstantValuePointer(*rm.flrsr * rsd.A / rm.FArea) 122 } 123 } 124 125 // fsolが規定されている部位についてfsolを合計する 126 if rsd.ffix_flg == '*' { 127 rm.tfsol += *rsd.fsol // fsolの合計値計算 128 } 129 } 130 } 131 132 // 室内部位の日射吸収比率の計算(毎計算ステップへ変更)2017/12/25 133 Rmrdshfc(Room, Sd) 134 for i, rm := range Room { 135 Q := Qrm[i] 136 137 rm.Qgt = 0.0 138 rm.Qsolm = 0.0 139 rm.Qsab = 0.0 140 rm.Qrnab = 0.0 141 Q.Solo = 0.0 142 Q.Solw = 0.0 143 Q.Asl = 0.0 144 145 RmSd := Sd[rm.Brs : rm.Brs+rm.N] 146 147 for n, Sdn := range RmSd { 148 149 if Sdn.ble == BLE_InnerWall || Sdn.ble == BLE_InnerFloor || Sdn.ble == BLE_Ceil { 150 continue 151 } 152 153 e := Exs[Sdn.exs] 154 155 Sdn.RSsol = 0.0 156 Sdn.RSsold = 0. 157 Fsdw := 0.0 158 Qgtn := 0.0 159 Qga := 0.0 160 161 var Idre float64 // 直逹日射 [W/m2] 162 var Idf float64 // 拡散日射 [W/m2] 163 var RN float64 // 夜間輻射 [W/m2] 164 if Sdn.Sname == "" { /*---higuchi 070918---start-*/ 165 Sdn.Fsdworg = 0.0 166 167 sb := Sdn.sb 168 if sb >= 0 && e.Cinc > 0.0 { 169 S := Snbk[sb] 170 171 // 日よけの影面積率 [-] 172 Fsdw = FNFsdw(S.Type, S.Ksi, e.Tazm, e.Tprof, S.D, S.W, S.H, S.W1, S.H1, S.W2, S.H2) 173 Sdn.Fsdworg = Fsdw 174 175 if DEBUG { 176 fmt.Printf(" xxx Rmexct xxx i=%d n=%d sb=%d type=%d tazm=%f tprof=%f Fsdw=%f\n", 177 i, n, sb, S.Type, e.Tazm, e.Tprof, Fsdw) 178 } 179 } else { 180 Fsdw = 0.0 181 } 182 183 Idre = e.Idre 184 Idf = e.Idf 185 RN = e.Rn 186 187 if DEBUG { 188 fmt.Printf("1:Fsdw=%f,Idre=%f,Idf=%f,rn=%f Sb=%d Cinc=%f\n", Fsdw, Idre, Idf, RN, sb, e.Cinc) 189 } 190 191 } else { /*---higuchi 070918 end--*/ /*--higuchi 070918 start--*/ 192 Fsdw = Sdn.Fsdw 193 // Idre = Sdn.Idre ; 090131 higuchi Sdn.Idre が影をすでに考慮していたため、下に変更 194 Idre = e.Idre /*--090131 higuchi --*/ 195 Idf = Sdn.Idf 196 RN = Sdn.rn 197 } /*---higuchi 070918 end --*/ 198 199 switch Sdn.ble { 200 case BLE_Window: 201 // 通常窓の場合 202 /*--higuchi add--*/ 203 Qgtn, Qga = Glasstga(Sdn.A, Sdn.tgtn, Sdn.Bn, 204 e.Cinc, Fsdw, Idre, Idf, Sdn.window.Cidtype, e.Prof, e.Gamma) 205 Rab := Sdn.Eo * RN / Sdn.alo // 夜間放射熱取得 [W] 206 207 Sab := Qga / Sdn.A // [W/m2] 208 Sdn.TeEsol = Sab 209 Sdn.TeErn = -Rab 210 Sdn.TeEsol = Sab / Sdn.K 211 Sdn.Te = Sab/Sdn.K - Rab + Wd.T // 外表面の相当外気温 212 Sdn.Qgt = Qgtn // 開口部の透過日射熱取得 [W] 213 Sdn.Qga = Qga // 開口部の吸収日射熱取得 [W] 214 Sdn.Qrn = -Rab // 開口部の夜間放射熱取得 [W/m2] 215 216 // 部屋rm の日射 217 rm.Qgt += Qgtn // 部屋rmの透過日射熱取得 [W] 218 rm.Qsab += Sab * Sdn.A // 部屋rmの吸収日射熱取得 [W] 219 rm.Qrnab += Rab * Sdn.A * Sdn.K // 部屋rmの夜間放射による熱損失 [W] 220 221 Q.Solw += Sdn.A * (Idre + Idf) /*--higuchi add --*/ 222 break 223 224 case BLE_ExternalWall, BLE_Floor, BLE_Roof: // このあたりを参考に修正(相当外気温度の計算) 225 if Sdn.typ != RMSRFType_E && Sdn.typ != RMSRFType_e { 226 /*---higuchi add---*/ 227 Sab := Sdn.as * (Idre*(1.0-Fsdw) + Idf) / Sdn.alo 228 Rab := Sdn.Eo * RN / Sdn.alo // 長波長 229 /*------------------*/ 230 231 Sdn.TeEsol = Sab 232 Sdn.TeErn = -Rab 233 234 // 建材一体型空気集熱器のための相当外気温度修正 235 if Sdn.rpnl != nil && Sdn.rpnl.Type == 'C' { 236 //wall := Sdn.mw.wall 237 Sdn.Te = Sdn.Tcole 238 Sdn.Iwall = Idre*(1.0-Fsdw) + Idf 239 } else { 240 Sdn.Te = Sab - Rab + Wd.T 241 } 242 243 rm.Qsab += Sab * Sdn.A * Sdn.K 244 Sdn.Qga = Sab * Sdn.A * Sdn.K 245 rm.Qrnab += Rab * Sdn.A * Sdn.K 246 Q.Solo += Sdn.A * (Idre + Idf) 247 Q.Asl += Sdn.as * Sdn.A * (Idre + Idf) 248 } else { 249 Sdn.Te = e.Tearth 250 Sdn.TeEsol = 0.0 251 Sdn.TeErn = 0.0 252 } 253 break 254 255 case BLE_InnerWall, BLE_InnerFloor, BLE_Ceil, BLE_d: 256 if Sdn.nxrm < 0 { 257 // 隣室が無い場合 258 Tr := Sdn.room.Trold 259 Eo := Sdn.room.cmp.Elouts[0] 260 if Eo.Control == LOAD_SW { 261 Tr = Sdn.room.rmld.Tset 262 } 263 264 // 相当外気温を設定 265 Sdn.Te = Sdn.c*Tr + (1.0-Sdn.c)*Wd.T 266 } else { 267 // 隣室がある場合 268 Tr := Sdn.nextroom.Trold 269 Eo := Sdn.nextroom.cmp.Elouts[0] 270 if Eo.Control == LOAD_SW { 271 Tr = Sdn.nextroom.rmld.Tset 272 } 273 274 // 相当外気温を設定 275 Sdn.Te = Sdn.c*Tr + (1.0-Sdn.c)*Wd.T 276 } 277 Sdn.TeEsol = 0.0 278 Sdn.TeErn = 0.0 279 break 280 } 281 } // 表面ループ 282 283 // 室内部位への入射日射の計算(吸収日射ではない) 284 for _, Sdn := range RmSd { 285 // 室内部位への入射日射量の計算 286 Sdn.RSsold = rm.Qgt * Sdn.srg 287 } 288 } // 室ループ終了 289 290 // 透過日射の室内部位の最終計算(隣接室への日射分配、透過日射のうちガラスから屋外に放熱される分も考慮) 291 for _, rm := range Room { 292 // 透過間仕切りなど、隣接空間への透過日射分配の計算 293 for _, Sdn := range Sd[rm.Brs : rm.Brs+rm.N] { 294 295 // 隣室への日射の分配率が指定されており、分配する入射がある 296 if Sdn.tnxt > 0. && Sdn.RSsold > 0. { 297 // 分配する入射量 RSsol 298 Rmnxt := Room[Sdn.nxrm] 299 RSsol := Sdn.RSsold * Sdn.tnxt 300 301 // 入射日射×透過率が当該室の透過日射熱取得より減ずる 302 rm.Qgt -= RSsol 303 if Sdn.nextroom != nil { 304 // 外皮でない場合は隣室の透過日射熱取得に透過分を加算 305 Rmnxt.Qgt += RSsol 306 } 307 } 308 309 // 透過日射が入射したときに屋外に放熱されるときには、表面吸収日射はゼロとする 310 if Sdn.RStrans { 311 rm.Qgt -= Sdn.RSsold 312 Sdn.RSsol = 0.0 313 } 314 } 315 } 316 317 for i, rm := range Room { 318 Q := Qrm[i] 319 RmSd := Sd[rm.Brs : rm.Brs+rm.N] 320 321 // 室内部位の短波長吸収量の計算 322 for n, Sdn := range RmSd { 323 Sdn.RSsol = rm.Qgt * Sdn.srg2 / Sdn.A 324 325 Sdn.RS = (Sdn.RSsol*Sdn.A + rm.Hr*Sdn.srh + rm.Lr*Sdn.srl + rm.Ar*Sdn.sra + rm.Qeqp*Sdn.eqrd) / Sdn.A 326 Sdn.RSin = (rm.Hr*Sdn.srh + rm.Lr*Sdn.srl + rm.Ar*Sdn.sra + rm.Qeqp*Sdn.eqrd) / Sdn.A 327 Sdn.RSli = rm.Lr * Sdn.srl / Sdn.A 328 329 if DEBUG { 330 fmt.Printf("----- Rmexct i=%d n=%d rm.Qgt=%f Fsdw=%f Fsdworg=%f Qgt=%f Qga=%f srg2=%f RSsol=%f RS=%f RSin=%f RSli=%f\n", 331 i, n, rm.Qgt, Sdn.Fsdw, Sdn.Fsdworg, Sdn.Qgt, Sdn.Qga, Sdn.srg2, Sdn.RSsol, Sdn.RS, Sdn.RSin, Sdn.RSli) 332 } 333 } 334 335 // 室の透過日射熱取得を再度積算(透明間仕切りによる隣接空間からの透過日射を考慮するため) 336 if rm.rsrnx { 337 for _, Sdn := range RmSd { 338 if Sdn.ble == BLE_Ceil || Sdn.ble == BLE_InnerFloor { 339 if Sdn.nxn >= 0 { 340 Sdn.Te += Sd[Sdn.nxn].RS / Sdn.alo 341 } 342 } 343 } 344 } 345 346 Q.Tsol = rm.Qgt 347 Q.Asol = rm.Qsab 348 Q.Arn = rm.Qrnab 349 350 // 家具の日射吸収量の計算 351 rm.Qsolm = 0. 352 if rm.fsolm != nil { 353 rm.Qsolm = rm.Qgt * rm.Srgm2 354 } 355 356 } // 室ループ 357 358 for n, Sdn := range Sd { 359 // 共用壁の場合の外表面の相当外気温 Te [C] の計算 360 if Sdn.mwtype == RMSRFMwType_C { 361 Sdnx := Sdn.nxsd 362 Sdn.Te = (Sdnx.alir*Sdnx.Tmrt + Sdnx.RS) / Sdnx.ali 363 364 if DEBUG { 365 fmt.Printf("----- Rmexct n=%d Te=%f nxalir=%f nxTmrt=%f nxSdnx->RS=%f nxali=%f\n", 366 n, Sdn.Te, Sdnx.alir, Sdnx.Tmrt, Sdnx.RS, Sdnx.ali) 367 } 368 } 369 } 370 } 371 372 /* ----------------------------------------------------------------- */ 373 374 // 室の係数、定数項の計算 375 func Roomcf(mw []*MWALL, rooms []*ROOM, rdpnl []*RDPNL, wd *WDAT, exsf *EXSFS) { 376 for _, rdpnl := range rdpnl { 377 panelwp(rdpnl) 378 } 379 380 // 壁体係数行列の作成(壁体数RMSRF分だけループ) 381 RMwlc(mw, exsf, wd) 382 383 for i := range rooms { 384 room := rooms[i] 385 386 RMcf(room) 387 RMrc(room) // 室の定数項の計算 388 389 room.RMx = room.GRM / DTM 390 room.RMXC = room.RMx*room.xrold + (room.HL+room.AL)/Ro 391 392 room.RMt += Ca * room.Gvent 393 room.RMC += Ca * room.Gvent * wd.T 394 room.RMx += room.Gvent 395 room.RMXC += room.Gvent * wd.X 396 } 397 398 for _, rdpnl := range rdpnl { 399 Panelcf(rdpnl) 400 rdpnl.EPC = Panelce(rdpnl) 401 } 402 } 403 404 /* ----------------------------------------------------------------- */ 405 // 前時刻の室温の入れ替え、OT、MRTの計算 406 func Rmsurft(rooms []*ROOM, sd []*RMSRF) { 407 if rooms == nil { 408 return 409 } 410 411 // 重み係数が未定義もしくは不適切な数値の場合の対処 412 r := 0.5 413 if rooms[0].OTsetCwgt != nil && *(rooms[0].OTsetCwgt) >= 0.0 && *(rooms[0].OTsetCwgt) <= 1.0 { 414 r = *(rooms[0].OTsetCwgt) 415 } 416 417 if DEBUG { 418 fmt.Printf("<Rmsurft> Start\n") 419 } 420 421 for i := range rooms { 422 room := rooms[i] 423 n := room.N 424 brs := room.Brs 425 sdr := sd[brs:] 426 427 if DEBUG { 428 fmt.Printf("Room[%d]=%s\tN=%d\tbrs=%d\n", i, room.Name, room.N, room.Brs) 429 } 430 431 // 前時刻の温度の入れ替え 432 room.mrk = 'C' 433 room.Trold = room.Tr 434 room.xrold = room.xr 435 436 if room.FunHcap > 0 { 437 // 家具の温度の計算 438 room.TM = room.FMT*room.Tr + room.FMC 439 // 家具の吸放熱量の計算 440 if room.CM != nil { 441 room.QM = *room.CM * (room.TM - room.Tr) 442 } 443 444 room.oldTM = room.TM 445 } 446 447 if DEBUG { 448 fmt.Printf("<Rmsurft> RMsrt start\n") 449 } 450 451 // 室内表面温度の計算 452 RMsrt(room) 453 454 if DEBUG { 455 fmt.Printf("<Rmsurft> RMsrt end\n") 456 } 457 458 room.Tsav = RTsav(n, sdr) // 平均表面温度 Ts,av 459 room.Tot = r*room.Tr + (1.0-r)*room.Tsav // 作用温度 Tot 460 } 461 } 462 463 /* ----------------------------------------------------------------- */ 464 // PCM収束計算過程における部位表面温度の計算 465 func Rmsurftd(_Room []*ROOM, Sd []*RMSRF) { 466 var r float64 467 468 if _Room == nil { 469 return 470 } 471 472 Room := _Room[0] 473 474 if Room.OTsetCwgt == nil || *(Room.OTsetCwgt) < 0.0 || *(Room.OTsetCwgt) > 1.0 { 475 r = 0.5 476 } else { 477 r = *(Room.OTsetCwgt) 478 } 479 480 if DEBUG { 481 fmt.Printf("<Rmsurft> Start\n") 482 } 483 484 for i := range _Room { 485 Room := _Room[i] 486 487 if DEBUG { 488 fmt.Printf("Room[%d]=%s\tN=%d\tbrs=%d\n", i, Room.Name, Room.N, Room.Brs) 489 } 490 491 N := Room.N 492 brs := Room.Brs 493 sd := Sd[brs:] 494 495 if DEBUG { 496 fmt.Printf("<Rmsurft> RMsrt start\n") 497 } 498 499 // 室内表面温度の計算 500 RMsrt(Room) 501 502 if DEBUG { 503 fmt.Printf("<Rmsurft> RMsrt end\n") 504 } 505 506 Room.Tsav = RTsav(N, sd) 507 Room.Tot = r*Room.Tr + (1.0-r)*Room.Tsav 508 } 509 } 510 511 /*--------------------------------------------------------------------------------------------*/ 512 513 // 室の熱取得要素の計算 514 func Qrmsim(Room []*ROOM, Wd *WDAT, Qrm []*QRM) { 515 for i := range Room { 516 Q := Qrm[i] 517 rm := Room[i] 518 519 // 人体・照明・機器の顕熱 [W] 520 Q.Hums = rm.Hc + rm.Hr 521 Q.Light = rm.Lc + rm.Lr 522 Q.Apls = rm.Ac + rm.Ar 523 Q.Hgins = Q.Hums + Q.Light + Q.Apls 524 525 // 人体・機器の潜熱 [W] 526 Q.Huml = rm.HL 527 Q.Apll = rm.AL 528 529 // 熱負荷 [W] 530 Q.Qinfs = Ca * rm.Gvent * (Wd.T - rm.Tr) 531 Q.Qinfl = Ro * rm.Gvent * (Wd.X - rm.xr) 532 Q.Qeqp = rm.Qeqp 533 Q.Qsto = rm.MRM * (rm.Trold - rm.Tr) / DTM 534 Q.Qstol = rm.GRM * Ro * (rm.xrold - rm.xr) / DTM 535 536 // 電力の消費量 [W] 537 if rm.AEsch != nil { 538 Q.AE = rm.AE * *rm.AEsch 539 } else { 540 Q.AE = 0.0 541 } 542 543 // ガスの消費量 [W] 544 if rm.AGsch != nil { 545 Q.AG = rm.AG * *rm.AGsch 546 } else { 547 Q.AG = 0.0 548 } 549 } 550 }