github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/blroomene.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 /* bl_roomene.c */ 17 18 package eeslism 19 20 import ( 21 "fmt" 22 "io" 23 "math" 24 ) 25 26 // 室温・湿度計算結果代入、室供給熱量計算 27 // およびパネル入口温度代入、パネル供給熱量計算 28 func Roomene(Rmvls *RMVLS, Room []*ROOM, Rdpnl []*RDPNL, Exsfs *EXSFS, Wd *WDAT) { 29 var j int 30 var E *ELOUT 31 32 for _, rm := range Room { 33 E = rm.cmp.Elouts[0] 34 rm.Tr = E.Sysv 35 E = rm.cmp.Elouts[1] 36 rm.xr = E.Sysv 37 rm.RH = FNRhtx(rm.Tr, rm.xr) 38 rm.hr = FNH(rm.Tr, rm.xr) 39 40 if rm.Arsp != nil { 41 42 for j = 0; j < rm.Nasup; j++ { 43 A := rm.Arsp[j] 44 elin := rm.elinasup[j] 45 elix := rm.elinasupx[j] 46 47 if elin.Lpath.Control != 0 { 48 A.G = elin.Lpath.G 49 A.Tin = elin.Sysvin 50 A.Xin = elix.Sysvin 51 } else { 52 A.G = 0.0 53 A.Tin = 0.0 54 A.Xin = 0.0 55 } 56 57 if elin.Lpath.Control != 0 { 58 A.Qs = Ca * elin.Lpath.G * (elin.Sysvin - rm.Tr) 59 } else { 60 A.Qs = 0.0 61 } 62 63 A.Ql = 0.0 64 if elix.Lpath != nil && elix.Lpath.Control != 0 { 65 A.Ql = Ro * elix.Lpath.G * (elix.Sysvin - rm.xr) 66 } 67 68 A.Qt = A.Qs + A.Ql 69 } 70 } 71 } 72 73 for i := range Rdpnl { 74 var Sd *RMSRF 75 var Wall *WALL 76 Sd = Rdpnl[i].sd[0] 77 Wall = Sd.mw.wall 78 if Rdpnl[i].cmp.Control != 0 { 79 E := Rdpnl[i].cmp.Elouts[0] 80 Rdpnl[i].Tpi = Rdpnl[i].cmp.Elins[0].Sysvin 81 Rdpnl[i].Tpo = E.Sysv 82 cG := Rdpnl[i].cG 83 Rdpnl[i].Q = cG * (E.Sysv - Rdpnl[i].Tpi) 84 85 if Wall.WallType == WallType_C { 86 var Kc float64 87 if Wall.chrRinput { 88 Kc = Sd.dblKc 89 } else { 90 Kc = Wall.Kc 91 } 92 93 ECG := cG * Rdpnl[i].Ec / (Kc * Sd.A) 94 Rdpnl[i].sd[0].Tf = (1.0-ECG)*Sd.Tcole + ECG*Rdpnl[i].Tpi 95 96 if Sd.Ndiv > 0 { 97 for k := 0; k < Sd.Ndiv; k++ { 98 Ec := 1.0 - math.Exp(-Kc*Sd.A*float64(k+1)/float64(Sd.Ndiv)/cG) 99 Sd.Tc[k] = (1.0-Ec)*Rdpnl[i].Tpi + Ec*Sd.Tcole 100 } 101 } 102 } 103 } else { 104 Rdpnl[i].Q = 0.0 105 Rdpnl[i].Tpi = 0.0 106 Rdpnl[i].sd[0].Tf = 0.0 107 108 if Sd.Ndiv > 0 { 109 for k := 0; k < Sd.Ndiv; k++ { 110 Sd.Tc[k] = 0.0 111 } 112 } 113 } 114 } 115 } 116 117 // PCM内蔵壁体の収束判定 118 func PCMwlchk(counter int, Rmvls *RMVLS, Exsfs *EXSFS, Wd *WDAT, LDreset *int) { 119 var Rmwlcreset int 120 121 Rmwlcreset = 0 122 // 室温の仮計算 123 for i := range Rmvls.Room { 124 Rm := Rmvls.Room[i] 125 Eo := Rm.cmp.Elouts[0] 126 Rm.Tr = Eo.Sysv 127 } 128 129 // 部位の表面温度の計算 130 Rmsurftd(Rmvls.Room, Rmvls.Sd) 131 132 // 壁体内部温度の仮計算 133 RMwltd(Rmvls.Mw) 134 135 // PCM温度の収束判定 136 for i := range Rmvls.Room { 137 Rm := Rmvls.Room[i] 138 139 // 部位でのループ 140 for j := 0; j < Rm.N; j++ { 141 Sd := Rm.rsrf[j] 142 if Sd.PCMflg { 143 mw := Sd.mw 144 Wall := mw.wall 145 Told := mw.Told 146 Toldd := mw.Toldd 147 Twd := mw.Twd 148 if Sd.mwside == RMSRFMwSideType_i { 149 for m := 0; m < mw.M; m++ { 150 pcmstate := Sd.pcmstate[m] 151 PCM := Wall.PCMLyr[m] 152 PCM1 := Wall.PCMLyr[m+1] 153 T := 0.0 154 Toldn := 0.0 155 PCMresetR := 0 156 PCMresetL := 0 157 nWeightR := -999.0 158 nWeightL := -999.0 159 if PCM != nil && PCM.Iterate { 160 pcmstate.TempPCMave = (Twd[m-1] + Twd[m]) * 0.5 161 pcmstate.TempPCMNodeL = Twd[m-1] 162 pcmstate.TempPCMNodeR = Twd[m] 163 ToldPCMave := (Told[m-1] + Told[m]) * 0.5 164 //ToldPCMNodeL := Told[m-1] 165 ToldPCMNodeR := Told[m] 166 if PCM.AveTemp == 'y' { 167 T = pcmstate.TempPCMave 168 Toldn = ToldPCMave 169 } else { 170 T = pcmstate.TempPCMNodeR 171 Toldn = ToldPCMNodeR 172 } 173 if PCM.Spctype == 'm' { 174 pcmstate.CapmR = FNPCMStatefun(PCM.Ctype, PCM.Cros, PCM.Crol, 175 PCM.Ql, PCM.Ts, PCM.Tl, PCM.Tp, Toldn, T, PCM.DivTemp, &PCM.PCMp) 176 } else { 177 pcmstate.CapmR = FNPCMstate_table(&PCM.Chartable[0], Toldn, T, PCM.DivTemp) 178 } 179 if math.Abs(pcmstate.CapmR-pcmstate.OldCapmR) > pcmstate.OldCapmR*PCM.IterateJudge || 180 (PCM.IterateTemp && math.Abs(Twd[m]-Toldd[m]) > 1e-2) { 181 nWeightR = PCM.NWeight 182 PCMresetR = 1 183 } 184 pcmstate.OldCapmR = pcmstate.CapmR 185 } 186 187 if PCM1 != nil && PCM1.Iterate { 188 pcmstate_p1 := Sd.pcmstate[m+1] 189 pcmstate_p1.TempPCMave = (Twd[m] + Twd[m+1]) * 0.5 190 pcmstate_p1.TempPCMNodeL = Twd[m] 191 pcmstate_p1.TempPCMNodeR = Twd[m+1] 192 ToldPCMave := (Told[m] + Told[m+1]) * 0.5 193 ToldPCMNodeL := Told[m] 194 //ToldPCMNodeR := Told[m+1] 195 if PCM1.AveTemp == 'y' { 196 T = pcmstate_p1.TempPCMave 197 Toldn = ToldPCMave 198 } else { 199 T = pcmstate_p1.TempPCMNodeL 200 Toldn = ToldPCMNodeL 201 } 202 if PCM1.Spctype == 'm' { 203 pcmstate_p1.CapmL = FNPCMStatefun(PCM1.Ctype, PCM1.Cros, PCM1.Crol, 204 PCM1.Ql, PCM1.Ts, PCM1.Tl, PCM1.Tp, Toldn, T, PCM1.DivTemp, &PCM1.PCMp) 205 } else { 206 pcmstate_p1.CapmL = FNPCMstate_table(&PCM1.Chartable[0], Toldn, T, PCM1.DivTemp) 207 } 208 if math.Abs(pcmstate_p1.CapmL-pcmstate_p1.OldCapmL) > pcmstate_p1.OldCapmL*PCM1.IterateJudge || 209 (PCM1.IterateTemp && math.Abs(Twd[m]-Toldd[m]) > 1e-2) { 210 nWeightL = PCM1.NWeight 211 PCMresetL = 1 212 } 213 pcmstate_p1.OldCapmL = pcmstate_p1.CapmL 214 } 215 216 if PCMresetR+PCMresetL != 0 { 217 var nWeight float64 218 if nWeightR > 0.0 && nWeightL > 0.0 { 219 nWeight = (nWeightR + nWeightL) / 2.0 220 } else { 221 nWeight = math.Max(nWeightR, nWeightL) 222 } 223 // Update Toldd[m] with the average value between the previous and current step 224 Toldd[m] = ((1.0 - nWeight) * Toldd[m]) + (nWeight * Twd[m]) 225 (*LDreset)++ 226 Rmwlcreset++ 227 } 228 } 229 } 230 } 231 } 232 } 233 234 if Rmwlcreset > 0 { 235 Roomcf(Rmvls.Mw, Rmvls.Room, Rmvls.Rdpnl, Wd, Exsfs) 236 } 237 } 238 239 // PCM内蔵家具のPCM温度収束判定 240 func PCMfunchk(Room []*ROOM, Wd *WDAT, LDreset *int) { 241 //var intI int 242 var tempTM float64 243 244 for intI := range Room { 245 if Room[intI].PCM != nil { 246 tempTM = Room[intI].TM 247 Room[intI].TM = Room[intI].FMT*Room[intI].Tr + Room[intI].FMC 248 if math.Abs(tempTM-Room[intI].TM) > 1e-2 && Room[intI].PCM.Iterate { 249 (*LDreset)++ 250 if Room[intI].PCM.NWeight > 0.0 { 251 Room[intI].TM = tempTM*(1.0-Room[intI].PCM.NWeight) + Room[intI].TM*Room[intI].PCM.NWeight 252 } else { 253 Room[intI].TM = (tempTM + Room[intI].TM) / 2.0 254 } 255 FunCoeff(Room[intI]) 256 257 if Room[intI].FunHcap > 0.0 { 258 dblTemp := DTM / Room[intI].FunHcap 259 Room[intI].FMC = 1.0 / (dblTemp**Room[intI].CM + 1.0) * (Room[intI].oldTM + dblTemp*Room[intI].Qsolm) 260 } else { 261 Room[intI].FMC = 0.0 262 } 263 264 Room[intI].RMC = Room[intI].MRM/DTM*Room[intI].Trold + Room[intI].HGc + Room[intI].CA 265 if Room[intI].FunHcap > 0.0 { 266 Room[intI].RMC += *Room[intI].CM * Room[intI].FMC 267 } 268 Room[intI].RMt += Ca * Room[intI].Gvent 269 Room[intI].RMC += Ca * Room[intI].Gvent * Wd.T 270 } 271 } 272 } 273 } 274 275 /* ------------------------------------------------------ */ 276 277 // 室負荷の計算 278 func Roomload(Room []*ROOM, LDreset *int) { 279 var reset, resetl int 280 281 for i := range Room { 282 rm := Room[i] 283 if rm.rmld != nil { 284 rmld := rm.rmld 285 rmld.Qs = 0.0 286 rmld.Ql = 0.0 287 rmld.Qt = 0.0 288 Eo := rm.cmp.Elouts[0] 289 290 if Eo.Control == LOAD_SW { 291 rmld.Qs = rm.RMt*rm.Tr - rm.RMC 292 293 for j := 0; j < rm.Ntr; j++ { 294 trnx := rm.trnx[j] 295 arn := rm.ARN[j] 296 rmld.Qs -= arn * trnx.nextroom.Tr 297 } 298 for j := 0; j < rm.Nrp; j++ { 299 rmpnl := rm.rmpnl[j] 300 rmp := rm.RMP[j] 301 rmld.Qs -= rmp * rmpnl.pnl.Tpi 302 } 303 304 if rm.Arsp != nil { 305 for j := 0; j < rm.Nasup; j++ { 306 A := rm.Arsp[j] 307 rmld.Qs -= A.Qs 308 } 309 } 310 311 for j := 0; j < rm.Nachr; j++ { 312 achr := rm.achr[j] 313 rmld.Qs -= Ca * achr.Gvr * (Room[achr.rm].Tr - rm.Tr) 314 } 315 316 reset = rmloadreset(rmld.Qs, *rmld.loadt, Eo, ON_SW) 317 if reset != 0 { 318 (*LDreset)++ 319 //fmt.Printf("resetting...\n") 320 } 321 } 322 323 Eo = rm.cmp.Elouts[1] 324 if Eo.Control == LOAD_SW { 325 rmld.Ql = Ro * (rm.RMx*rm.xr - rm.RMXC) 326 if rm.Arsp != nil { 327 for j := 0; j < rm.Nasup; j++ { 328 A := rm.Arsp[j] 329 rmld.Ql -= A.Ql 330 } 331 } 332 333 for j := 0; j < rm.Nachr; j++ { 334 achr := rm.achr[j] 335 rmld.Ql -= Ro * achr.Gvr * (Room[achr.rm].xr - rm.xr) 336 } 337 338 resetl = rmloadreset(rmld.Ql, *rmld.loadt, Eo, ON_SW) 339 if reset != 0 || resetl != 0 { 340 Eo.Control = ON_SW 341 Eo.Eldobj.Sysld = 'n' 342 (*LDreset)++ 343 //fmt.Printf("resetting...\n") 344 } 345 } 346 347 rmld.Qt = rmld.Qs + rmld.Ql 348 } 349 } 350 } 351 352 /* ------------------------------------------------------ */ 353 354 /* 室供給熱量の出力 */ 355 356 func rmqaprint(fo io.Writer, id int, Rooms []*ROOM) { 357 var Nload, Nfnt int 358 //var rpnl *RPANEL 359 360 switch id { 361 case 0: 362 if len(Rooms) > 0 { 363 fmt.Fprintf(fo, "%s %d\n", ROOM_TYPE, len(Rooms)) 364 } 365 for _, Room := range Rooms { 366 if Room.rmld != nil { 367 Nload = 2 368 } else { 369 Nload = 0 370 } 371 372 Nfnt = 0 373 if Room.FunHcap > 0.0 { 374 Nfnt = 4 375 } 376 377 Nset := 0 378 if Room.setpri { 379 Nset = 1 380 } 381 fmt.Fprintf(fo, " %s 5 %d 4 %d %d %d\n", Room.Name, 382 4+Nload+Room.Nasup*5+Room.Nrp+Nfnt+Nset, 383 Nload, Room.Nasup*5, Room.Nrp) 384 } 385 case 1: 386 for _, Room := range Rooms { 387 fmt.Fprintf(fo, "%s_Tr t f %s_xr x f %s_RH r f %s_Ts t f ", 388 Room.Name, Room.Name, Room.Name, Room.Name) 389 390 if Room.setpri { 391 fmt.Fprintf(fo, "%s_SET* t f ", Room.Name) 392 } 393 394 if Room.FunHcap > 0.0 { 395 fmt.Fprintf(fo, "%s_TM t f %s_QM q f %s_QMsol q f %s_PCMQl q f ", Room.Name, Room.Name, Room.Name, Room.Name) 396 } 397 398 if Room.rmld != nil { 399 fmt.Fprintf(fo, "%s_Ls q f %s_Lt q f ", Room.Name, Room.Name) 400 } 401 402 if Room.Nasup > 0 { 403 Ei := Room.cmp.Elins[Room.Nachr+Room.Nrp] 404 for j := 0; j < Room.Nasup; j++ { 405 if Ei.Lpath == nil { 406 fmt.Fprintf(fo, "%s:%1d_G m f %s:%1d_Tin t f %s:%1d_Xin x f %s:%1d_Qas q f %s:%1d_Qat q f ", 407 Room.Name, j, Room.Name, j, Room.Name, j, Room.Name, j, Room.Name, j) 408 } else { 409 fmt.Fprintf(fo, "%s:%s_G m f %s:%s_Tin t f %s:%s_Xin x f %s:%s_Qas q f %s:%s_Qat q f ", 410 Room.Name, Ei.Lpath.Name, Room.Name, Ei.Lpath.Name, Room.Name, Ei.Lpath.Name, Room.Name, Ei.Lpath.Name, 411 Room.Name, Ei.Lpath.Name) 412 } 413 } 414 } 415 416 for j := 0; j < Room.Nrp; j++ { 417 rpnl := Room.rmpnl[j] 418 fmt.Fprintf(fo, "%s:%s_Qp q f ", Room.Name, rpnl.pnl.Name) 419 } 420 421 fmt.Fprintf(fo, "\n") 422 } 423 default: 424 for _, Room := range Rooms { 425 fmt.Fprintf(fo, "%.2f %5.4f %2.0f %.2f ", 426 Room.Tr, Room.xr, Room.RH, Room.Tsav) 427 428 if Room.setpri { 429 fmt.Fprintf(fo, "%.2f ", Room.SET) 430 } 431 432 if Room.FunHcap > 0.0 { 433 fmt.Fprintf(fo, "%.2f %.2f %.2f %.2f ", Room.TM, Room.QM, Room.Qsolm, Room.PCMQl) 434 } 435 436 if Room.rmld != nil { 437 fmt.Fprintf(fo, "%.2f %.2f ", Room.rmld.Qs, Room.rmld.Qt) 438 } 439 440 if Room.Nasup > 0 { 441 for j := 0; j < Room.Nasup; j++ { 442 A := Room.Arsp[j] 443 fmt.Fprintf(fo, "%.4g %4.1f %.4f %.2f %.2f ", A.G, A.Tin, A.Xin, A.Qs, A.Qt) 444 } 445 } 446 447 for j := 0; j < Room.Nrp; j++ { 448 rpnl := Room.rmpnl[j] 449 fmt.Fprintf(fo, " %.2f", -rpnl.pnl.Q) 450 } 451 452 fmt.Fprintf(fo, "\n") 453 } 454 } 455 } 456 457 /* ------------------------------------------------------ */ 458 459 /* 放射パネルに関する出力 */ 460 461 func panelprint(fo io.Writer, id int, Rdpnl []*RDPNL) { 462 var ld int 463 var Wall *WALL 464 465 switch id { 466 case 0: 467 if len(Rdpnl) > 0 { 468 fmt.Fprintf(fo, "%s %d\n", RDPANEL_TYPE, len(Rdpnl)) 469 } 470 for i := range Rdpnl { 471 Sd := Rdpnl[i].sd[0] 472 Wall = Sd.mw.wall 473 if Sd.mw.wall.WallType == WallType_P { 474 fmt.Fprintf(fo, " %s 1 5\n", Rdpnl[i].Name) 475 } else { 476 ld = 0 477 if Wall.chrRinput { 478 ld = 5 479 } 480 if Rdpnl[i].sd[0].PVwallFlg { 481 fmt.Fprintf(fo, " %s 1 %d\n", Rdpnl[i].Name, Sd.Ndiv+11+ld) 482 } else { 483 fmt.Fprintf(fo, " %s 1 %d\n", Rdpnl[i].Name, Sd.Ndiv+8+ld) 484 } 485 } 486 } 487 case 1: 488 for i := range Rdpnl { 489 Sd := Rdpnl[i].sd[0] 490 Wall = Sd.mw.wall 491 if Sd.mw.wall.WallType == WallType_P { 492 fmt.Fprintf(fo, "%s_c c c %s_G m f %s_Ti t f %s_To t f %s_Q q f\n", 493 Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name) 494 } else { 495 if !Sd.PVwallFlg { 496 fmt.Fprintf(fo, "%s_c c c %s_G m f %s_Ti t f %s_To t f %s_Te t f %s_Tf t f %s_Q q f %s_S q f\n", 497 Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name) 498 } else { 499 fmt.Fprintf(fo, "%s_c c c %s_G m f %s_Ti t f %s_To t f %s_Te t f %s_Tf t f %s_Q q f %s_S q f %s_TPV t f %s_Iw q f %s_P q f\n", 500 Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, 501 Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name) 502 503 if Wall.chrRinput { 504 fmt.Fprintf(fo, "%s_Ksu q f %s_Ksd q f %s_Kc q f %s_Tsu t f %s_Tsd t f\n", Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name, Rdpnl[i].Name) 505 } 506 507 if Sd.Ndiv > 0 { 508 for k := 0; k < Sd.Ndiv; k++ { 509 fmt.Fprintf(fo, "%s_Tc[%d] t f ", Rdpnl[i].Name, k+1) 510 } 511 fmt.Fprintf(fo, "\n") 512 } 513 } 514 } 515 } 516 default: 517 for i := range Rdpnl { 518 Sd := Rdpnl[i].sd[0] 519 Wall = Sd.mw.wall 520 if Sd.mw.wall.WallType == WallType_P { 521 fmt.Fprintf(fo, "%c %g %4.1f %4.1f %3.0f\n", Rdpnl[i].cmp.Elouts[0].Control, 522 Rdpnl[i].cmp.Elouts[0].G, Rdpnl[i].Tpi, Rdpnl[i].cmp.Elouts[0].Sysv, Rdpnl[i].Q) 523 } else { 524 Eo := Rdpnl[i].cmp.Elouts[0] 525 G := 0.0 526 Wall = Sd.mw.wall 527 if Eo.Control != OFF_SW { 528 G = Eo.G 529 } 530 531 fmt.Fprintf(fo, "%c %g %4.1f %4.1f %4.1f %4.1f %3.0f %3.0f ", Eo.Control, 532 G, Rdpnl[i].Tpi, Eo.Sysv, Sd.Tcole, Sd.Tf, Rdpnl[i].Q, Sd.Iwall*Sd.A) 533 534 if Sd.PVwallFlg { 535 fmt.Fprintf(fo, "%4.1f %4.0f %3.0f\n", Sd.PVwall.TPV, Sd.Iwall, Sd.PVwall.Power) 536 } else { 537 fmt.Fprintf(fo, "\n") 538 } 539 540 if Wall.chrRinput { 541 fmt.Fprintf(fo, "%.3f %.3f %.3f %.1f %.1f\n", Sd.dblKsu, Sd.dblKsd, Sd.dblKc, Sd.dblTsu, Sd.dblTsd) 542 } 543 544 if Sd.Ndiv > 0 { 545 for k := 0; k < Sd.Ndiv; k++ { 546 fmt.Fprintf(fo, "%4.1f ", Sd.Tc[k]) 547 } 548 fmt.Fprintf(fo, "\n") 549 } 550 } 551 } 552 } 553 }