/// <summary>共通比Cを用いた応答係数を計算する</summary> /// <param name="timeStep">タイムステップ[sec]</param> /// <param name="filmCoefficient1">1側総合熱伝達率[W/m2K]</param> /// <param name="filmCoefficient2">2側総合熱伝達率[W/m2K]</param> /// <param name="wallLayers">壁層</param> /// <param name="rfNumber">応答係数の数</param> /// <param name="rFactorX">1側吸熱応答係数</param> /// <param name="rFactorY">貫流応答係数</param> /// <param name="rFactorZ">2側吸熱応答係数</param> /// <param name="commonRatio">共通比</param> public static void GetResponseFactor(double timeStep, double filmCoefficient1, double filmCoefficient2, WallLayers wallLayers, uint rfNumber, ref double[] rFactorX, ref double[] rFactorY, ref double[] rFactorZ, out double commonRatio) { const int G_NUMBER = 8; double[] beta = new double[G_NUMBER]; double[,] g_xyz = new double[3, G_NUMBER]; double[,] rf = new double[3, rfNumber]; double[] g_xyz_0 = new double[3]; //熱抵抗リストと熱容量リストを初期化 double[] res = new double[wallLayers.LayerNumber + 2]; double[] cap = new double[wallLayers.LayerNumber + 2]; res[0] = 1.0d / filmCoefficient1; res[res.Length - 1] = 1.0d / filmCoefficient2; for (uint i = 0; i < wallLayers.LayerNumber; i++) { WallLayers.Layer wl = wallLayers.GetLayer(i); res[i + 1] = wl.Resistance; cap[i + 1] = wl.HeatCapacityPerUnitArea; } for (int i = 0; i < G_NUMBER; i++) { uint iter = 0; //反復計算回数 double bm = 0; //初期値は0 //Beta(i)を収束計算 while (true) { //各壁層の行列Pを計算する for (uint j = 0; j < res.Length; j++) { double rCap = cap[j] * res[j]; double w = rCap * bm; if (0 < w) { w = Math.Sqrt(w); double cw = Math.Cos(w); double sw = Math.Sin(w); matPi[0, 0] = matPi[1, 1] = cw; matPi[0, 1] = res[j] * sw / w; matPi[1, 0] = -w * sw / res[j]; matPid[0, 0] = matPid[1, 1] = 0.5 * rCap * sw / w; matPid[0, 1] = 0.5 * res[j] * (sw / w - cw) / bm; matPid[1, 0] = 0.5 * cap[j] * (sw / w + cw); } else { matPi[0, 0] = 1.0; matPi[0, 1] = res[j]; matPi[1, 0] = 0.0; matPi[1, 1] = 1.0; if (cap[j] == 0) initMatrix(matPid, 0.0); else { matPid[0, 0] = matPid[1, 1] = 0.5 * rCap; matPid[0, 1] = res[j] * rCap / 6.0d; matPid[1, 0] = cap[j]; } } if (j == 0) { copyMatrix(matPi, matP); copyMatrix(matPid, matPd); } else { copyMatrix(matP, matPo); copyMatrix(matPd, matPod); multiplicateMatrix(matPo, matPi, ref matP); multiplicateMatrix(matPod, matPi, ref matPd); multiplicateMatrix(matPo, matPid, ref matPd2); addMatrix(matPd, matPd2, ref matPd); } } if (i == 0 && iter == 0) { double p2 = matP[0, 1] * matP[0, 1]; g_xyz_0[0] = (matPd[0, 0] * matP[0, 1] - matP[0, 0] * matPd[0, 1]) / p2; g_xyz_0[1] = -matPd[0, 1] / p2; g_xyz_0[2] = (matPd[1, 1] * matP[0, 1] - matP[1, 1] * matPd[0, 1]) / p2; } //収束判定 if (Math.Abs(matP[0, 1]) < 1.0e-10d) break; //Nラプソン法でbetaを更新 double bmm = 0; if (0 < i) { for (int j = 0; j < i; j++) { bmm += 1.0d / (beta[j] - bm); } } bm += matP[0, 1] / (matPd[0, 1] - matP[0, 1] * bmm); iter++; if (20 < iter) throw new Exception("Iteration Error"); } //betaを設定 beta[i] = bm; g_xyz[1, i] = 1.0d / (bm * bm * matPd[0, 1]); g_xyz[0, i] = matP[0, 0] * g_xyz[1, i]; g_xyz[2, i] = matP[1, 1] * g_xyz[1, i]; } for (int xyz = 0; xyz < 3; xyz++) { rf[xyz, 0] = g_xyz_0[xyz]; rf[xyz, 1] = -g_xyz_0[xyz]; for (int i = 2; i < rfNumber; i++) rf[xyz, i] = 0; } for (int i = 0; i < G_NUMBER; i++) { double eb = Math.Exp(-beta[i] * timeStep); for (int xyz = 0; xyz < 3; xyz++) { rf[xyz, 0] += g_xyz[xyz, i] * eb; rf[xyz, 1] += g_xyz[xyz, i] * (eb - 2.0d) * eb; for (int j = 2; j < rfNumber; j++) rf[xyz, j] += g_xyz[xyz, i] * (1.0d - eb) * (1.0d - eb) * Math.Exp(-beta[i] * (j - 1) * timeStep); } } double kValue = wallLayers.GetThermalTransmission(filmCoefficient1, filmCoefficient2); for (int xyz = 0; xyz < 3; xyz++) { rf[xyz, 0] = kValue + rf[xyz, 0] / timeStep; for (int i = 1; i < rfNumber; i++) rf[xyz, i] /= timeStep; } //公比 commonRatio = Math.Exp(-beta[0] * timeStep); rFactorX[0] = rf[0, 0]; rFactorY[0] = rf[1, 0]; rFactorZ[0] = rf[2, 0]; for (int i = 1; i < rfNumber; i++) { rFactorX[i] = rf[0, i] - commonRatio * rf[0, i - 1]; rFactorY[i] = rf[1, i] - commonRatio * rf[1, i - 1]; rFactorZ[i] = rf[2, i] - commonRatio * rf[2, i - 1]; } }
private static void wallOverallHeatTransferCoefTest() { //多層壁オブジェクトを作成 WallLayers wLayers = new WallLayers("熱貫流率計算用多層壁"); //壁層の素材を作成 WallMaterial[] materials = new WallMaterial[4]; //第1層:合板 materials[0] = new WallMaterial(WallMaterial.PredefinedMaterials.Plywood); //第2層:非密閉空気層 materials[1] = new WallMaterial(WallMaterial.PredefinedMaterials.AirGap); //第3層:鉄筋コンクリート materials[2] = new WallMaterial(WallMaterial.PredefinedMaterials.ReinforcedConcrete); //第4層:漆喰 materials[3] = new WallMaterial("漆喰", 0.7, 1000); //壁の各層を作成 //合板:20mm wLayers.AddLayer(new WallLayers.Layer(materials[0], 0.02)); //空気層:厚みは関係なし wLayers.AddLayer(new WallLayers.Layer(materials[1], 0.01)); //鉄筋コンクリート:150mm wLayers.AddLayer(new WallLayers.Layer(materials[2], 0.15)); //漆喰:10mm wLayers.AddLayer(new WallLayers.Layer(materials[3], 0.01)); //結果書き出し Console.WriteLine("壁層の構成"); for (uint i = 0; i < wLayers.LayerNumber; i++) { WallLayers.Layer layer = wLayers.GetLayer(i); Console.WriteLine("第" + (i + 1) + "層:" + layer.Material.Name + "(" + layer.Thickness + "m)"); } Console.WriteLine("熱貫流率=" + wLayers.GetThermalTransmission().ToString("F1") + " W/(m2-K)"); Console.WriteLine(); //軽量コンクリートに変えてみる wLayers.ReplaceLayer(2, new WallLayers.Layer(new WallMaterial(WallMaterial.PredefinedMaterials.LightweightConcrete), 0.15)); //結果書き出し Console.WriteLine("壁層の構成"); for (uint i = 0; i < wLayers.LayerNumber; i++) { WallLayers.Layer layer = wLayers.GetLayer(i); Console.WriteLine("第" + (i + 1) + "層:" + layer.Material.Name + "(" + layer.Thickness + "m)"); } Console.WriteLine("熱貫流率=" + wLayers.GetThermalTransmission().ToString("F1") + " W/(m2-K)"); Console.Read(); }
private static void rFactorSample() { WallLayers wallLayers = new WallLayers(); wallLayers.AddLayer(new WallLayers.Layer(new WallMaterial("コンクリート", 1.4, 1934), 0.15)); wallLayers.AddLayer(new WallLayers.Layer(new WallMaterial("ロックウール", 0.042, 84), 0.05)); wallLayers.AddLayer(new WallLayers.Layer(new WallMaterial("中空層", 11.6, 0), 0.02)); wallLayers.AddLayer(new WallLayers.Layer(new WallMaterial("アルミ化粧板", 210, 2373), 0.002)); double[] rfx = new double[8]; double[] rfy = new double[8]; double[] rfz = new double[8]; double commonRatio = 0; ResponseFactor.GetResponseFactor(3600, 9.3, 23.0, wallLayers, 8, ref rfx, ref rfy, ref rfz, out commonRatio); Console.WriteLine(wallLayers.GetThermalTransmission(9.3, 23)); double[] temperatures1 = new double[] { 27.4, 27.1, 26.8, 26.5, 26.9, 27.7, 28.8, 29.8, 30.8, 31.5, 32.1, 32.6, 32.9, 33.2, 33.5, 33.1, 32.4, 31.5, 30.6, 29.8, 29.1, 28.5, 28.1, 27.7 }; double[] temperatures2 = new double[24]; for (int i = 0; i < temperatures2.Length; i++) temperatures2[i] = 26.0d; double[] qloads = new double[24]; int hour = 0; double kValue = wallLayers.GetThermalTransmission(9.3,23.0); double q1 = 0; double q2 = 0; while (true) { Console.Write(hour.ToString() + "時: "); ResponseFactor.GetHeatFlow(temperatures1, temperatures2, rfx, rfy, rfz, commonRatio, q1, q2, out q1, out q2); Console.WriteLine(temperatures1[0].ToString("F1") + " C " + q2.ToString("F1") + " W/m2 " + (q2 / kValue).ToString("F1") + " C"); if (Math.Abs(q2 - qloads[hour]) < 0.0001) break; else qloads[hour] = q2; //温度をずらす double tmp = temperatures1[0]; for (int j = 1; j < temperatures1.Length; j++) temperatures1[j - 1] = temperatures1[j]; temperatures1[temperatures1.Length - 1] = tmp; hour++; if (hour == 24) hour = 0; } }
/// <summary>Sample program calculating the thermal transimission of the wall layers</summary> private static void wallLayersTest() { //Create an instance of WallLayers WallLayers wLayers = new WallLayers("Sample wall layer"); //Make an array of materials WallMaterial[] materials = new WallMaterial[4]; //The first layer : plywood materials[0] = new WallMaterial(WallMaterial.PredefinedMaterials.Plywood); //The second layer : air gap materials[1] = new WallMaterial(WallMaterial.PredefinedMaterials.AirGap); //The thirg layer : concrete materials[2] = new WallMaterial(WallMaterial.PredefinedMaterials.ReinforcedConcrete); //The fourth layer : white Wash materials[3] = new WallMaterial("White Wash", 0.7, 1000); //Add a layer to WallLayers object //plywood : 20mm wLayers.AddLayer(new WallLayers.Layer(materials[0], 0.02)); //air gap : heat conductance doesn't depend on thickness wLayers.AddLayer(new WallLayers.Layer(materials[1], 0.01)); //concrete : 150mm wLayers.AddLayer(new WallLayers.Layer(materials[2], 0.15)); //white Wash : 10mm wLayers.AddLayer(new WallLayers.Layer(materials[3], 0.01)); //output result Console.WriteLine("Wall composition"); for (uint i = 0; i < wLayers.LayerNumber; i++) { WallLayers.Layer layer = wLayers.GetLayer(i); Console.WriteLine("Layer " + (i + 1) + ":" + layer.Material.Name + "(" + layer.Thickness + "m)"); } Console.WriteLine("Thermal transmission = " + wLayers.GetThermalTransmission().ToString("F1") + " W/(m2-K)"); Console.WriteLine(); //Replace concrete to light weight concrete wLayers.ReplaceLayer(2, new WallLayers.Layer(new WallMaterial(WallMaterial.PredefinedMaterials.LightweightConcrete), 0.15)); //output result Console.WriteLine("Wall composition"); for (uint i = 0; i < wLayers.LayerNumber; i++) { WallLayers.Layer layer = wLayers.GetLayer(i); Console.WriteLine("Layer " + (i + 1) + ":" + layer.Material.Name + "(" + layer.Thickness + "m)"); } Console.WriteLine("Thermal transmission = " + wLayers.GetThermalTransmission().ToString("F1") + " W/(m2-K)"); Console.WriteLine(); Console.Read(); }