github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/blsolarwall.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 // 空気集熱建材のシミュレーション 17 18 package eeslism 19 20 import ( 21 "fmt" 22 "math" 23 ) 24 25 // 集熱器の放射取得熱量 26 func FNScol(ta, I, EffPV, Ku, ao, Eo, Fs, RN float64) float64 { 27 return (ta-EffPV)*I - Ku/ao*Eo*Fs*RN 28 } 29 30 // 建材一体型空気集熱器の相当外気温度を計算する 31 func CalcSolarWallTe(Rmvls *RMVLS, Wd *WDAT, Exsfs *EXSFS) { 32 for i := range Rmvls.Rdpnl { 33 rdpnl := Rmvls.Rdpnl[i] 34 Sd := rdpnl.sd[0] 35 if Sd.mw != nil && Sd.mw.wall.WallType == WallType_C { 36 Sd.Tcole = FNTcoleContrl(Sd, Wd, Exsfs) 37 } 38 } 39 } 40 41 // 集熱器相当外気温度の計算(制御用) 42 // 集熱器裏面温度は前時刻の値を使用する 43 func FNTcoleContrl(Sd *RMSRF, Wd *WDAT, Exsfs *EXSFS) float64 { 44 var Cidf float64 45 var Wall *WALL 46 var Exs *EXSF 47 var Glsc float64 48 var Ksu, alo, ku, kd float64 49 50 if Sd.mw.wall.ColType != "" { 51 Wall = Sd.mw.wall 52 Exs = Exsfs.Exs[Sd.exs] 53 Glsc = 1.0 54 Cidf = 1.0 55 if Sd.mw.wall.ColType != "" && 56 Sd.mw.wall.ColType[:2] != "A2" && 57 Sd.mw.wall.ColType[:2] != "W2" { 58 Glsc = Glscid(Exs.Cinc) 59 Cidf = 0.91 60 } 61 62 //熱貫流率等の計算 63 if Wall.chrRinput { 64 FNKc(Wd, Exsfs, Sd) 65 Ksu = Sd.dblKsu 66 alo = Sd.dblao 67 ku = Sd.ku 68 kd = Sd.kd 69 } else { 70 //熱貫流率が入力値の場合 71 Ksu = Wall.Ksu 72 alo = *Exs.Alo 73 ku = Wall.ku 74 kd = Wall.kd 75 } 76 77 //Sd.Scol = FNScol(Wall.tra, Glsc*Exs.Idre+Cidf*Exs.Idf, Sd.PVwall.Eff, Ksu, alo, Wall.Eo, Exs.Fs, Wd.RN) 78 //fmt.Printf("Ko=%g Scol=%g Ku=%g Ta=%g Kd=%g Tx=%g\n", Wall.Ko, Sd.Scol, Wall.Ku, Wd.T, Wall.Kd, Sd.oldTx) 79 80 // Satoh DEBUG 2018/2/26 壁体一体型空気集熱器への影の影響を考慮するように修正 81 Sd.Tcoled = Sd.oldTx 82 Idre := Exs.Idre 83 Idf := Exs.Idf 84 RN := Exs.Rn 85 86 Sd.dblSG = (Wall.tra - Sd.PVwall.Eff) * (Glsc*Idre + Cidf*Idf) 87 if Sd.mw.wall.ColType[:2] == "A3" { 88 Sd.Tcoled += Sd.dblSG / Sd.dblKsd 89 } 90 91 Sd.Tcoleu = Sd.dblSG/Ksu - Wall.Eo*RN/alo + Wd.T 92 93 //return Wall.ku*(Sd.Scol/Wall.Ksu+Wd.T) + Wall.kd*Sd.oldTx 94 95 //fmt.Printf("name=%s ku=%.2f kd=%.2f Tcoleu=%.2f Tcoled=%.2f\n", Sd.name, ku, kd, Sd.Tcoleu, Sd.Tcoled) 96 return ku*Sd.Tcoleu + kd*Sd.Tcoled 97 } else { 98 return 0 99 } 100 } 101 102 // 建材一体型空気集熱パネルの境界条件計算 103 func FNBoundarySolarWall(Sd *RMSRF, ECG, ECt, CFc *float64) { 104 Wall := Sd.mw.wall 105 Pnl := Sd.rpnl 106 107 // 戻り値の初期化 108 *ECG = 0.0 109 110 // 各種熱貫流率の設定 111 var Kc, Kcd, ku, kd float64 112 if Wall.chrRinput { 113 Kc = Sd.dblKc 114 //Kcu = Sd.dblKcu 115 Kcd = Sd.dblKcd 116 ku = Sd.ku 117 kd = Sd.kd 118 } else { 119 Kc = Wall.Kc 120 //Kcu = Wall.Kcu 121 Kcd = Wall.Kcd 122 ku = Wall.ku 123 kd = Wall.kd 124 } 125 126 // パネル動作時 127 if Pnl.cG > 0.0 { 128 *ECG = Pnl.cG * Pnl.Ec / (Kc * Sd.A) 129 } 130 131 *ECt = Kcd * ((1.0-*ECG)*ku - 1.0) 132 *CFc = Kcd * (1.0 - *ECG) * kd 133 } 134 135 // 熱媒平均温度の計算 136 func FNTf(Tcin, Tcole, ECG float64) float64 { 137 return (1.0-ECG)*Tcole + ECG*Tcin 138 } 139 140 // 外表面の総合熱伝達率の計算 141 func FNSolarWallao(Wd *WDAT, Sd *RMSRF, Exsfs *EXSFS) float64 { 142 var dblac, dblar, dblao float64 143 var Exs *EXSF 144 var dblWdre float64 145 var dblWa float64 146 var dblu float64 147 148 // 放射熱伝達率 149 // 屋根の表面温度は外気温度で代用 150 dblar = Sd.Eo * 4.0 * Sgm * math.Pow((Wd.T+Sd.Tg)/2.0+273.15, 3.0) 151 152 // 対流熱伝達率 153 Exs = Exsfs.Exs[Sd.exs] 154 155 // 外部風向の計算(南面0゜に換算) 156 dblWdre = Wd.Wdre*22.5 - 180.0 157 // 外表面と風向のなす角 158 dblWa = float64(Exs.Wa) - dblWdre 159 160 // 風上の場合 161 if math.Cos(dblWa*math.Pi/180.0) > 0.0 { 162 if Wd.Wv <= 2.0 { 163 dblu = 2.0 164 } else { 165 dblu = 0.25 * Wd.Wv 166 } 167 } else { 168 dblu = 0.3 + 0.05*Wd.Wv 169 } 170 171 // 対流熱伝達率 172 dblac = 3.5 + 5.6*dblu 173 174 // 総合熱伝達率 175 dblao = dblar + dblac 176 177 return dblao 178 } 179 180 // 通気層の放射熱伝達率の計算 181 func VentAirLayerar(dblEsu, dblEsd, dblTsu, dblTsd float64) float64 { 182 var dblEs float64 183 184 // 放射率の計算 185 dblEs = 1.0 / (1.0/dblEsu + 1.0/dblEsd - 1.0) 186 187 return 4.0 * dblEs * Sgm * math.Pow((dblTsu+dblTsd)/2.0+273.15, 3.0) 188 } 189 190 // 通気層の強制対流熱伝達率(ユルゲスの式) 191 func FNJurgesac(Sd *RMSRF, dblV, a, b float64) float64 { 192 var Dh, Nu, Re, lam float64 193 194 //if(fabs(dblV) <= 1.0e-3) 195 // dblTemp = 3.0 ; 196 //else if(dblV <= 5.0) 197 // dblTemp = 7.1 * pow(dblV, 0.78) ; 198 //else 199 // dblTemp = 5.8 + 3.9 * dblV ; 200 201 // 長方形断面の相当直径の計算 202 Dh = 1.232 * (a * b) / (a + b) 203 // レイノルズ数の計算 204 Re = dblV * Dh / FNanew(Sd.dblTf) 205 // 空気の熱伝導率 206 lam = FNalam(Sd.dblTf) 207 // ヌセルト数の計算 208 Nu = 0.0158 * math.Pow(Re, 0.8) 209 return Nu / Dh * lam 210 } 211 212 // 屋根一体型空気集熱器の熱伝達率、熱貫流率の計算 213 func FNKc(Wd *WDAT, Exsfs *EXSFS, Sd *RMSRF) { 214 var dblDet, dblWsuWsd, Ru, Cr, Cc float64 215 //g := 9.81 // Assuming the value of gravity 216 M_rad := math.Pi / 180.0 217 218 Wall := Sd.mw.wall 219 Exs := Exsfs.Exs[Sd.exs] 220 rad := M_rad 221 222 // 外表面の総合熱伝達率の計算 223 Sd.dblao = FNSolarWallao(Wd, Sd, Exsfs) 224 225 // 通気層の対流熱伝達率の計算 226 if Wall.air_layer_t < 0.0 { 227 fmt.Printf("%s Ventilation layer thickness is undefined\n", Sd.Name) 228 } 229 if Sd.rpnl.cmp.Elouts[0].G > 0.0 { 230 Sd.dblacc = FNJurgesac(Sd, Sd.rpnl.cmp.Elouts[0].G/Roa/((Sd.dblWsd+Sd.dblWsu)/2.0*Wall.air_layer_t), 231 (Sd.dblWsd+Sd.dblWsu)/2.0, Wall.air_layer_t) 232 } else { 233 Sd.dblacc = FNVentAirLayerac(Sd.dblTsu, Sd.dblTsd, Wall.air_layer_t, Exs.Wb*rad) 234 } 235 236 if math.Abs(Sd.dblacc) > 100.0 || Sd.dblacc < 0.0 { 237 fmt.Printf("xxxxxx <FNKc> name=%s acc=%f\n", Sd.Name, Sd.dblacc) 238 } 239 240 // 通気層の放射熱伝達率の計算 241 Sd.dblacr = VentAirLayerar(Wall.dblEsu, Wall.dblEsd, Sd.dblTsu, Sd.dblTsd) 242 243 if math.Abs(Sd.dblacr) > 100.0 || Sd.dblacr < 0.0 { 244 fmt.Printf("xxxxxx <FNKc> name=%s acr=%f\n", Sd.Name, Sd.dblacr) 245 } 246 247 // 通気層上面、下面から境界までの熱貫流率の計算 248 if Wall.Ru >= 0.0 { 249 Ru = Wall.Ru 250 } else { 251 // 空気層のコンダクタンスの計算 252 // 放射成分 253 Cr = VentAirLayerar(Wall.Eg, Wall.Eb, Sd.Tg, Sd.dblTsu) 254 // 対流成分 component 255 Cc = FNVentAirLayerac(Sd.Tg, Sd.dblTsu, Wall.ta, Exs.Wb*rad) 256 Ru = 1.0 / (Cc + Cr) 257 Sd.ras = Ru 258 } 259 260 Sd.dblKsu = 1.0 / (Ru + 1.0/Sd.dblao) 261 Sd.dblKsd = 1.0 / Wall.Rd 262 263 dblWsuWsd = Sd.dblWsu / Sd.dblWsd 264 265 dblDet = (Sd.dblacr*dblWsuWsd+Sd.dblacc+Sd.dblKsd)*(Sd.dblacr+Sd.dblacc+Sd.dblKsu) - Sd.dblacr*Sd.dblacr*dblWsuWsd 266 Sd.dblb11 = (Sd.dblacr + Sd.dblacc + Sd.dblKsu) / dblDet 267 Sd.dblb12 = Sd.dblacr / dblDet 268 Sd.dblb21 = Sd.dblacr * dblWsuWsd / dblDet 269 Sd.dblb22 = (Sd.dblacr*dblWsuWsd + Sd.dblacc + Sd.dblKsd) / dblDet 270 271 Sd.dblfcu = Sd.dblacc/dblWsuWsd*Sd.dblb12 + Sd.dblacc*dblWsuWsd*Sd.dblb22 272 Sd.dblfcd = Sd.dblacc/dblWsuWsd*Sd.dblb11 + Sd.dblacc*dblWsuWsd*Sd.dblb21 273 274 Sd.dblKcu = Sd.dblKsu * Sd.dblfcu 275 Sd.dblKcd = Sd.dblKsd * Sd.dblfcd 276 277 // 集熱器の総合熱貫流率の計算 278 Sd.dblKc = Sd.dblKcu + Sd.dblKcd 279 280 Sd.ku = Sd.dblKcu / Sd.dblKc 281 Sd.kd = Sd.dblKcd / Sd.dblKc 282 } 283 284 // 空気集熱器の通気層上面、下面表面温度の計算 285 func FNTsuTsd(Sd *RMSRF, Wd *WDAT, Exsfs *EXSFS) { 286 //var dblTf float64 // 集熱空気の平均温度 287 Rdpnl := Sd.rpnl 288 Wall := Sd.mw.wall 289 Exs := Exsfs.Exs[Sd.exs] 290 cG := Sd.rpnl.cG 291 292 if Wall.chrRinput { 293 Kc := Sd.dblKc 294 Ksu := Sd.dblKsu 295 Ksd := Sd.dblKsd 296 ECG := cG * Rdpnl.Ec / (Kc * Sd.A) 297 Sd.dblTf = (1.0-ECG)*Sd.Tcole + ECG*Rdpnl.Tpi 298 Sd.dblTsd = Sd.dblb11*Ksd*(Sd.Tcoled-Sd.dblTf) + Sd.dblb12*Ksu*(Sd.Tcoleu-Sd.dblTf) + Sd.dblTf 299 Sd.dblTsu = Sd.dblb21*Ksd*(Sd.Tcoled-Sd.dblTf) + Sd.dblb22*Ksu*(Sd.Tcoleu-Sd.dblTf) + Sd.dblTf 300 301 if Sd.dblTsd < -100 { 302 fmt.Println("Error") 303 } 304 305 // 空気層の熱抵抗が未定義の場合はガラスの温度を計算する 306 if Wall.Ru < 0.0 { 307 Sd.Tg = (Sd.dblao*Wd.T + 1.0/Sd.ras*Sd.dblTsu + Wall.ag*Exs.Iw - Wall.Eo*Exs.Fs*Wd.RN) / (Sd.dblao + 1.0/Sd.ras) 308 } 309 } 310 } 311 312 // 通気層の集熱停止時の熱コンダクタンス[W/m2K] 313 func FNVentAirLayerac(Tsu, Tsd, air_layer_t, Wb float64) float64 { 314 var Tas, Ra, anew, a, RacosWb, lama float64 315 g := 9.81 // Assuming the value of gravity 316 317 var Tsud float64 318 if math.Abs(Tsu-Tsd) < 1.0e-4 { 319 Tsud = Tsu + 0.1 320 } else { 321 Tsud = Tsu 322 } 323 324 // 通気層の温度 325 Tas = (Tsud + Tsd) / 2.0 326 // 空気の動粘性係数 327 anew = FNanew(Tas) 328 // 空気の熱拡散率 329 a = FNaa(Tas) 330 // 空気の熱伝導率 331 lama = FNalam(Tas) 332 // レーリー数 333 Ra = g * (1.0 / Tas) * math.Abs(Tsud-Tsd) * math.Pow(air_layer_t, 3.0) / (anew * a) 334 335 RacosWb = Ra * math.Cos(Wb) 336 337 dblTemp := (1.0 + 1.44*math.Max(0.0, 1.0-1708.0/RacosWb)*(1.0-math.Pow(math.Sin(1.8*Wb), 1.6)*1708.0/RacosWb) + math.Max(math.Pow(RacosWb/5830.0, 1.0/3.0)-1.0, 0.0)) * air_layer_t / lama 338 339 return dblTemp 340 }