diff --git a/excel_addin/Solve.cs b/excel_addin/Solve.cs index e5429fe..2e15839 100644 --- a/excel_addin/Solve.cs +++ b/excel_addin/Solve.cs @@ -38,40 +38,7 @@ namespace excel_addin } return _sigma; } - //从状态方程接触张力 - //start_tension 牛顿法初值 - //alpha 是膨胀系数 - //E 弹性模量 - //area 导线截面 - //conrol_t 控制条件温度 - //conrol_load 控制条件荷载 - //conrol_tension 控制条件张力 - //load 计算工况荷载 - //t 计算工况温度 - //l 档距 - public static double tensionFrmoStateEquation(double start_tension, double E, double alpha, double area, double control_load, double control_tension, double control_t, double load, double t, double l) - { - double A, B; - //A = E / 24 * Math.Pow(control_load * l / control_tension, 2) - control_tension / area + alpha * E * (t - control_t); - A = Fx(E, control_load, control_tension, alpha, area, control_t, l) + alpha * E * t; - B = E * Math.Pow(load / area * l, 2) / 24; - double tension;//牛顿法初值 - bool succeed = false; - tension = newton(A, B, start_tension / area, ref succeed) * area; - if (succeed) - { - return tension; - } - return double.NaN; - } - //alpha 是膨胀系数 - //E 弹性模量 - //area 导线截面 - //t 温度 - // l 档距 - public static double Fx(double E, double load, double tension, double alpha, double area, double t, double l) - { - return E * Math.Pow(load * l / tension, 2) / 24 - tension / area - alpha * E * t; - } + + } } diff --git a/excel_addin/Tension.cs b/excel_addin/Tension.cs index 8f54426..4f7d43f 100644 --- a/excel_addin/Tension.cs +++ b/excel_addin/Tension.cs @@ -11,8 +11,9 @@ namespace excel_addin { - - + //全局用临界档距,是个单例 + private static List gCriticalSpan; + [ExcelFunction(Description = "覆冰增重荷载")]//仅包含覆冰重量 public static double ice_load(double d, double iceThickness)//d导线直径,单位mm,iceThickness 覆冰厚度 单位mm { @@ -126,6 +127,340 @@ namespace excel_addin return val; } + //alpha 是膨胀系数 + //E 弹性模量 + //area 导线截面 + //t 温度 + // l 档距 + public static double Fx(double E, double load, double tension, double alpha, double area, double t, double l) + { + return E * Math.Pow(load * l / tension, 2) / 24 - tension / area - alpha * E * t; + } + + + //临界档距 + public static double[] criticalSpanForExcel(int maxSpan, double Epsilon, double Alpha, double area, double lowTemp_t, double lowTemp_load, double lowTemp_tens, double avrTemp_t, double avrTemp_load, double avrTemp_tens, double strongWind_t, double strongWind_load, double strongWind_tens, double ice_t, double ice_load, double ice_tens) + { + List criticalSpanList = criticalSpan(maxSpan, Epsilon, Alpha, area, lowTemp_t, lowTemp_load, lowTemp_tens, avrTemp_t, avrTemp_load, avrTemp_tens, strongWind_t, strongWind_load, strongWind_tens, ice_t, ice_load, ice_tens); + double[] value = new double[criticalSpanList.Count * 2]; + for (int foo = 0; foo < criticalSpanList.Count; foo++) + { + value[2 * foo] = criticalSpanList[foo][0]; + value[2 * foo + 1] = criticalSpanList[foo][1]; + } + return value; + } + //临界档距 + public static List criticalSpan(int maxSpan, double Epsilon, double Alpha, double area, double lowTemp_t, double lowTemp_load, double lowTemp_tens, double avrTemp_t, double avrTemp_load, double avrTemp_tens, double strongWind_t, double strongWind_load, double strongWind_tens, double ice_t, double ice_load, double ice_tens) + { + List criticalSpanList = new List(); + //计算4个工况下的Fx + //t_dangju 试探最大Fx时使用的档距 + int[] MaxFxConditionFlag = new int[maxSpan + 1];//记录不同档距下,哪种工况的Fx最大。1代表最低温,2代表年平均温,3代表大风,4代表覆冰。0位置元素无效。 + for (int span = 1; span <= maxSpan; span++) + { + double Fx_lowTemp; + double Fx_avrTemp; + double Fx_strongWind; + double Fx_Ice; + Fx_lowTemp = Fx(Epsilon, lowTemp_load, lowTemp_tens, Alpha, area, lowTemp_t, span); + Fx_avrTemp = Fx(Epsilon, avrTemp_load, avrTemp_tens, Alpha, area, avrTemp_t, span); + Fx_strongWind = Fx(Epsilon, strongWind_load, strongWind_tens, Alpha, area, strongWind_t, span); + Fx_Ice = Fx(Epsilon, ice_load, ice_tens, Alpha, area, ice_t, span); + double maxFx; + maxFx = Fx_lowTemp; + MaxFxConditionFlag[span] = 1; + if (maxFx < Fx_avrTemp) + { + maxFx = Fx_avrTemp; + MaxFxConditionFlag[span] = 2; + } + if (maxFx < Fx_strongWind) + { + maxFx = Fx_strongWind; + MaxFxConditionFlag[span] = 3; + } + if (maxFx < Fx_Ice) + { + maxFx = Fx_Ice; + MaxFxConditionFlag[span] = 4; + } + MaxFxConditionFlag[0] = MaxFxConditionFlag[1];//为了后面判断临界档距突变,不会从1米档距开始跳变。 + double currentTension = 0; + double currentLoad = 0; + double currentTemperature = 0; + switch (MaxFxConditionFlag[span]) + { + case 1: + currentLoad = lowTemp_load; + currentTension = lowTemp_tens; + currentTemperature = lowTemp_t; + break; + case 2: + currentLoad = avrTemp_load; + currentTension = avrTemp_tens; + currentTemperature = avrTemp_t; + break; + case 3: + currentLoad = strongWind_load; + currentTension = strongWind_tens; + currentTemperature = strongWind_t; + break; + case 4: + currentLoad = ice_load; + currentTension = ice_tens; + currentTemperature = ice_t; + break; + default: + break; + } + if (MaxFxConditionFlag[span] != MaxFxConditionFlag[span - 1])//有突变,找到了临界档距的范围 + { + double formerTension = 0; + double formerLoad = 0; + double formerTemperature = 0; + switch (MaxFxConditionFlag[span - 1]) + { + case 1: + formerLoad = lowTemp_load; + formerTension = lowTemp_tens; + formerTemperature = lowTemp_t; + break; + case 2: + formerLoad = avrTemp_load; + formerTension = avrTemp_tens; + formerTemperature = avrTemp_t; + break; + case 3: + formerLoad = strongWind_load; + formerTension = strongWind_tens; + formerTemperature = strongWind_t; + break; + case 4: + formerLoad = ice_load; + formerTension = ice_tens; + formerTemperature = ice_t; + break; + default: + break; + } + double t1 = 24 / Epsilon * (formerTension - currentTension) / area; + double t2 = 24 * Alpha * (formerTemperature - currentTemperature); + double t3 = Math.Pow(formerLoad / formerTension, 2) - Math.Pow(currentLoad / currentTension, 2); + double _criticalSpan = Math.Sqrt((t1 + t2) / t3); + //List中存有数组,0位置为临界档距,1位置为控制条件 + criticalSpanList.Add(new double[] { _criticalSpan, MaxFxConditionFlag[span - 1] }); + } + } + criticalSpanList.Add(new double[] { maxSpan, MaxFxConditionFlag[maxSpan] }); + gCriticalSpan = new List(criticalSpanList); + return criticalSpanList; + } + + //从状态方程接触张力 + //start_tension 牛顿法初值 + //alpha 是膨胀系数 + //E 弹性模量 + //area 导线截面 + //conrol_t 控制条件温度 + //conrol_load 控制条件荷载 + //conrol_tension 控制条件张力 + //load 计算工况荷载 + //t 计算工况温度 + //l 档距 + public static double tensionFrmoStateEquation(double start_tension, double E, double alpha, double area, double control_load, double control_tension, double control_t, double load, double t, double l) + { + double A, B; + //A = E / 24 * Math.Pow(control_load * l / control_tension, 2) - control_tension / area + alpha * E * (t - control_t); + A = Fx(E, control_load, control_tension, alpha, area, control_t, l) + alpha * E * t; + B = E * Math.Pow(load / area * l, 2) / 24; + double tension;//牛顿法初值 + bool succeed = false; + tension = Solve.newton(A, B, start_tension / area, ref succeed) * area; + if (succeed) + { + return tension; + } + return -999999; + } + + + //public static bool CalZhangLi(calStressLoadNew inPut, ref double ZhangLi) + //{ + // //张力=T6 + // //计算最大使用张力 + // double ZuiDaShiYongZhangLi; //最大使用张力=计算拉断力*保证破断张力取计算拉断力的/安全系数 + // ZuiDaShiYongZhangLi = inPut.EDingLaDuanLi * inPut.BaoZhengPoDuanZhangLiXiShu / 100 / inPut.AnQuan; + // //ZuiDaShiYongZhangLi = inPut.LaDuanLi / inPut.AnQuan; + // //计算温度线膨胀系数 + // double XianPengZhang = inPut.XianPengZhang; + // //计算平均运行张力 + // double PingJunYunXingZhangLi = inPut.EDingLaDuanLi * inPut.BaoZhengPoDuanZhangLiXiShu / 100 * inPut.NianPingJunXishu / 100;//年平均单位是% + // //double a, b, T1, T2, T3, T4, T5, T6; + // //计算待求工况比载 + // double DaiHeZai = 0; //待求工况比载 + // if (CalHeZai(inPut, ref DaiHeZai) == false) + // { + // return false; + // } + // //临界档距表计算 + // //一、初始计算数组,5项分别代表:1:气温,2:荷载,3:容许张力,4:P/T,5:Fo=-(T+A*E*a*t)(N) + // double[] ChuShiZuiDiQiWen = new double[5]; //最低温 + // double[] ChuShiNianPingJun = new double[5]; //年平均气温 + // double[] ChuShiDaFeng = new double[5]; //大风 + // double[] ChuShiFuBing = new double[5]; //最大覆冰 + // //1:存储各工况温度 + // ChuShiZuiDiQiWen[0] = inPut.DiWen; + // ChuShiNianPingJun[0] = inPut.PingWen; + // ChuShiDaFeng[0] = inPut.FengWen; + // ChuShiFuBing[0] = inPut.BingWen; + // //定义各个工况结构体,将每个结构体中的待求工况设置为对应工况数据,因为计算荷载时前面写的计算荷载函数中调取的是待求工况的温度等信息,所以需要对应各个工况 + // calStressLoadNew ZuiDiWen = inPut; + // calStressLoadNew NianPingJun = inPut; + // calStressLoadNew DaFeng = inPut; + // calStressLoadNew FuBing = inPut; + // ZuiDiWen.DaiBing = ZuiDiWen.DiBing; + // ZuiDiWen.DaiFeng = ZuiDiWen.DiFeng; + // ZuiDiWen.DaiZheSuanFengSu = false; + // ZuiDiWen.DaiWen = ZuiDiWen.DiWen; + // NianPingJun.DaiBing = NianPingJun.PingBing; + // NianPingJun.DaiFeng = NianPingJun.PingFeng; + // NianPingJun.DaiZheSuanFengSu = false; + // NianPingJun.DaiWen = NianPingJun.PingWen; + // DaFeng.DaiBing = DaFeng.FengBing; + // //double wind_velocity; + // //wind_velocity = Math.Round(DaFeng.FengFeng * Math.Pow(DaFeng.PingJunGaoDu / DaFeng.SheJiFengSuGaoDu, 0.16), 2); + // DaFeng.DaiFeng = DaFeng.FengFeng; + // DaFeng.DaiZheSuanFengSu = true; + // DaFeng.DaiWen = DaFeng.FengWen; + // FuBing.DaiBing = FuBing.BingBing; + // FuBing.DaiFeng = FuBing.BingFeng; + // FuBing.DaiZheSuanFengSu = false; + // FuBing.DaiWen = FuBing.BingWen; + // //2:计算并存储各个工况荷载 + // CalHeZai(ZuiDiWen, ref ChuShiZuiDiQiWen[1]); + // CalHeZai(NianPingJun, ref ChuShiNianPingJun[1]); + // CalHeZai(DaFeng, ref ChuShiDaFeng[1]); + // CalHeZai(FuBing, ref ChuShiFuBing[1]); + // //3:存储各工况容许张力 + // ChuShiZuiDiQiWen[2] = ZuiDaShiYongZhangLi; + // ChuShiNianPingJun[2] = PingJunYunXingZhangLi; + // ChuShiDaFeng[2] = ZuiDaShiYongZhangLi; + // ChuShiFuBing[2] = ZuiDaShiYongZhangLi; + // //4:计算并存储P/T 荷载/张力 + // ChuShiZuiDiQiWen[3] = ChuShiZuiDiQiWen[1] / ChuShiZuiDiQiWen[2]; + // ChuShiNianPingJun[3] = ChuShiNianPingJun[1] / ChuShiNianPingJun[2]; + // ChuShiDaFeng[3] = ChuShiDaFeng[1] / ChuShiDaFeng[2]; + // ChuShiFuBing[3] = ChuShiFuBing[1] / ChuShiFuBing[2]; + + // //计算4个工况下的Fx by 杜孟远2020.4.17 + // //t_dangju 试探最大Fx时使用的档距 + // int[] MaxFxConditionFlag = new int[inPut.DangJu + 1];//记录不同t_dangju下,哪种工况的Fx最大。1代表最低温,2代表年平均温,3代表大风,4代表覆冰。0位置元素无效。 + // MaxFxConditionFlag[0] = 1; + // for (int t_dangju = inPut.DangJu; t_dangju <= inPut.DangJu; t_dangju++) + // { + // double Fx_dangjuZuiDiWen; + // double Fx_dangjuNianPingJun; + // double Fx_dangjuDaFeng; + // double Fx_dangjuFuBing; + // Fx_dangjuZuiDiWen = Fx(inPut.MoLiang, ChuShiZuiDiQiWen[1], ChuShiZuiDiQiWen[2], inPut.XianPengZhang, inPut.JieMianJi, ChuShiZuiDiQiWen[0], t_dangju); + // Fx_dangjuNianPingJun = Fx(inPut.MoLiang, ChuShiNianPingJun[1], ChuShiNianPingJun[2], inPut.XianPengZhang, inPut.JieMianJi, ChuShiNianPingJun[0], t_dangju); + // Fx_dangjuDaFeng = Fx(inPut.MoLiang, ChuShiDaFeng[1], ChuShiDaFeng[2], inPut.XianPengZhang, inPut.JieMianJi, ChuShiDaFeng[0], t_dangju); + // Fx_dangjuFuBing = Fx(inPut.MoLiang, ChuShiFuBing[1], ChuShiFuBing[2], inPut.XianPengZhang, inPut.JieMianJi, ChuShiFuBing[0], t_dangju); + // double maxFx; + // maxFx = Fx_dangjuZuiDiWen; + // MaxFxConditionFlag[t_dangju] = 1; + // if (maxFx < Fx_dangjuNianPingJun) + // { + // maxFx = Fx_dangjuNianPingJun; + // MaxFxConditionFlag[t_dangju] = 2; + // } + // if (maxFx < Fx_dangjuDaFeng) + // { + // maxFx = Fx_dangjuDaFeng; + // MaxFxConditionFlag[t_dangju] = 3; + // } + // if (maxFx < Fx_dangjuFuBing) + // { + // maxFx = Fx_dangjuFuBing; + // MaxFxConditionFlag[t_dangju] = 4; + // } + // double currentTension = 0; + // double currentLoad = 0; + // double currentTemperature = 0; + // switch (MaxFxConditionFlag[t_dangju]) + // { + // case 1: + // currentLoad = ChuShiZuiDiQiWen[1]; + // currentTension = ChuShiZuiDiQiWen[2]; + // currentTemperature = ChuShiZuiDiQiWen[0]; + // break; + // case 2: + // currentLoad = ChuShiNianPingJun[1]; + // currentTension = ChuShiNianPingJun[2]; + // currentTemperature = ChuShiNianPingJun[0]; + // break; + // case 3: + // currentLoad = ChuShiDaFeng[1]; + // currentTension = ChuShiDaFeng[2]; + // currentTemperature = ChuShiDaFeng[0]; + // break; + // case 4: + // currentLoad = ChuShiFuBing[1]; + // currentTension = ChuShiFuBing[2]; + // currentTemperature = ChuShiFuBing[0]; + // break; + // default: + // break; + // } + // //TODO: 目前不进入这个判断 by 杜孟远 2020.4.18 + // MaxFxConditionFlag[t_dangju] = MaxFxConditionFlag[t_dangju - 1];//TODO: 以后删掉这句 by 杜孟远 2020.4.18 + // if (MaxFxConditionFlag[t_dangju] != MaxFxConditionFlag[t_dangju - 1])//有突变,找到了临界档距的范围 + // { + // double criticalSpan; + // double formerTension = 0; + // double formerLoad = 0; + // double formerTemperature = 0; + // switch (MaxFxConditionFlag[t_dangju - 1]) + // { + // case 1: + // formerLoad = ChuShiZuiDiQiWen[1]; + // formerTension = ChuShiZuiDiQiWen[2]; + // formerTemperature = ChuShiZuiDiQiWen[0]; + // break; + // case 2: + // formerLoad = ChuShiNianPingJun[1]; + // formerTension = ChuShiNianPingJun[2]; + // formerTemperature = ChuShiNianPingJun[0]; + // break; + // case 3: + // formerLoad = ChuShiDaFeng[1]; + // formerTension = ChuShiDaFeng[2]; + // formerTemperature = ChuShiDaFeng[0]; + // break; + // case 4: + // formerLoad = ChuShiFuBing[1]; + // formerTension = ChuShiFuBing[2]; + // formerTemperature = ChuShiFuBing[0]; + // break; + // default: + // break; + // } + // double t1 = 24 / inPut.MoLiang * (formerTension - currentTension) / inPut.JieMianJi; + // double t2 = 24 * inPut.XianPengZhang * (formerTemperature - currentTemperature); + // double t3 = Math.Pow(formerLoad / formerTension, 2) - Math.Pow(currentLoad / currentTension, 2); + // criticalSpan = Math.Sqrt((t1 + t2) / t3);//TODO:暂时不用 + // //Console.WriteLine("{0}", criticalSpan); + + // } + // double start_tension = inPut.EDingLaDuanLi / inPut.AnQuan; + // ZhangLi = tensionFrmoStateEquation(start_tension, inPut.MoLiang, inPut.XianPengZhang, inPut.JieMianJi, currentLoad, currentTension, currentTemperature, DaiHeZai, inPut.DaiWen, inPut.DangJu); + // } + + // ZhangLi = BaoLiuLiangWei(ZhangLi); + // return true; + //} + } }