github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/eebslib.go (about) 1 package eeslism 2 3 import ( 4 "fmt" 5 "math" 6 "os" 7 "strings" 8 ) 9 10 // 外表面方位デ-タの入力 11 func Exsfdata(section *EeTokens, dsn string, Exsf *EXSFS, Schdl *SCHDL, Simc *SIMCONTL) { 12 var ename string 13 //var st *string 14 var dt, wa, wb, swa, cwa, swb, cwb float64 15 var k int 16 var err error 17 18 // 外表面総合伝達率のデフォルト値 19 Exsf.Alosch = envptr(fmt.Sprintf("%f", ALO), Simc, nil, nil, nil) 20 Exsf.Alotype = Alotype_Fix // 固定値 21 Exsf.Exs = make([]*EXSF, 0) 22 23 var dfrg float64 // 全面地物の日射反射率(デフォルト値) 24 25 // 最初の行: 全体に対する設定 26 line := section.GetLogicalLine() 27 for _, s := range line { 28 if strings.HasPrefix(s, "alo=") { 29 // 外表面総合伝達率[W/m2K] 30 // 31 value := s[4:] 32 if value == "Calc" { 33 // 風速から計算する 34 Exsf.Alotype = Alotype_V 35 } else if k, err = idsch(value, Schdl.Sch, ""); err == nil { 36 // スケジュールに基づいて値を変化させる 37 Exsf.Alosch = &Schdl.Val[k] 38 Exsf.Alotype = Alotype_Schedule 39 } else { 40 // 数値 or 内部変数名 41 Exsf.Alosch = envptr(value, Simc, nil, nil, nil) 42 if Exsf.Alosch != nil { 43 Exsf.Alotype = Alotype_Schedule 44 } 45 } 46 } else if strings.HasPrefix(s, "r=") { 47 // 全面地物の日射反射率[-] 48 // 49 value := s[2:] 50 dfrg, err = readFloat(value) 51 if err != nil || dfrg < 0.0 || dfrg > 1.0 { 52 fmt.Fprintf(os.Stderr, "%s の設置値が不適切です", s) 53 os.Exit(1) 54 } 55 } 56 } 57 58 for section.IsEnd() == false { 59 // 論理行を取得 60 line = section.GetLogicalLine() 61 62 // "*"が出てきたら終了 63 if line[0] == "*" { 64 break 65 } 66 67 // 外表面データの初期化 68 ex := new(EXSF) 69 Exsfinit(ex) 70 ex.Name = line[0] // 外表面名 71 ex.Alotype = Exsf.Alotype // 外表面総合伝達率の設定方法=デフォルト値 72 ex.Alo = Exsf.Alosch // 外表面総合伝達率=デフォルト値 73 74 // 特殊名 Hor, EarchSf への対応 75 if line[0] == "Hor" { 76 // 水平面なので、傾斜角は0 77 ex.Wb = 0.0 78 } else if line[0] == "EarthSf" { 79 // 地表面境界を含むことをフラグに書き込む 80 Exsf.EarthSrfFlg = true 81 82 // 種別: 地表面 83 ex.Typ = EXSFType_e 84 } else { 85 // 通常の表面の定義 86 ex.Wb = 90.0 // 傾斜角=90° 87 ex.Rg = dfrg // 日射反射率=デフォルト値 88 } 89 90 for _, s := range line[1:] { 91 st := strings.IndexRune(s, '=') 92 93 key := s[:st] 94 value := s[st+1:] 95 96 if key == "a" { 97 // *** 方位角 a*** 98 // 99 var err error 100 if dt, err = readFloat(value); err == nil { 101 // 数値指定 102 ex.Wa = dt 103 } else { 104 var dir rune = ' ' 105 if strings.Contains(s, "+") { 106 st := strings.IndexRune(s, '+') 107 dir = '+' 108 ename = s[2:st] 109 offvalue := s[st+1:] 110 dt, err = readFloat(offvalue) 111 if err != nil { 112 panic(err) 113 } 114 } else if strings.Contains(s, "-") { 115 st := strings.IndexRune(s, '-') 116 dir = '-' 117 ename = s[2:st] 118 offvalue := s[st+1:] 119 dt, err = readFloat(offvalue) 120 if err != nil { 121 panic(err) 122 } 123 } else { 124 ename = s[2:] 125 } 126 127 var found_flag = false 128 for _, exj := range Exsf.Exs { 129 if exj.Name == ename { 130 if dir == '+' { 131 ex.Wa = exj.Wa + dt 132 } else if dir == '-' { 133 ex.Wa = exj.Wa - dt 134 } else { 135 ex.Wa = exj.Wa 136 } 137 found_flag = true 138 break 139 } 140 } 141 if !found_flag { 142 Eprint("<Exsfdata>", s) 143 } 144 } 145 } else if key == "alo" { 146 // *** 外表面熱伝達率 alo *** 147 // 148 if value == "Calc" { 149 // 風速から計算 150 ex.Alotype = Alotype_V 151 } else { 152 // スケジュール 153 ex.Alotype = Alotype_Schedule 154 if k, err = idsch(value, Schdl.Sch, ""); err == nil { 155 ex.Alo = &Schdl.Val[k] 156 } else { 157 ex.Alo = envptr(value, Simc, nil, nil, nil) 158 } 159 } 160 } else { 161 // *** 傾斜角 t,日射反射率 r,地中深さ Z,土の熱拡散率 d *** 162 // 163 dt, err = readFloat(value) 164 if err != nil { 165 panic(s) 166 } 167 switch key { 168 case "t": 169 // 傾斜角[°] 170 ex.Wb = dt 171 case "r": 172 // 全面地物の日射反射率[-] 173 ex.Rg = dt 174 case "Z": 175 // 地中深さ [m] 176 ex.Z = dt 177 ex.Typ = EXSFType_E // 地下扱いにする 178 case "d": 179 // 土の熱拡散率 [m2/s] 180 ex.Erdff = dt 181 default: 182 Eprint("<Exsfdata>", s) 183 } 184 } 185 } 186 187 Exsf.Exs = append(Exsf.Exs, ex) 188 } 189 190 // 外表面熱伝達率の設定 191 // if len(Exsf.Exs) > 0 { 192 // s = strconv.FormatFloat(ALO, 'f', -1, 64) 193 // Exsf.Alosch = envptr(s, Simc, nil, nil, nil) 194 // Exsf.Alotype = Alotype_Fix // 固定値 195 // Exsf.Exs = exs 196 // } 197 198 for _, ex := range Exsf.Exs { 199 200 // 一般外表面 の場合は、日射に関するパラメータを計算する 201 if ex.Typ == EXSFType_S { 202 const rad = PI / 180. 203 wa = ex.Wa * rad // 方位角 [rad] 204 wb = ex.Wb * rad // 傾斜角 [rad] 205 cwa = math.Cos(wa) // 方位角の余弦 206 swa = math.Sin(wa) // 方位角の正弦 207 cwb = math.Cos(wb) // 傾斜角の余弦 208 swb = math.Sin(wb) // 傾斜角の正弦 209 ex.Cwa = cwa // = 方位角の余弦 210 ex.Swa = swa // = 方位角の正弦 211 ex.Swb = swb // = 傾斜角の正弦 212 ex.Wz = cwb // = 傾斜角の余弦 213 ex.Ww = swb * swa // = 傾斜角の正弦 × 方位角の正弦 214 ex.Ws = swb * cwa // = 傾斜角の正弦 × 方位角の余弦 215 ex.CbSa = cwb * swa // = 傾斜角の余弦 × 方位角の正弦 216 ex.CbCa = cwb * cwa // = 傾斜角の余弦 × 方位角の正弦 217 ex.Fs = 0.5 * (1.0 + cwb) // 天空を見る形態係数 218 } 219 } 220 } 221 222 /* 外表面入射日射量の計算 */ 223 func (exsf *EXSFS) Exsfsol(Wd *WDAT) { 224 for _, ex := range exsf.Exs { 225 226 if ex.Typ == EXSFType_S { 227 // 入射角のcos 228 cinc := Wd.Sh*ex.Wz + Wd.Sw*ex.Ww + Wd.Ss*ex.Ws 229 230 if cinc > 0.0 { 231 // 太陽が出ている場合 232 233 // プロファイル角の計算 234 ex.Tprof = (Wd.Sh*ex.Swb - Wd.Sw*ex.CbSa - Wd.Ss*ex.CbCa) / cinc 235 ex.Prof = math.Atan(ex.Tprof) 236 237 // 見かけの方位角の計算 238 ex.Tazm = (Wd.Sw*ex.Cwa - Wd.Ss*ex.Swa) / cinc 239 ex.Gamma = math.Atan(ex.Tazm) 240 ex.Cinc = cinc 241 } else { 242 // 太陽が出ていない場合 243 ex.Prof = 0.0 244 ex.Gamma = 0.0 245 ex.Cinc = 0.0 246 } 247 248 // 日射量の計算 249 ex.Idre = Wd.Idn * ex.Cinc // 直逹日射 [W/m2] 250 ex.Idf = Wd.Isky*ex.Fs + ex.Rg*Wd.Ihor*(1.0-ex.Fs) // 拡散日射 [W/m2] 251 ex.Iw = ex.Idre + ex.Idf // 全日射 [W/m2] 252 ex.Rn = Wd.RN * ex.Fs // 夜間輻射 [W/m2] 253 } 254 } 255 } 256 257 // ガラス日射熱取得の計算 258 // 入力: 259 // 面積 Ag [m2] 260 // 日射総合取得率 tgtn [-] 261 // 吸収日射取得率 Bn [-] 262 // 入射角のcos cinc [-] 263 // ********** Fsdw 264 // 直逹日射 Idr [W/m2] 265 // 拡散日射 Idf [W/m2] 266 // 出力: 267 // 透過日射熱取得 Qgt [W] 268 // 吸収日射熱取得 Qga [W] 269 func Glasstga(Ag, tgtn, Bn, cinc, Fsdw, Idr, Idf float64, Cidtype string, Profile, Gamma float64) (Qgt, Qga float64) { 270 var Cid, Cidf, Bid, Bidf float64 271 272 Cid = 0.0 273 Bid = 0.0 274 Cidf = 0.01 275 Bidf = 0.0 276 277 // 標準 278 if Cidtype == "N" { 279 Cid = Glscid(cinc) 280 Cidf = 0.91 281 282 Bid = Cid 283 Bidf = Cidf 284 } else { 285 fmt.Printf("xxxxx <eebslib.c CidType=%s\n", Cidtype) 286 } 287 288 // 透過日射量の計算 289 Qt := Ag * (Cid*Idr*(1.0-Fsdw) + Cidf*Idf) 290 291 // 吸収日射量の計算 292 Qb := Ag * (Bid*Idr*(1.0-Fsdw) + Bidf*Idf) 293 294 Qgt = Qt * tgtn 295 Qga = Qb * Bn 296 297 return Qgt, Qga 298 } 299 300 // ガラスの直達日射透過率標準特性 301 // 入力: 302 // 入射角のcos cinc [-] 303 // 出力: 304 // ガラスの直達日射透過率標準特性 Cid [-] 305 func Glscid(cinc float64) float64 { 306 return math.Max(0, cinc*(3.4167+cinc*(-4.389+cinc*(2.4948-0.5224*cinc)))) 307 } 308 309 // ガラスの直達日射透過率標準特性(普通複層ガラス用) 310 // 入力: 311 // 入射角のcos cinc [-] 312 // 出力: 313 // ガラスの直達日射透過率標準特性 Cid [-] 314 func GlscidDG(cinc float64) float64 { 315 return math.Max(0, cinc*(0.341819+cinc*(6.070709+cinc*(-9.899236+4.495774*cinc)))) 316 } 317 318 func ExsfCount(section *EeTokens) int { 319 var N int 320 for section.IsEnd() == false { 321 if section.GetToken() == ";" { 322 N++ 323 break 324 } 325 } 326 section.Reset() 327 return N 328 }