github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/mcpv.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 /* solrcol.c */ 17 18 package eeslism 19 20 /* 太陽光発電システム 21 22 機器仕様入力 */ 23 24 import ( 25 "fmt" 26 "io" 27 "math" 28 "strconv" 29 "strings" 30 ) 31 32 func PVcadata(s string, PVca *PVCA) int { 33 dt := 0.0 34 id := 0 35 36 var st int 37 if st = strings.IndexRune(s, '='); st == -1 { 38 PVca.Name = s 39 PVca.PVcap = -999.0 40 PVca.Area = -999.0 41 PVca.KHD = 1.0 42 PVca.KPD = 0.95 43 PVca.KPM = 0.94 44 PVca.KPA = 0.97 45 PVca.effINO = 0.9 46 PVca.A = -999.0 47 PVca.B = -999.0 48 PVca.apmax = -0.41 49 } else { 50 s1 := s[:st] 51 s2 := s[st+1:] 52 53 var err error 54 dt, err = strconv.ParseFloat(s2, 64) 55 if err != nil { 56 panic(err) 57 } 58 59 switch { 60 case strings.HasPrefix(s1, "KHD"): 61 // 日射量年変動補正係数 62 PVca.KHD = dt 63 case strings.HasPrefix(s1, "KPD"): 64 // 経時変化補正係数 65 PVca.KPD = dt 66 case strings.HasPrefix(s1, "KPM"): 67 // アレイ負荷整合補正係数 68 PVca.KPM = dt 69 case strings.HasPrefix(s1, "KPA"): 70 // アレイ回路補正係数 71 PVca.KPA = dt 72 case strings.HasPrefix(s1, "EffInv"): 73 // インバータ実行効率 74 PVca.effINO = dt 75 case strings.HasPrefix(s1, "apmax"): 76 // 最大出力温度係数 77 PVca.apmax = dt 78 case s1 == "InstallType": 79 PVca.InstallType = rune(s2[0]) 80 switch PVca.InstallType { 81 case 'A': 82 PVca.A = 46.0 83 PVca.B = 0.41 84 case 'B': 85 PVca.A = 50.0 86 PVca.B = 0.38 87 case 'C': 88 PVca.A = 57.0 89 PVca.B = 0.33 90 } 91 case strings.HasPrefix(s1, "PVcap"): 92 // 太陽電池容量 93 PVca.PVcap = dt 94 case strings.HasPrefix(s1, "Area"): 95 // 太陽電池容量 96 PVca.Area = dt 97 default: 98 id = 1 99 } 100 } 101 return id 102 } 103 104 /* ------------------------------------- */ 105 106 /* 初期設定 */ 107 108 func PVint(PV []*PV, Exs []*EXSF, Wd *WDAT) { 109 Err := "" 110 111 for i := range PV { 112 PV[i].Ta = &Wd.T 113 PV[i].V = &Wd.Wv 114 115 for _, exs := range Exs { 116 if PV[i].Cmp.Exsname == exs.Name { 117 PV[i].Sol = exs 118 PV[i].I = &PV[i].Sol.Iw 119 break 120 } 121 } 122 123 if PV[i].Sol == nil { 124 Eprint("PVint", PV[i].Cmp.Exsname) 125 } 126 127 if PV[i].Cat.KHD < 0.0 { 128 Err = fmt.Sprintf("Name=%s KHD=%.4g", PV[i].Cmp.Name, PV[i].Cat.KHD) 129 Eprint("PVint", Err) 130 } 131 132 if PV[i].Cat.KPD < 0.0 { 133 Err = fmt.Sprintf("Name=%s KHD=%.4g", PV[i].Cmp.Name, PV[i].Cat.KPD) 134 Eprint("PVint", Err) 135 } 136 137 if PV[i].Cat.KPM < 0.0 { 138 Err = fmt.Sprintf("Name=%s KPM=%.4g", PV[i].Cmp.Name, PV[i].Cat.KPM) 139 Eprint("PVint", Err) 140 } 141 142 if PV[i].Cat.KPA < 0.0 { 143 Err = fmt.Sprintf("Name=%s KPA=%.4g", PV[i].Cmp.Name, PV[i].Cat.KPA) 144 Eprint("PVint", Err) 145 } 146 147 if PV[i].Cat.effINO < 0.0 { 148 Err = fmt.Sprintf("Name=%s EffInv=%.4g", PV[i].Cmp.Name, PV[i].Cat.effINO) 149 Eprint("PVint", Err) 150 } 151 152 if PV[i].Cat.apmax > 0.0 { 153 Err = fmt.Sprintf("Name=%s apmax=%.4g", PV[i].Cmp.Name, PV[i].Cat.apmax) 154 Eprint("PVint", Err) 155 } 156 157 if PV[i].PVcap < 0.0 { 158 Err = fmt.Sprintf("Name=%s PVcap=%.4g", PV[i].Cmp.Name, PV[i].PVcap) 159 Eprint("PVint", Err) 160 } 161 162 if PV[i].Area < 0.0 { 163 Err = fmt.Sprintf("Name=%s Area=%.4g", PV[i].Cmp.Name, PV[i].Area) 164 Eprint("PVint", Err) 165 } 166 167 // 計算途中で変化しない各種補正係数の積 168 PV[i].KConst = PV[i].Cat.KHD * PV[i].Cat.KPD * PV[i].Cat.KPM * PV[i].Cat.KPA * PV[i].Cat.effINO 169 } 170 } 171 172 // 太陽光発電の発電量計算 173 /* ------------------------------------- */ 174 175 /* 集熱量の計算 */ 176 177 func PVene(PV []*PV) { 178 for i := range PV { 179 // 太陽電池アレイの計算(JIS C 8907:2005 P21による) 180 PV[i].TPV = *PV[i].Ta + (PV[i].Cat.A/(PV[i].Cat.B*math.Pow(*PV[i].V, 0.8)+1.0)+2.0)**PV[i].I/1000.0 - 2.0 181 PV[i].KPT = FNKPT(PV[i].TPV, PV[i].Cat.apmax) 182 PV[i].KTotal = PV[i].KConst * PV[i].KPT 183 184 // 太陽電池入社日射量の計算 185 PV[i].Iarea = *PV[i].I * PV[i].Area 186 187 // 発電量の計算 188 PV[i].Power = PV[i].KTotal * *PV[i].I / 1000.0 * PV[i].PVcap 189 190 // 発電効率の計算 191 PV[i].Eff = 0.0 192 if PV[i].Iarea > 0.0 { 193 PV[i].Eff = PV[i].Power / PV[i].Iarea 194 } 195 } 196 } 197 198 /* ------------------------------------------------------------- */ 199 200 func PVprint(fo io.Writer, id int, PV []*PV) { 201 switch id { 202 case 0: 203 if len(PV) > 0 { 204 fmt.Fprintf(fo, "%s %d\n", PV_TYPE, len(PV)) 205 } 206 for i := range PV { 207 fmt.Fprintf(fo, " %s 1 4\n", PV[i].Name) 208 } 209 break 210 211 case 1: 212 for i := range PV { 213 fmt.Fprintf(fo, " %s_TPV t f %s_I e f %s_P e f %s_Eff r f \n", 214 PV[i].Name, PV[i].Name, PV[i].Name, PV[i].Name) 215 } 216 break 217 218 default: 219 for i := range PV { 220 fmt.Fprintf(fo, " %4.1f %4.0f %3.0f %.3f\n", 221 PV[i].TPV, PV[i].Iarea, PV[i].Power, PV[i].Eff) 222 } 223 break 224 } 225 } 226 227 /* --------------------------- */ 228 229 /* 日積算値に関する処理 */ 230 231 func PVdyint(PV []*PV) { 232 for i := range PV { 233 qdyint(&PV[i].Edy) 234 edyint(&PV[i].Soldy) 235 } 236 } 237 238 func PVmonint(PV []*PV) { 239 for i := range PV { 240 qdyint(&PV[i].mEdy) 241 edyint(&PV[i].mSoldy) 242 } 243 } 244 245 func PVday(Mon int, Day int, ttmm int, PV []*PV, Nday int, SimDayend int) { 246 Mo := Mon - 1 247 tt := ConvertHour(ttmm) 248 249 for i := range PV { 250 var sw ControlSWType 251 if PV[i].Power > 0.0 { 252 sw = ON_SW 253 } else { 254 sw = OFF_SW 255 } 256 257 // 日間集計 258 qdaysum(int64(ttmm), sw, PV[i].Power, &PV[i].Edy) 259 260 if *PV[i].I > 0.0 { 261 sw = ON_SW 262 } else { 263 sw = OFF_SW 264 } 265 // 時間集計 266 edaysum(ttmm, sw, *PV[i].I, &PV[i].Soldy) 267 268 // 月間集計 269 sw = OFF_SW 270 if PV[i].Power > 0.0 { 271 sw = ON_SW 272 } 273 qmonsum(Mon, Day, ttmm, sw, PV[i].Power, &PV[i].mEdy, Nday, SimDayend) 274 275 if *PV[i].I > 0.0 { 276 sw = ON_SW 277 } else { 278 sw = OFF_SW 279 } 280 // 時間集計 281 emonsum(Mon, Day, ttmm, sw, *PV[i].I, &PV[i].mSoldy, Nday, SimDayend) 282 283 // 月・時刻のクロス集計 284 emtsum(Mon, Day, ttmm, sw, PV[i].Power, &PV[i].mtEdy[Mo][tt]) 285 } 286 } 287 288 func PVdyprt(fo io.Writer, id int, PV []*PV) { 289 switch id { 290 case 0: 291 if len(PV) > 0 { 292 fmt.Fprintf(fo, "%s %d\n", PV_TYPE, len(PV)) 293 } 294 for i := range PV { 295 fmt.Fprintf(fo, " %s 1 8\n", PV[i].Name) 296 } 297 case 1: 298 for i := range PV { 299 fmt.Fprintf(fo, "%s_Hh H d %s_E E f\n", PV[i].Name, PV[i].Name) 300 fmt.Fprintf(fo, "%s_th h d %s_Em e f\n", PV[i].Name, PV[i].Name) 301 fmt.Fprintf(fo, "%s_He H d %s_S E f %s_te h d %s_Sm e f\n\n", PV[i].Name, PV[i].Name, PV[i].Name, PV[i].Name) 302 } 303 default: 304 for i := range PV { 305 fmt.Fprintf(fo, "%1d %3.1f ", PV[i].Edy.Hhr, PV[i].Edy.H) 306 fmt.Fprintf(fo, "%1d %2.0f\n", PV[i].Edy.Hmxtime, PV[i].Edy.Hmx) 307 308 fmt.Fprintf(fo, "%1d %3.1f ", PV[i].Soldy.Hrs, PV[i].Soldy.D) 309 fmt.Fprintf(fo, "%1d %2.0f\n", PV[i].Soldy.Mxtime, PV[i].Soldy.Mx) 310 } 311 } 312 } 313 314 func PVmonprt(fo io.Writer, id int, PV []*PV) { 315 switch id { 316 case 0: 317 if len(PV) > 0 { 318 fmt.Fprintf(fo, "%s %d\n", PV_TYPE, len(PV)) 319 } 320 for i := range PV { 321 fmt.Fprintf(fo, " %s 1 8\n", PV[i].Name) 322 } 323 case 1: 324 for i := range PV { 325 fmt.Fprintf(fo, "%s_Hh H d %s_E E f\n", PV[i].Name, PV[i].Name) 326 fmt.Fprintf(fo, "%s_th h d %s_Em e f\n", PV[i].Name, PV[i].Name) 327 fmt.Fprintf(fo, "%s_He H d %s_S E f %s_te h d %s_Sm e f\n\n", PV[i].Name, PV[i].Name, PV[i].Name, PV[i].Name) 328 } 329 default: 330 for i := range PV { 331 fmt.Fprintf(fo, "%1d %3.1f ", PV[i].mEdy.Hhr, PV[i].mEdy.H) 332 fmt.Fprintf(fo, "%1d %2.0f\n", PV[i].mEdy.Hmxtime, PV[i].mEdy.Hmx) 333 334 fmt.Fprintf(fo, "%1d %3.1f ", PV[i].mSoldy.Hrs, PV[i].mSoldy.D) 335 fmt.Fprintf(fo, "%1d %2.0f\n", PV[i].mSoldy.Mxtime, PV[i].mSoldy.Mx) 336 } 337 } 338 } 339 340 func PVmtprt(fo io.Writer, id int, PV []*PV, Mo int, tt int) { 341 switch id { 342 case 0: 343 if len(PV) > 0 { 344 fmt.Fprintf(fo, "%s %d\n", PV_TYPE, len(PV)) 345 } 346 for i := range PV { 347 fmt.Fprintf(fo, " %s 1 1\n", PV[i].Name) 348 } 349 case 1: 350 for i := range PV { 351 fmt.Fprintf(fo, "%s_E E f\n", PV[i].Name) 352 } 353 default: 354 for i := range PV { 355 fmt.Fprintf(fo, " %.2f\n", PV[i].mtEdy[Mo-1][tt-1].D*Cff_kWh) 356 } 357 } 358 }