github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/eepathlib_s.go (about) 1 package eeslism 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 ) 8 9 /* 経路の定義用関数 */ 10 11 /* ----------------------------------------------- */ 12 13 // システム要素出力端割当 14 func pelmco(pflow FliudType, Pelm *PELM, errkey string) { 15 var Nout int 16 err := 0 17 var cmp *COMPNT 18 var elmo *ELOUT 19 20 cmp = Pelm.Cmp 21 Nout = cmp.Nout 22 23 elmo_idx := 0 24 elmo = cmp.Elouts[elmo_idx] 25 26 if cmp.Eqptype == DIVERG_TYPE || cmp.Eqptype == DIVGAIR_TYPE { 27 for i := 0; i < Nout; i++ { 28 elmo = cmp.Elouts[elmo_idx] 29 if elmo.Id != '*' { 30 Pelm.Co = '*' 31 elmo.Id = '*' 32 Pelm.Out = elmo 33 err = 0 34 break 35 } 36 elmo_idx++ 37 } 38 } else if cmp.Eqptype == STANK_TYPE { 39 stank := cmp.Eqp.(*STANK) 40 var i, ii int 41 for i = 0; i < stank.Nin; i++ { 42 if stank.Pthcon[i] == Pelm.Co { 43 break 44 } 45 } 46 ii = i 47 for i = 0; i < Nout; i++ { 48 elmo = cmp.Elouts[elmo_idx] 49 if elmo.Id == stank.Pthcon[ii] { 50 Pelm.Out = elmo 51 err = 0 52 break 53 } 54 elmo_idx++ 55 } 56 } else if Nout == 1 { 57 Pelm.Out = elmo 58 Pelm.Co = elmo.Id 59 } else if cmp.Eqptype == RDPANEL_TYPE { 60 if pflow == WATER_FLD || pflow == AIRa_FLD { 61 Pelm.Out = elmo 62 Pelm.Co = elmo.Id 63 } else if pflow == AIRx_FLD { 64 elmo_idx++ 65 Pelm.Out = elmo 66 Pelm.Co = elmo.Id 67 } 68 } else { 69 err = 1 70 for i := 0; i < Nout; i++ { 71 elmo = cmp.Elouts[i] 72 if Pelm.Co == elmo.Id { 73 Pelm.Out = elmo 74 err = 0 75 break 76 } 77 } 78 } 79 80 if err != 0 { 81 for i := 0; i < Nout; i++ { 82 elmo = cmp.Elouts[i] 83 84 if (pflow == AIRa_FLD && elmo.Id == 't') || 85 (pflow == AIRx_FLD && elmo.Id == 'x') || 86 (pflow == WATER_FLD && elmo.Id == 'W') { 87 Pelm.Out = elmo 88 Pelm.Co = elmo.Id 89 err = 0 90 break 91 } 92 } 93 } 94 95 // Satoh追加 気化冷却器 2013/10/31 96 if err != 0 { 97 if cmp.Eqptype == EVAC_TYPE { 98 Nout = 4 99 } 100 101 for i := 0; i < Nout; i++ { 102 elmo = cmp.Elouts[i] 103 if Pelm.Co == elmo.Id || 104 (Pelm.Co == 'W' && elmo.Id == 'V') || 105 (Pelm.Co == 'w' && elmo.Id == 'v') { 106 Pelm.Out = elmo 107 err = 0 108 break 109 } 110 } 111 } 112 113 Errprint(err, errkey+" <pelmco>", cmp.Name) 114 } 115 116 /* ----------------------------------------------- */ 117 118 // システム要素入力端割当 119 func pelmci(pflow FliudType, Pelm *PELM, errkey string) { 120 err := 0 121 cmp := Pelm.Cmp 122 elmi := cmp.Elins[0] 123 Nin := cmp.Nin 124 125 // 入口の数が0の場合は処理を行わない 126 if Nin <= 0 { 127 return 128 } 129 130 if cmp.Eqptype == CONVRG_TYPE || cmp.Eqptype == CVRGAIR_TYPE { 131 // 合流要素の場合 132 // 133 for i := 0; i < Nin; i++ { 134 elmi := cmp.Elins[i] 135 if elmi.Id != ELIO_ASTER { 136 elmi.Id = ELIO_ASTER 137 Pelm.Ci = ELIO_ASTER 138 Pelm.In = elmi 139 break 140 } 141 } 142 } else if SIMUL_BUILDG && cmp.Eqptype == ROOM_TYPE { 143 // 室要素の場合 144 // 145 room := cmp.Eqp.(*ROOM) 146 147 var elins *[]*ELIN 148 if pflow == AIRa_FLD { 149 // 流体が空気(温度)の場合: 150 elins = &room.elinasup 151 } else if pflow == AIRx_FLD { 152 // 流体が空気(湿度)の場合: 153 elins = &room.elinasupx 154 } else { 155 panic(pflow) 156 } 157 158 for i := 0; i < room.Nasup; i++ { 159 elmi := (*elins)[i] 160 if elmi.Id != ELIO_ASTER { 161 Pelm.Ci = ELIO_ASTER 162 elmi.Id = ELIO_ASTER 163 Pelm.In = elmi 164 break 165 } 166 } 167 } else if SIMUL_BUILDG && cmp.Eqptype == RDPANEL_TYPE { 168 // 放射パネル要素の場合 169 // 170 if pflow == WATER_FLD || pflow == AIRa_FLD { 171 Elout_a := cmp.Elouts[0] // 温水または空気温度 172 for i := 0; i < Elout_a.Ni; i++ { 173 elmi := cmp.Elins[i] 174 if elmi.Id == ELIO_f { 175 Pelm.Ci = elmi.Id 176 Pelm.In = elmi 177 break 178 } 179 } 180 } else if pflow == AIRx_FLD { 181 Elout_x := cmp.Elouts[1] // 空気湿度 182 elmi := Elout_x.Elins[0] 183 Pelm.Ci = elmi.Id 184 Pelm.In = elmi 185 } 186 } else if Nin == 1 { 187 // 入口の数が1の場合 188 // 189 Pelm.In = elmi 190 Pelm.Ci = elmi.Id 191 } else { 192 err = 1 193 194 for i := 0; i < Nin; i++ { 195 elmi := cmp.Elins[i] 196 197 // ACの絶対湿度はここに入った 198 if Pelm.Ci == elmi.Id { 199 Pelm.In = elmi 200 err = 0 201 break 202 } 203 } 204 } 205 206 if err != 0 { 207 208 if cmp.Eqptype == HCLOADW_TYPE { 209 Hcload := cmp.Eqp.(*HCLOAD) 210 if Hcload.Wet { 211 Nin = 4 212 } 213 } else if cmp.Eqptype == DESI_TYPE { 214 Nin = 4 215 } 216 217 for i := 0; i < Nin; i++ { 218 elmi := cmp.Elins[i] 219 if (pflow == AIRa_FLD && elmi.Id == ELIO_t) || 220 (pflow == AIRx_FLD && elmi.Id == ELIO_x) || 221 (pflow == WATER_FLD && elmi.Id == ELIO_W) { 222 Pelm.In = elmi 223 Pelm.Ci = elmi.Id 224 err = 0 225 break 226 } 227 } 228 229 //printf("\n") ; 230 } 231 232 if err != 0 { 233 234 if cmp.Eqptype == THEX_TYPE { 235 N := 0 236 for i := 0; i < cmp.Nout; i++ { 237 Eo := cmp.Elouts[i] 238 N += Eo.Ni 239 } 240 241 Nin = N 242 } 243 244 for i := 0; i < Nin; i++ { 245 elmi := cmp.Elins[i] 246 if Pelm.Ci == elmi.Id { 247 Pelm.In = elmi 248 err = 0 249 break 250 } 251 } 252 } 253 254 if err != 0 { 255 if cmp.Eqptype == EVAC_TYPE { 256 N := 0 257 for i := 0; i < cmp.Nout; i++ { 258 Eo := cmp.Elouts[i] 259 N += Eo.Ni 260 } 261 262 Nin = N 263 } 264 265 for i := 0; i < Nin; i++ { 266 elmi := cmp.Elins[i] 267 if Pelm.Ci == elmi.Id || 268 (Pelm.Ci == 'W' && elmi.Id == 'V') || 269 (Pelm.Ci == 'w' && elmi.Id == 'v') { 270 Pelm.In = elmi 271 err = 0 272 break 273 } 274 } 275 } 276 277 Errprint(err, errkey+" <pelmci>", cmp.Name) 278 } 279 280 /* ----------------------------------------------- */ 281 282 // システム要素接続データのコピー(空気系統湿度経路用 283 // 空気経路の場合は湿度経路用にpathをコピーする 284 // 285 // - 空気温度用のシステム経路 mpath_t の設定を 空湿度用のシステム経路 にコピーする。 286 // - コピーに際して要素(PELM)を追加する。 287 // - 要素(PELM)は _Pelm 配列に追加するものとし、 Npelm 番目から詰め込むとする。 Npelmは上書きする。 288 // ##- _Plist は システム経路 mpath_t に属するすべての 末端経路の配列である。 289 // - Compntには SYSCMPデータセットで読み込んだすべての機器情報が保持されている。 290 func plistcpy(mpath_t *MPATH, _Pelm *[]*PELM, _Plist *[]*PLIST, Compnt []*COMPNT) *MPATH { 291 // 空気湿度用経路 292 var mpath_x *MPATH = NewMPATH() 293 mpath_x.Name = mpath_t.Name + ".x" // 湿度用経路の名前 = 温度経路用の名前 + ".x" 294 //mpath_x.Plist = _Plist // 末端経路 (要確認) 295 mpath_x.Fluid = AIRx_FLD // 流体種別 = 空気湿度 296 mpath_x.G0 = mpath_t.G0 // 流量比率 297 mpath_x.Rate = mpath_t.Rate // 流量比率フラグ 298 299 // 空気温度用経路 300 mpath_t.Fluid = AIRa_FLD // 流体種別を念のため上書き? 301 mpath_t.Mpair = mpath_x // 空気湿度経路への参照(Mpair)を設定 302 303 // 末端経路についてループ 304 for i := range mpath_t.Plist { 305 pli := mpath_t.Plist[i] 306 Plist := NewPLIST() 307 308 // ターゲットの末端経路 309 //pli := &mpath_t.Plist[i] 310 311 // 相互参照設定 312 pli.Lpair = Plist 313 pli.Plistx = Plist 314 Plist.Plistt = pli 315 316 // コピー 317 Plist.Pelm = nil 318 Plist.Org = false 319 Plist.Type = pli.Type 320 Plist.Go = pli.Go 321 Plist.Nvav = pli.Nvav 322 Plist.Nvalv = pli.Nvalv 323 Plist.NOMVAV = pli.NOMVAV 324 Plist.OMvav = pli.OMvav 325 Plist.Valv = pli.Valv 326 Plist.Rate = pli.Rate 327 Plist.UnknownFlow = pli.UnknownFlow 328 329 // 名前のコピー: ".x"を付与しながらコピー 330 if pli.Name != "" { 331 Plist.Name = pli.Name + ".x" 332 } else { 333 Plist.Name = ".x" 334 } 335 336 // 要素のコピー 337 nelm := 0 338 Plist.Pelm = make([]*PELM, 0, len(pli.Pelm)) 339 for _, peli := range pli.Pelm { 340 341 // コピー対象は空気経路のみ 342 if !peli.Cmp.Airpathcpy { 343 continue 344 } 345 346 var Pelm *PELM = NewPELM() 347 348 *_Pelm = append(*_Pelm, Pelm) 349 Plist.Pelm = append(Plist.Pelm, Pelm) 350 351 if peli.Cmp.Eqptype == CVRGAIR_TYPE || peli.Cmp.Eqptype == DIVGAIR_TYPE { 352 // ** 合流要素の場合 ** 353 354 // Find index 355 k, err := FindComponentRef(peli.Cmp, Compnt) 356 if err != nil { 357 panic(err) 358 } 359 360 // k+1番目位以降のコンポーネントのみ検索している: 理由?? 361 var cmp *COMPNT 362 for k++; k < len(Compnt); k++ { 363 cmp = Compnt[k] 364 s := cmp.Name 365 366 // "name.xxx" のうち name だけで一致する機器を探す。 367 if idx := strings.IndexRune(s, '.'); idx >= 0 { 368 s = s[:idx] 369 370 if peli.Cmp.Name == s { 371 break 372 } 373 } 374 } 375 Pelm.Cmp = cmp // 検索で見つけた機器参照 376 } else if peli.Cmp.Eqptype == THEX_TYPE { 377 // ** 全熱交換器の場合 ** 378 Pelm.Cmp = peli.Cmp 379 if peli.Ci == ELIO_E { 380 Pelm.Ci = ELIO_e 381 Pelm.Co = ELIO_e 382 } else { 383 Pelm.Ci = ELIO_o 384 Pelm.Co = ELIO_o 385 } 386 } else if peli.Cmp.Eqptype == EVAC_TYPE { 387 // Satoh追加 気化冷却器 2013/10/31 388 Pelm.Cmp = peli.Cmp 389 if peli.Ci == ELIO_D { 390 Pelm.Ci = ELIO_d 391 Pelm.Co = ELIO_d 392 } else if peli.Ci == ELIO_W { 393 Pelm.Ci = ELIO_w 394 Pelm.Co = ELIO_w 395 } 396 } else { 397 Pelm.Cmp = peli.Cmp 398 Pelm.Ci = peli.Ci 399 Pelm.Co = peli.Co 400 } 401 402 Pelm.Out = peli.Out 403 nelm++ 404 } 405 406 mpath_x.Plist = append(mpath_x.Plist, Plist) 407 } 408 409 return mpath_x 410 } 411 412 /* ----------------------------------------------- */ 413 414 /* 合流レベルの設定 */ 415 416 func plevel(Nmpath int, Mpath []MPATH, Ncnvrg int, Cnvrg []*COMPNT) { 417 418 var i, j int 419 lvc := 0 420 var lvcmx, lvcf int 421 var Plist *PLIST 422 var cmp *COMPNT 423 var elin *ELIN 424 425 for i = 0; i < Ncnvrg; i++ { 426 cmp = Cnvrg[i] 427 cmp.Elouts[0].Lpath.Lvc = -1 428 } 429 430 lvcf = Ncnvrg 431 432 for lvcf > 0 { 433 for i = 0; i < Ncnvrg; i++ { 434 cmp = Cnvrg[i] 435 if cmp.Elouts[0].Lpath.Lvc <= 0 { 436 for j = 0; j < cmp.Nin; j++ { 437 elin = cmp.Elins[j] 438 Plist = elin.Lpath 439 if Plist.Type != CONVRG_LPTP { 440 lvc = 0 441 } else { 442 if Plist.Lvc > 0 { 443 if lvc <= Plist.Lvc { 444 lvc = Plist.Lvc 445 } 446 } else { 447 break 448 } 449 } 450 } 451 452 if j == cmp.Nin { 453 lvc++ 454 cmp.Elouts[0].Lpath.Lvc = lvc 455 456 lvcf-- 457 } 458 } 459 } 460 } 461 462 for i = 0; i < Nmpath; i++ { 463 _Mpath := &Mpath[i] 464 465 lvcmx = 0 466 467 for _, Plist := range _Mpath.Plist { 468 if Plist.Lvc > lvcmx { 469 lvcmx = Plist.Lvc 470 } 471 } 472 _Mpath.Lvcmx = lvcmx 473 } 474 } 475 476 /* ----------------------------------------------- */ 477 478 func pflowstrct(_Mpath []*MPATH) { 479 var j, n, M, MM, k int 480 var etype EqpType 481 var Elout *ELOUT 482 var Elin *ELIN 483 484 var nplist int = 0 485 for _, Mpath := range _Mpath { 486 nplist += len(Mpath.Plist) 487 } 488 489 for _, Mpath := range _Mpath { 490 Mpath.Pl = make([]*PLIST, nplist) 491 Mpath.Cbcmp = make([]*COMPNT, nplist) 492 } 493 494 for _, Mpath := range _Mpath { 495 n = 0 496 497 for _, Plist := range Mpath.Plist { 498 // 流量未設定の末端経路を検索 499 if Plist.Go == nil && Plist.Nvav == 0 && 500 Plist.Rate == nil && Plist.NOMVAV == 0 && 501 (Plist.Nvalv == 0 || (Plist.Nvalv > 0 && Plist.Valv.MonPlist == nil && Plist.Valv.MGo == nil)) { 502 Mpath.Pl[n] = Plist 503 Plist.N = n 504 // 末端経路未知フラグの変更 505 Plist.UnknownFlow = 0 506 n++ 507 } 508 509 if Mpath.Rate && (Plist.Go != nil || Plist.Nvav > 0 || Plist.Nvalv > 0 || Plist.NOMVAV > 0) { 510 Mpath.G0 = &Plist.G // 流量比率設定時の既知流量へのポインタをセット 511 } 512 } 513 514 Mpath.NGv = n 515 Mpath.NGv2 = n * n 516 517 n = 0 518 519 for _, Plist := range Mpath.Plist { 520 521 // 末端経路の先頭機器 522 etype = Plist.Pelm[0].Cmp.Eqptype 523 524 // 末端経路の先頭が分岐・合流の場合 525 if etype == CONVRG_TYPE || 526 etype == CVRGAIR_TYPE || 527 etype == DIVERG_TYPE || 528 etype == DIVGAIR_TYPE { 529 MM = 0 530 531 for k = 0; k < n; k++ { 532 if Plist.Pelm[0].Cmp == Mpath.Cbcmp[k] { 533 MM++ 534 break 535 } 536 } 537 538 if MM == 0 { 539 // 末端経路の先頭機器(分岐・合流)の入口、出口経路の未知流量の数(M)を数える 540 M = 0 541 542 // 末端経路の先頭機器の入口 543 for j = 0; j < Plist.Pelm[0].Cmp.Nin; j++ { 544 Elin = Plist.Pelm[0].Cmp.Elins[j] 545 546 Plist.Upplist = Elin.Lpath 547 // 末端経路の先頭機器の上流の流量が未定義 548 if Elin.Lpath.UnknownFlow == 0 { 549 M++ 550 break 551 } 552 } 553 554 if M == 0 { 555 // 末端経路の先頭機器の出口 556 Elout = Plist.Pelm[0].Cmp.Elouts[0] 557 558 for j = 0; j < Plist.Pelm[0].Cmp.Nout; j++ { 559 Elout = Plist.Pelm[0].Cmp.Elouts[j] 560 561 Plist.Dnplist = Elout.Lpath 562 // 末端経路の先頭機器の出口経路の流量が未知なら 563 if Elout.Lpath.UnknownFlow == 0 { 564 M++ 565 break 566 } 567 } 568 } 569 570 // 末端経路先頭にある分岐・合流の入口もしくは出口経路の未知流量の数(M) 571 if M > 0 { 572 // 流量連立方程式を解くときに使用する分岐・合流機器と数(n) 573 Mpath.Cbcmp[n] = Plist.Pelm[0].Cmp 574 n++ 575 } 576 } 577 } 578 } 579 580 // 既知末端流量数のチェック 581 if n > 0 && (n-1 != Mpath.NGv) { 582 fmt.Printf("<%s> 末端流量の与えすぎ、もしくは少なすぎです n=%d NGv=%d\n", Mpath.Name, n, Mpath.NGv) 583 } 584 } 585 } 586 587 func FindComponentRef(target *COMPNT, Compnt []*COMPNT) (int, error) { 588 for k := range Compnt { 589 cmp := Compnt[k] 590 if cmp == target { 591 return k, nil 592 } 593 } 594 return -1, errors.New("Not Found") 595 }