excel_addin/excel_addin/Tension.cs

467 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//using System;
using System.Collections.Generic;
//using System.Linq;
//using System.Text;
using ExcelDna.Integration;
using System;
namespace excel_addin
{
public static class Excel_Addin
{
//全局用临界档距,是个单例
private static List<double[]> gCriticalSpan;
[ExcelFunction(Description = "覆冰增重荷载")]//仅包含覆冰重量
public static double ice_load(double d, double iceThickness)//d导线直径单位mm,iceThickness 覆冰厚度 单位mm
{
double val = 9.80665 * 0.9 * Math.PI * iceThickness * (iceThickness + d) / 1000;
return val;
}
[ExcelFunction(Description = "计算杆塔用风压不均匀系数")]
public static double alpha_load(double basicV)//basicV 基本风速 单位m/s
{
double _a = 0;
if (basicV < 20)
{
_a = 1;
}
else
{
if (basicV >= 20 && basicV < 27)
{
_a = 0.85;
}
else
{
if (basicV >= 27 && basicV < 31.5)
{
_a = 0.75;
}
else
{
if (basicV >= 31.5)
{
_a = 0.7;
}
}
}
}
return _a;
}
[ExcelFunction(Description = "计算风偏用风压不均匀系数")]
public static double alpha_swing(double basicV)//basicV 基本风速 单位m/s
{
double _a = 0;
if (basicV < 20)
{
_a = 1;
}
else
{
if (basicV >= 20 && basicV < 27)
{
_a = 0.75;
}
else
{
if (basicV >= 27 && basicV < 31.5)
{
_a = 0.61;
}
else
{
if (basicV >= 31.5)
{
_a = 0.61;
}
}
}
}
return _a;
}
[ExcelFunction(Description = "覆冰后风荷载增大系数")]
public static double iceB(int iceThickness)//iceThickness 覆冰厚度 单位mm
{
var code = new Dictionary<int, double>();
code.Add(0, 1.0);
code.Add(5, 1.1);
code.Add(10, 1.2);
code.Add(15, 1.3);
if (iceThickness >= 20)
{
throw new Exception("缺少20mm冰以上覆冰后荷载增大系数!");
}
return code[iceThickness];
}
[ExcelFunction(Description = "电线受风形体系数")]
public static double mu_sc(double d,int iceThickness)//d导线直径单位mm,iceThickness 覆冰厚度 单位mm
{
if (iceThickness > 0)
{
return 1.2;
}
if (d < 17)
{
return 1.2;
}
//if d >=17
return 1.1;
}
[ExcelFunction(Description = "电线单位风荷载")]
public static double wind_loadPN(double ave_h_v, double d, double alpha_load,double mu_sc, int iceThickness)//ave_h_v平均高处的风速 , d 导线直径 单位mm,alpha_load 风压不均匀系数mu_sc电线体型系数,iceThickness 覆冰厚度 单位mm
{
double val = 0.625 * Math.Pow(ave_h_v, 2) * (d + 2 * iceThickness) * alpha_load*mu_sc / 1000;
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<double[]> 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<double[]> 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<double[]> criticalSpanList = new List<double[]>();
//计算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<double[]>(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/T5: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;
//}
}
}