github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/blpanel.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_panel.c */ 17 18 package eeslism 19 20 import ( 21 "errors" 22 "math" 23 ) 24 25 const WPTOLE = 1.0e-10 26 27 /* 輻射パネル有効熱容量流量 */ 28 29 func panelwp(rdpnl *RDPNL) { 30 sd := rdpnl.sd[0] 31 eo := rdpnl.cmp.Elouts[0] 32 wall := sd.mw.wall 33 34 var Kc, Kcd float64 35 if wall.chrRinput { 36 Kc = sd.dblKc 37 Kcd = sd.dblKcd 38 } else { 39 Kc = wall.Kc 40 Kcd = wall.Kcd 41 } 42 43 if eo.Control != OFF_SW && rdpnl.cmp.Elins[0].Upv != nil { 44 rdpnl.cG = eo.G * Spcheat(eo.Fluid) 45 46 if wall.WallType == WallType_P { 47 rdpnl.Wp = rdpnl.cG * rdpnl.effpnl / sd.A 48 } else { 49 rdpnl.Ec = 1.0 - math.Exp(-Kc*sd.A/rdpnl.cG) 50 rdpnl.Wp = Kcd * rdpnl.cG * rdpnl.Ec / (Kc * sd.A) 51 } 52 } else { 53 rdpnl.cG = 0.0 54 rdpnl.Ec = 0.0 55 rdpnl.Wp = 0.0 56 } 57 58 // 流量が前時刻から変化していれば係数行列を作りなおす 59 if math.Abs(rdpnl.Wp-rdpnl.Wpold) >= WPTOLE || sd.PCMflg { 60 rdpnl.Wpold = rdpnl.Wp 61 62 for i := 0; i < rdpnl.MC; i++ { 63 rdpnl.sd[i].mrk = '*' // 表面の係数行列再作成 64 rdpnl.rm[i].mrk = '*' // 室の係数行列再作成 65 } 66 } 67 } 68 69 /* -------------------------------------- */ 70 71 /* 輻射パネル計算用係数 */ 72 73 func Panelcf(rdpnl *RDPNL) { 74 var j, nn, m, mp, M, iup, nrp, n, N int 75 var epr, epw *float64 76 var ew, kd float64 77 var rm *ROOM 78 var Sd, Sdd *RMSRF 79 var wall *WALL 80 var Mw *MWALL 81 var C1 float64 82 83 if rdpnl.Wp > 0.0 { 84 for m = 0; m < rdpnl.MC; m++ { 85 Sd = rdpnl.sd[m] 86 rm = rdpnl.rm[m] 87 N = rm.N 88 nrp = m 89 nn = N * nrp 90 91 if Sd.mrk == '*' || Sd.PCMflg { 92 if m == 0 { 93 Mw = Sd.mw 94 mp = Mw.mp 95 M = Mw.M 96 97 iup = mp * M 98 99 rdpnl.FIp[m] = Mw.UX[iup] * Mw.uo 100 if Mw.wall.WallType == WallType_P { // 通常の床暖房パネル 101 rdpnl.FOp[m] = Mw.UX[iup+M-1] * Mw.um 102 } else if Mw.wall.WallType == WallType_C { // 屋根一体型空気集熱器 103 rdpnl.FOp[m] = Mw.UX[iup+M-1] * Sd.ColCoeff 104 } 105 rdpnl.FPp = Mw.UX[iup+mp] * Mw.Pc * rdpnl.Wp 106 } else { 107 Mw = Sd.mw 108 rdpnl.FIp[1] = rdpnl.FOp[0] 109 rdpnl.FOp[1] = rdpnl.FIp[0] 110 } 111 112 wall = Mw.wall 113 C1 = Sd.alic 114 for j = 0; j < N; j++ { 115 alr := rm.alr[nn+j] 116 Sdd = rm.rsrf[j] 117 if j != nrp { 118 C1 += alr * Sdd.WSR 119 } 120 } 121 C1 *= rdpnl.FIp[m] / Sd.ali 122 123 if wall.WallType == WallType_P { // 床暖房パネル 124 rdpnl.EPt[m] = C1 * rdpnl.Wp * Sd.A 125 } else { // 屋根一体型空気集熱器 126 if wall.chrRinput { // 集熱器の特性が熱抵抗で入力されている場合 127 kd = Sd.kd 128 } else { 129 kd = wall.kd 130 } 131 rdpnl.EPt[m] = C1 * rdpnl.cG * rdpnl.Ec * kd 132 } 133 134 for j = 0; j < rm.Ntr; j++ { 135 epr = &rdpnl.EPR[m][j] 136 137 *epr = 0.0 138 for n = 0; n < N; n++ { 139 alr := rm.alr[nn+n] 140 Sdd := rm.rsrf[n] 141 142 if n != nrp { 143 *epr += alr * Sdd.WSRN[j] 144 } 145 } 146 if wall.WallType == WallType_P { 147 *epr *= rdpnl.FIp[m] / Sd.ali * rdpnl.Wp * Sd.A 148 } else { 149 if wall.chrRinput { 150 kd = Sd.kd 151 } else { 152 kd = wall.kd 153 } 154 155 *epr *= rdpnl.FIp[m] / Sd.ali * rdpnl.cG * rdpnl.Ec * kd 156 //*epr *= rdpnl.FIp[m] / Sd.ali * rdpnl.cG * rdpnl.Ec * wall.KdKo ; 157 } 158 159 /********* 160 *epr += rdpnl.FOp[m] * Sd.nxsd.alic / Sd.nxsd.ali; 161 ***********/ 162 } 163 if wall.WallType == WallType_P { // 通常の床暖房パネル 164 rdpnl.Epw = rdpnl.Wp * Sd.A * (1.0 - rdpnl.FPp) 165 } else { // 屋根一体型空気集熱器 166 if wall.chrRinput { 167 kd = Sd.kd 168 } else { 169 kd = wall.kd 170 } 171 172 rdpnl.Epw = rdpnl.cG * (1.0 - rdpnl.Ec*(1.-kd*rdpnl.FPp)) 173 } 174 //} 175 //else 176 // rdpnl.Epw = 1. - rdpnl.Ec * ( 1. + wall.KdKo * Sd.FP ) ; 177 178 for j = 0; j < rm.Nrp; j++ { 179 epw = &rdpnl.EPW[m][j] 180 181 ew = 0.0 182 for n = 0; n < N; n++ { 183 alr := rm.alr[nn+n] 184 Sdd := rm.rsrf[n] 185 186 if n != nrp { 187 ew += alr * Sdd.WSPL[j] 188 } 189 } 190 191 if wall.WallType == WallType_P { 192 *epw = rdpnl.Wp * Sd.A * rdpnl.FIp[m] * ew / Sd.ali 193 } else { 194 if wall.chrRinput { 195 kd = Sd.kd 196 } else { 197 kd = wall.kd 198 } 199 200 *epw = rdpnl.cG * rdpnl.FIp[m] * ew / Sd.ali * rdpnl.Ec * kd 201 } 202 } 203 } 204 } 205 } else { 206 rdpnl.Epw = 0.0 207 for m = 0; m < rdpnl.MC; m++ { 208 rm = rdpnl.rm[m] 209 rdpnl.EPt[m] = 0.0 210 211 for j = 0; j < rm.Ntr; j++ { 212 epr = &rdpnl.EPR[m][j] 213 *epr = 0.0 214 } 215 216 for j = 0; j < rm.Nrp; j++ { 217 epw = &rdpnl.EPW[m][j] 218 *epw = 0.0 219 } 220 } 221 } 222 } 223 224 /* -------------------------------------------- */ 225 226 /* 輻射パネルの外乱に関する項の計算 */ 227 228 func Panelce(rdpnl *RDPNL) float64 { 229 var N int 230 var rm *ROOM 231 var Sd *RMSRF 232 var Mw *MWALL 233 var j, nn, m, mp, M, iup, nrp int 234 var CFp, C, CC, kd, ku float64 235 var wall *WALL 236 237 Sd = nil 238 Mw = nil 239 wall = nil 240 CC = 0.0 241 242 if rdpnl.Wp > 0.0 { 243 for m = 0; m < rdpnl.MC; m++ { 244 Sd = rdpnl.sd[m] 245 246 if m == 0 { 247 Mw = Sd.mw 248 mp = Mw.mp 249 M = Mw.M 250 wall = Mw.wall 251 252 iup = mp * M 253 CFp = 0.0 254 for j = 0; j < M; j++ { 255 CFp += Mw.UX[iup+j] * Mw.Told[j] 256 } 257 258 CC = CFp 259 if Mw.wall.WallType == WallType_C { 260 if Mw.wall.chrRinput { 261 kd = Sd.kd 262 } else { 263 kd = Mw.wall.kd 264 } 265 CC = CFp * kd 266 } 267 if rdpnl.MC == 1 { 268 if Mw.wall.WallType == WallType_P { 269 CC += rdpnl.FOp[m] * Sd.Te 270 } else { 271 if wall.chrRinput { 272 kd = Sd.kd 273 ku = Sd.ku 274 } else { 275 kd = Mw.wall.kd 276 ku = Mw.wall.ku 277 } 278 CC += (ku + kd*rdpnl.FOp[m]) * Sd.Tcoleu 279 } 280 } 281 } 282 283 rm = rdpnl.rm[m] 284 N = rm.N 285 nrp = m 286 nn = N * nrp 287 288 C = 0.0 289 for j = 0; j < N; j++ { 290 alr := rm.alr[nn+j] 291 Sdd := rm.rsrf[j] 292 if j != nrp { 293 C += alr * Sdd.WSC 294 } 295 } 296 297 if Mw.wall.WallType == WallType_P { 298 CC += rdpnl.FIp[m] * (Sd.RS + C) / Sd.ali 299 } else { 300 if wall.chrRinput { 301 kd = Sd.kd 302 ku = Sd.ku 303 } else { 304 kd = Mw.wall.kd 305 ku = Mw.wall.ku 306 } 307 CC += kd * rdpnl.FIp[m] * (Sd.RS + C) / Sd.ali 308 } 309 } 310 311 if Mw.wall.WallType == WallType_P { 312 return (CC * rdpnl.Wp * Sd.A) 313 } else { 314 return (CC * rdpnl.cG * rdpnl.Ec) 315 } 316 } else { 317 return (0.0) 318 } 319 } 320 321 /* --------------------------- */ 322 323 /* 負荷計算用設定値のポインター */ 324 325 func rdpnlldsptr(load *ControlSWType, key []string, Rdpnl *RDPNL, idmrk *byte) (VPTR, error) { 326 var err error 327 var vptr VPTR 328 329 if key[1] == "Tout" { 330 vptr.Ptr = &Rdpnl.Toset 331 vptr.Type = VAL_CTYPE 332 Rdpnl.Loadt = load 333 *idmrk = 't' 334 } else { 335 err = errors.New("Tout is expected") 336 } 337 338 return vptr, err 339 } 340 341 /* ------------------------------------------ */ 342 343 /* 負荷計算用設定値のスケジュール設定 */ 344 345 func rdpnlldsschd(Rdpnl *RDPNL) { 346 Eo := Rdpnl.cmp.Elouts[0] 347 348 if Rdpnl.Loadt != nil { 349 if Eo.Control != OFF_SW { 350 if Rdpnl.Toset > TEMPLIMIT { 351 Eo.Control = ON_SW 352 //Eo.Control = LOAD_SW 353 //Eo.Sysv = Rdpnl.Toset 354 } else { 355 Eo.Control = OFF_SW 356 } 357 } 358 } 359 } 360 361 /* ------------------------------------- */ 362 363 /* 屋根一体型集熱器内部変数のポインター */ 364 365 func rdpnlvptr(key []string, Rdpnl *RDPNL) (VPTR, error) { 366 var err error 367 var vptr VPTR 368 369 if Rdpnl.sd[0].mw.wall.WallType == WallType_C && key[1] == "Te" { 370 vptr.Ptr = &Rdpnl.sd[0].Tcole 371 vptr.Type = VAL_CTYPE 372 } else { 373 err = errors.New("rdpnlvptr error") 374 } 375 376 return vptr, err 377 }