/// <summary>直散分離を行い、法線面直達日射量と水平面全天日射量を推定する</summary> /// <param name="method">直散分離の手法</param> /// <param name="globalHorizontalRadiation">水平面全天日射量[W/m2]</param> public void EstimateDiffuseAndDirectNormalRadiation(double globalHorizontalRadiation, DiffuseAndDirectNormalRadiationEstimatingMethod method) { this.GlobalHorizontalRadiation = globalHorizontalRadiation; EstimateDiffuseAndDirectNormalRadiation(globalHorizontalRadiation, this.Latitude, this.Longitude, this.StandardLongitude, this.CurrentDateTime, method, out this.directNormalRadiation, out this.diffuseHorizontalRadiation); }
/// <summary>水平面全天日射量[W/m2]をもとに直散分離を行う</summary> /// <param name="globalHorizontalRadiation">水平面全天日射量[W/m2]</param> /// <param name="latitude">緯度[degree]</param> /// <param name="xlongitude">計算地点の経度[degree]</param> /// <param name="sLongitude">標準時を規定する地点の経度(東経で正)[degree]</param> /// <param name="dTime">日時</param> /// <param name="method">直散分離の手法</param> /// <param name="directSolarRadiation">法線面直達日射量[W/m2]</param> /// <param name="diffuseHorizontalRadiation">天空日射[W/m2]</param> public static void EstimateDiffuseAndDirectNormalRadiation( double globalHorizontalRadiation, double latitude, double xlongitude, double sLongitude, DateTime dTime, DiffuseAndDirectNormalRadiationEstimatingMethod method, out double directSolarRadiation, out double diffuseHorizontalRadiation) { estimateDiffuseAndDirectNormalRadiation(globalHorizontalRadiation, latitude, xlongitude, sLongitude, dTime, method, out directSolarRadiation, out diffuseHorizontalRadiation); }
/// <summary>水平面全天日射量[W/m2]をもとに直散分離を行う</summary> /// <param name="globalHorizontalRadiation">水平面全天日射量[W/m2]</param> /// <param name="latitude">緯度[degree]</param> /// <param name="xlongitude">計算地点の経度[degree]</param> /// <param name="sLongitude">標準時を規定する地点の経度(東経で正)[degree]</param> /// <param name="dTime">日時</param> /// <param name="directSolarRadiation">法線面直達日射量[W/m2]</param> /// <param name="method">直散分離の手法</param> /// <param name="diffuseHorizontalRadiation">天空日射[W/m2]</param> private static void estimateDiffuseAndDirectNormalRadiation( double globalHorizontalRadiation, double latitude, double xlongitude, double sLongitude, DateTime dTime, DiffuseAndDirectNormalRadiationEstimatingMethod method, out double directSolarRadiation, out double diffuseHorizontalRadiation) { directSolarRadiation = diffuseHorizontalRadiation = 0; double io = GetExtraterrestrialRadiation(dTime.DayOfYear); double sinH = Math.Sin(Sun.GetSunAltitude(latitude, xlongitude, sLongitude, dTime)); if (sinH <= 0.001) return; //宇田川の手法 if (method == DiffuseAndDirectNormalRadiationEstimatingMethod.Udatgawa) { double ktc = 0.5163 + 0.333 * sinH + 0.00803 * sinH * sinH; double ktt = Math.Min(1, globalHorizontalRadiation / (io * sinH)); if (ktc <= ktt) directSolarRadiation = (-0.43 + 1.43 * ktt) * io; else directSolarRadiation = (2.277 - 1.258 * sinH + 0.2396 * sinH * sinH) * Math.Pow(ktt, 3) * io; directSolarRadiation = Math.Min(directSolarRadiation, globalHorizontalRadiation / sinH); diffuseHorizontalRadiation = globalHorizontalRadiation - directSolarRadiation * sinH; } //三木の手法 else if (method == DiffuseAndDirectNormalRadiationEstimatingMethod.Miki) { double lkt = Math.Min(1, globalHorizontalRadiation / (io * sinH)); double skt = (lkt - 0.15 - 0.2 * sinH) / 0.6; double skd; if (skt <= 0) skd = 0; else skd = 3 * skt * skt - 2 * skt * skt * skt; double lkd = Math.Min(skd * lkt, Math.Pow(0.8, (7 + sinH) / (1 + 7 * sinH))); double lks = Math.Max(lkt - lkd, 0.005); directSolarRadiation = lkd * io; directSolarRadiation = Math.Min(directSolarRadiation, globalHorizontalRadiation / sinH); diffuseHorizontalRadiation = globalHorizontalRadiation - directSolarRadiation * sinH; } //数値計算による方法 else { double atmTrans = estimateAtmosphericTransmissivity(sinH, io, globalHorizontalRadiation, method); estimateRadiationFromAtmosphericTransmissivity(atmTrans, sinH, io, method, out directSolarRadiation, out diffuseHorizontalRadiation); } //0以上とする directSolarRadiation = Math.Max(0, directSolarRadiation); diffuseHorizontalRadiation = Math.Max(0, diffuseHorizontalRadiation); }
/// <summary>日射に関する大気透過率[-]に基づいて法線面直達日射[W/m2]と水平面天空日射[W/m2]を推定する</summary> /// <param name="atmosphericTransmissivity">日射に関する大気透過率[-]</param> /// <param name="sinH">太陽高度の正弦</param> /// <param name="extraterrestrialRadiation">大気圏外日射[W/m2]</param> /// <param name="method">推定手法</param> /// <param name="directNormalRadiation">法線面直達日射[W/m2]</param> /// <param name="diffuseHorizontalRadiation">水平面天空日射[W/m2]</param> private static void estimateRadiationFromAtmosphericTransmissivity(double atmosphericTransmissivity, double sinH, double extraterrestrialRadiation, DiffuseAndDirectNormalRadiationEstimatingMethod method, out double directNormalRadiation, out double diffuseHorizontalRadiation) { double pcosech = Math.Pow(atmosphericTransmissivity, 1 / sinH); directNormalRadiation = extraterrestrialRadiation * Math.Pow(atmosphericTransmissivity, 1 / sinH); diffuseHorizontalRadiation = 0; switch (method) { case DiffuseAndDirectNormalRadiationEstimatingMethod.Akasaka: //赤坂の手法 diffuseHorizontalRadiation = sinH * extraterrestrialRadiation * (1 - pcosech) * 0.95 * Math.Pow(atmosphericTransmissivity, 1 / (0.5 + 2.5 * sinH)) * Math.Pow(1 - atmosphericTransmissivity, 2d / 3d); break; case DiffuseAndDirectNormalRadiationEstimatingMethod.Berlage: //Berlageの手法 diffuseHorizontalRadiation = sinH * extraterrestrialRadiation * (1 - pcosech) * 0.5 / (1 - 1.4 * Math.Log(atmosphericTransmissivity)); break; case DiffuseAndDirectNormalRadiationEstimatingMethod.LiuAndJordan: //Liu&Jordanの方法 diffuseHorizontalRadiation = sinH * extraterrestrialRadiation * (0.271 - 0.2939 * pcosech); break; case DiffuseAndDirectNormalRadiationEstimatingMethod.Matsuo: //松尾の手法 diffuseHorizontalRadiation = sinH * extraterrestrialRadiation * (1 - pcosech) * (1 - atmosphericTransmissivity) * 1.2 / (1 - 1.4 * Math.Log(atmosphericTransmissivity)); break; case DiffuseAndDirectNormalRadiationEstimatingMethod.Nagata: //永田の手法 diffuseHorizontalRadiation = sinH * extraterrestrialRadiation * (1 - pcosech) * (0.66 - 0.32 * sinH) * (0.5 + (0.4 - 0.3 * atmosphericTransmissivity) * sinH); break; case DiffuseAndDirectNormalRadiationEstimatingMethod.Watanabe: //渡辺の手法 double qq = (0.9013 + 1.123 * sinH) * Math.Pow(atmosphericTransmissivity, 0.489 / sinH) * Math.Pow(1 - pcosech, 2.525); diffuseHorizontalRadiation = sinH * extraterrestrialRadiation * qq / (1 + qq); break; } }
/// <summary>水平面天空日射[W/m2]に基づいて大気透過率[-]を推定する</summary> /// <param name="sinH">太陽高度の正弦</param> /// <param name="extraterrestrialRadiation">大気圏外日射[W/m2]</param> /// <param name="globalHorizontalRadiation">水平面天空日射[W/m2]</param> /// <param name="method">推定手法</param> /// <returns>大気透過率[-]</returns> private static double estimateAtmosphericTransmissivity(double sinH, double extraterrestrialRadiation, double globalHorizontalRadiation, DiffuseAndDirectNormalRadiationEstimatingMethod method) { //入力異常判定 if (sinH <= 0) return 0; if (extraterrestrialRadiation < globalHorizontalRadiation) return 0; if (globalHorizontalRadiation <= 0) return 0; //初期値 double atmTrans = 1; //収束計算実行; int iterNum = 0; const int MAX_ITER = 20; const double DELTA = 0.0001; const double ERR_TOL = 0.001; double dn, dff; double err1, err2; estimateRadiationFromAtmosphericTransmissivity(atmTrans, sinH, extraterrestrialRadiation, method, out dn, out dff); err1 = globalHorizontalRadiation - (dn * sinH + dff); while (true) { estimateRadiationFromAtmosphericTransmissivity(atmTrans - DELTA, sinH, extraterrestrialRadiation, method, out dn, out dff); err2 = globalHorizontalRadiation - (dn * sinH + dff); atmTrans -= err2 * DELTA / (err1 - err2); estimateRadiationFromAtmosphericTransmissivity(atmTrans, sinH, extraterrestrialRadiation, method, out dn, out dff); err1 = globalHorizontalRadiation - (dn * sinH + dff); if (Math.Abs(err2) < ERR_TOL) break; iterNum++; if (MAX_ITER < iterNum) break; } return atmTrans; }