#ifndef __ALGORITHM_H__
#define __ALGORITHM_H__

#pragma pack(push, 1)

#define DatasNumber 1							//数据最大数量

//cqr 20230224修改

//罐箱参数
struct TankPara
{	
	/////第2类：一次性下发的算法固定常数，按后面的注释值赋值，所有常数变量在苏醒后需要读入
	float DL0;	//		0.05  =====液位差判断基准==4G输入给出，
	float Dis_0; //  1000 
	float DT_0; //采样时间周期ΔT  整型常数变量 1 小时 	
	float T_0;	//		150  =====温度判断基准==4G输入给出，
	float Stable_Day;//		1 ====静置天数==4G输入给出，
	float Lamda_0; //   0.1 
	float L_0;	//		充装状态判断条件Φ0 0.75 =====液位判断基准==4G输入给出， 
	float Eta_V;	//		0.95  =====容积安全系数==4G输入给出，
	float Pa_0; //   0.1013 
	float Tc_0; //  =273.15+30 = 303.15 
	float R_0; //   8.314 
	float MTime_0; //   300
	float Fai_bz0; //   0.95 
	short int Nday_0;// 整型常数 20  平均日漏热量计算周期CT
	short int Tz_0;  // 内能计算间隔周期tz  整型常数 24小时
	float Fai_0;	//		0.75  =====充装率判断基准==4G输入给出，
	float Mavg_0; //   16
	float Pcr_0;// 常数  4.59
	float QHQR_0	;	//	511.12  =====标态LNG气化潜热==4G输入给出，
	float RhoLng_0; //   434.15 
	float K_1;	//		0.6583  =====标态LNG和液氮气化潜热转换系数=4G输入给出，
	
	float Default_CH4;//	0.95 ====默认甲烷成分==4G输入给出，
	float VN_0; //常数  0.01191
	float Nx_0; //   0.35
	float Ny_0; //   0.5
	float Nz_0; //   0.15
	float Kymax;  //常数 1.1
	float Kymin;  //常数 0.8

	float Da_0; //   0.00202 
	float Db_0; //   -0.023
	float Dc_0; //   0.0125 
	float Dd_0; //   -0.0309
	
	//预留
	float  Default_C2;  // 默认C2成分比
	float  Default_C3;  // 默认C3成分比
	float  Default_C4;  // 默认C4成分比
	float  Default_N2;  // 默认N2成分比
	float  TimeYJ;  // 安全阀起跳预警值
	float  RJJ;  // 结果相关性修正系数—截距
	float  RXL;  // 结果相关性修正系数—斜率
	float  RQP;  // 结果相关性修正区间起始压力
	float  QZP;  // 结果相关性修正区间终止压力
	float  ZQQ;  // 重罐轻罐权重系数-气相导热系数
	float  ZQY;  // 重罐轻罐权重系数-液相导热系数
	float  ZQFai0;  // 重罐轻罐权重修正起始充装率
	float  ZQFaiN;  // 重罐轻罐权重修正终止充装率
	short int  SFKZ1;  // 算法控制参数1(是否启用区间结果相关性修正）
	short int  SFKZ2;  // 算法控制参数2（重罐-轻罐权重系数）
	short int  SFKZ3;  // 算法控制参数3（临界参数你和修正）
	short int  SFKZ4;  // 算法控制参数4（温度系数K2修正）
	short int  SFKZ5;  // 算法控制参数5（日漏热量修正）
	short int  SFKZ6;  // 算法控制参数6（罐箱用途）

	float Tcr; //临界温度
	float dTmax; //罐内最大温差
	float dTP; //安全阀起跳状态判断参数

	float csY3;// 常数预留变量
	float csY4;
	float csY5;
	float csY6;
	float csY7;
	float csY8;
	float csY9;
	float csY10;

	/////

	//////////////////////////////////////////////////////////////////////////
	
	////第3类 罐箱固定参数
	float P75;//满罐安全阀起跳压力，文件输入
	float a20;    //液氮静态蒸发率，文件输入
	float TankVolYX; // 有效容积，文件输入
	float TankVol; // 总容积，文件输入
	float D; // 罐子直径
	float fai;    // 额定充装率，文件输入	
	short int GT;//罐箱用途 运输罐箱为01，燃料罐箱为02
	short int TankType; // 罐箱绝热型式，文件输入
	short int ZC;//罐箱支撑型式  01代表两点支撑，02代表8点支撑，02为默认值
	
	float ZKD; //真空度
	float Phz; // 安全阀回座压力
	float minFai;//最小可识别充装率
	float RL; // 罐箱圆柱段长度

	float gxY3;// 预留参数
	float gxY4;
	float gxY5;
	float gxY6;
	float gxY7;
	float gxY8;
	float gxY9;
	float gxY10;


	////////// 第5类 组分航次参数，营运输入，每航次变更
	float ch4;    // 甲烷成分比
	float C2;   // C2摩尔百分比（体积比）
	float C3;   // C3摩尔百分比（体积比）
	float C4;   // C4摩尔百分比（体积比）
	float N2;   // N2摩尔百分比（体积比）

	float hcY1;//航次预留系数
	float hcY2;
	float hcY3;
	float hcY4;
	float hcY5;
	float hcY6;
	float hcY7;
	float hcY8;
	float hcY9;
	float hcY10;


	
	//////////////////////////////////////////////////////////////////////////
	
	////第1类： 运行时的实时数据，苏醒后需要读入
	int isStart;     // 是否开始预报
	float QDay_0; //日漏热量
	
	float mMin;  // 最小安全质量，空罐最大允许剩余量  ，用于是否空罐的判断
	float aLNG20; //LNG静态蒸发率，a20*k1,k1=0.6583  
	float QdLNG20; // 根据静态蒸发率计算的标态每日漏热量

	float faiMax;  //极限充装率

	float m0;    //总质量

	float RhoLNG0; // 标态LNG饱和液体密度，根据甲烷成分比按P=0插值计算
	float QHQR0; // 标态LNG饱和液体气化潜热,取为定值511.12
	
	float Pn;// 终了起跳压力，文件输入；在涨罐压力和满罐起跳压力之间取小者
	float Qn;//终了内能
	float TAvg;//平均温度，(T0+Tn)/2

	float Qn_kg;//空罐终了内能 20230224

	float WE0;
	float SN0; //初始

	float ZeroL;   // 初始充装率
	double ZeroDate;  // 初始时间
	float ForeCast_Sec;  // 离满足条件的标记0时刻的时间长度（单位秒），-1代表未标记满足条件0时刻，非-1代表当前离标记0时刻的时间长度（单位秒）,这个未扣除稳定期时间长度	
	float ForeCast_Date;  //开始预报日期天数，-1不预报，非-1代表第多少天的预报；ForeCast_Date = (ForeCast_Sec - StablePeriod)/ 3600 / 24 //这个扣除了稳定期时间长度，其0值即代表预报开始的0时刻（单位天）

	unsigned char  ZeroDate_Str[12];  /// 苏醒后需要读入
	//unsigned char  PreDate_Str[12];  /// 苏醒后需要读入   //cqr-20230117 

	double preDate;  //cqr-20230117
	float Pre_fai; //前一时刻的充装率 cqr-2023 新增

	//每日24小时漏热量记录数据	
	short int nhour;  //记录小时数
	//	int nData; // 每天读取数据条数
	short int ihour;// 记录数据个数
	short int iQday;

	float Qhour[24];
	float hour[24];
	float dQi[24];

	//每日漏热量记录数据	
	short int nday;  //记录天数
	short int nData; // 每天读取数据条数
	float DayNow;
	short int iday;// 记录数据个数
	float Qi_0; // 起始时间的内能
	float Qi;  // 当天内能
	float QdAvg;
	float Qday[20];
	short int day[20]; //记录Qday对应的天数

	float Qi_kg;//空罐当前内能 20230224

	//jzw 20230228 记录质量数据
	short int isChange;//判断质量是否进行初始化赋值（实时计算） 0初始化 1不初始化
	short int isCal; //判断是否进行质量计算 0不计算  1计算
	float Mhour[12]; //质量数组
	short int iMhour; //质量个数

	//jzw 20230301 判断安全阀起跳相关数据
	short int isBreak; //是否起跳 0未起跳  1起跳
	float Pre_P;//上一实测压力
	double breakDate;  // 安全阀起跳时刻
	float Mbreak[12];
	short int iMbreak; //质量个数

	////////////////////// 中间结果
	float P0;// 初始压力 
	float T0;//初始温度
	float Q0;  // 初始内能
	float Tn;//终了温度，根据Pn计算得到
	float RhoLimit;// 最小液体密度
	float RhoLn;// 起跳压力对应的液体密度, 用于是否涨罐的判断

	float Dis;  // 根据经纬度计算的移动距离
	
	float Record_Tg;//存储每次从传感器读的数据，气体温度
	float Record_Tl;//存储每次从传感器读的数据，气体温度

	float LQdLng1;// 理论日漏热量
	float SQdLng2;//需要输入


	float lamda; //时间安全系数
	float VLp;//压力计算得到液相体积
	float VLf;//充装率计算得到液相体积
	float VGp;//压力计算得到气相体积
	float VGf;//充装率计算得到气相体积

	float TLp;//压力计算得到液相温度
	float TavgL;//液相平均温度

	float K2; //k2修正系数
	float Ky; //运动修正
	float Kr; //Russa修正
	float Kf; //热不均匀修正

	///////////
	float P; 
	float Pm;  
	float VL; 
	float RhoL; 
	float HL; 
	float QL;  
	float VG; 
	float RhoG; 
	float HG; 
	float QG; 
	float PQ; 
	float Pfai;
	float PRhoLimit;
	float PQdLNG;  
	
	float VLavg;//平均液相体积
	float fai_p; //实时压力插值计算充装率
	float VGavg;//平均液相体积

	

	float mG;//液相质量 cqr-201301
	float mL;//气相质量 cqr-201301
	float rhoG;//液相密度 cqr-201301
	float rhoL;//气相密度 cqr-201301
	float rhoL_n;//终了气相密度 cqr-201301
	float rhoG_n;//终了液相密度 cqr-201301
	
	///////////////////////////////////////////////////////////////
	
	
	
	
	
	
	///////////////////////////////////////

	////第6类，计算结果	
	
	float MaintainTime;  // 预报维持时间

	int sfbm;//算法编码
	double ztbm; //状态编码 jzw 20230303

	int sfrz1; //15位 日志编码
	int sfrz2; //预留日志
	int sfrz3; //预留日志

	float BOG;//BOG释放量
	float XHL;//燃料平均日消耗量

	float jgY1;  //结果预留变量
	float jgY2;
	float jgY3;
	float jgY4;
	float jgY5;
	float jgY6;
	float jgY7;
	float jgY8;
	float jgY9;
	float jgY10;



	////////  拟合并进日志编码 //////////////////////////
	// int RZ[50];


	///// 拟合并进状态编码
	//20220506增加变量
	short int CY;//储运状态  01静置，02运输，03充装，04利用，05异常
	short int CZ;//充装状态 11满罐，12涨罐，21空罐起跳，22空罐不起跳
	short int LR;//满罐计算方法，01 理论 ,02 实测 , 03 综合
	short int GJ; //告警信号 02 温度高于150K
	short int YJ;//预警信号

	//int DisplayInfo; // 预报状态
	
	/////  重复变量，拟去除  //////////////////////////

	//cqr 增加2个变量
	//int TankState;
	//int CalModel;

	
	
	 
};

////中间计算数据   
//实时物化参数
struct PhysicochemicalPara
{
	float ch4;//甲烷成分比
	float P; // 压力
	float m;  // 总质量
	float VL; //液体体积
	float RhoL; //液体密度
	float HL; // 液体焓值
	float QL;  // 液体内能
	float VG; //气体体积
	float RhoG; //气体密度
	float HG; // 气体焓值
	float QG; // 气体内能
	float Q; //内能
	float fai;//充装率
	float RhoLimit;// 最小液体密度
	float QdLNG;  // 实测每日漏热量
	float Amp;  // 运动幅度
	float fr;  //运动频率
};

////中间计算数据   
//每日漏热量记录
struct DailyHeatLoss
{
	short int nday;  //记录天数
	short int nData; // 每天读取数据条数
	float DayNow;
	int iday;// 记录数据个数
	float Qi_0; // 起始时间的内能
	float Qi;  // 当天内能
	float QdAvg;
	float Qday[20];
	short int day[20]; //记录Qday对应的天数
};

////实时采集数据
struct MonitoringData
{
	double Record_ID;//存储每次从传感器读的数据，ID
	//unsigned char  Record_Date[12]; //存储每次从传感器读的数据，日期时间
	double Record_Date;
	float Record_T;//存储每次从传感器读的数据，温度
	float Record_P;//存储每次从传感器读的数据，压力，
	float Record_L;//存储每次从传感器读的数据，充装率
	float Record_Amp_x;//运动幅度
	float Record_Amp_y;//运动幅度
	float Record_Amp_z;//运动幅度

	float Record_fr_x;//运动频率
	float Record_fr_y;//运动频率
	float Record_fr_z;//运动频率
	float  Record_OutT;//环境温度

	//20220506增加变量
	float WE;//经度
	float SN;//纬度

	float Record_Tg;//存储每次从传感器读的数据，气体温度
	float Record_Tl;//存储每次从传感器读的数据，气体温度

	float Yewei;//液位
	float zkd;// 真空度
	float dP; //压差

	float mdY2;// 预留变量
	float mdY3;
	float mdY4;
	float mdY5;
	float mdY6;
	float mdY7;
	float mdY8;
	float mdY9;
	float mdY10;

};


#pragma pack(pop)


//计算函数正式定义在main函数后面
void SetTankPara(struct TankPara *tank);
void InitConstantPara(struct TankPara *tank);
void InitTankPara(struct TankPara *tank);//cqr-20230213
void InitLoadPara(struct TankPara *tank);//cqr-20230219
void PredictTime( struct MonitoringData * MData, struct TankPara * tank );
void TankInit(int InitTime, struct TankPara *tank, struct MonitoringData *data);
void ConvertDateFormat(double Record_Date, struct tm *Date_Str );    //转换日期格式
void SaveDailyHeatLoss( struct TankPara * Qds );
float Calculate_m(struct  TankPara *tank ,struct  MonitoringData *data);
void CalculatePhyChemPara(struct TankPara *tank, float p, struct PhysicochemicalPara *PCi );

float CalculateLiquidTemperature(float ch4,float x);
float CalculateLiquidRhoAtP0(float ch4);
float CalculateLiquidRho(float ch4,float x);
float CalculateLiquidPressure(float ch4,float x);
float CalculateLiquid_H(float ch4,float x);
float CalculateGasRho(float ch4,float x);
float CalculateGasH(float ch4,float x);
float CalculateLiquidC(float ch4,float x);

float FullTankAlgorithm(struct TankPara *tank,struct MonitoringData *data);
float EmptyTankAlgorithm(struct TankPara *tank,struct  MonitoringData *data);

int ReadMontoringDataFile(struct  MonitoringData *data);

float t1ByTheoretical(struct TankPara *tank,struct  MonitoringData *data);
float t2ByMeasuredData(struct TankPara *tank,struct  MonitoringData *data) ;
double getDistanceFromGPS(double lat_a, double lng_a, double lat_b, double lng_b);
                    


#endif 
