//---------------------------------------------------------------------------
#include <math.h>

#pragma hdrstop

#include "CheckExecuteU.h"
#include "Data_Gen.h"
#include "Steel_param_ARSS.h"
#include "ListConst.h"
#include "ProcExt.h"
#include "ElementCheckFunction.h"
#include "sigma_beam.h"
#include "Get_param_sect_func.h"
#include "CheckFunction.h"
#include "SelectProfilSect.h"
#include "message.h"
#include "Get_param_sect_func.h"


//#define  DEBUG

//-----------------------------------------------------------------------------------------
// Выполнение проверок для двутавра
int TCheckExecute::CheckExecuteU(DATA_CHECK_U *data_check, int *n_krit, double *krit, int *nnel_krit) {
   double Ry, Ey;
   int i, rc;
   int ngroup, Nelem; // число элементов группы
   GEOM_PARAM_SECT param_sect;
   GEOM_PARAM_SECT param_netto;
   STEEL_PARAM steel_param;
   double i_zz, i_yy;
   double lambdaX[100], lambdaY[100];   // гибкости в плоскостях XZ и YZ
   double lambda_x[100], lambda_y[100]; // условные гибкости
   double lambda_w; // условная гибкость стенки
   double lambda_f; // условная гибкость поясов
   double h_, t_, hef;
   double bef_1, bef_2, tef_1, tef_2;
   double fi_x[100], fi_y[100];
   double fi_e[100], fi_ey[100], fi_exy[100];
   double lambda_f1, lambda_f2;
   double N_, Q_, Q_y, M_, M_y;
   int type_sect;
   double Ryw, Rsw;
   double gamma_m;
   double sigma_comm[6]; // напряжение в угловых точках 0, 1 - верхний пояс, 1, 2 - нижний пояс
   double Forces[8];
   double Aw, Af;
   double Ad[100], Ar;
   // Условные гибкости поясов в плоскости поясов
   double lambda_f1Y[100], lambda_f2Y[100];
   // Гибкости поясов в плоскости поясов
   double Lambda_f1Y[100], Lambda_f2Y[100];
   int n_elem, n_elem_rep;
   MATER_PARAM mater_param;
   int index_M_max0, index_N_plus0, index_N_minus0;
   double lambda_uw[100]; // наибольшая условная гибкость стенки
   double lambda_uf[100]; // наибольшая условная гибкость поясов
   double h_sect, b_sect;
   CHECK_STAB_PARAM Check_stab_param;
   CHECK_ELEM_PARAM_U *Cp;

	  Cp = &(Check_param);


   //, &index_M_max0, &index_N_plus0, &index_N_minus0);
   for (i=0; i<50; i++)
	 krit[i]=0;

   Cp->edge_param[0][0] = 1e6; Cp->edge_param[0][1] = Cp->edge_param[0][2] = 0;
   Cp->edge_param[1][0] = 1e6; Cp->edge_param[1][1] = Cp->edge_param[1][2] = 0;
   Cp->edge_param[2][0] = 1e6; Cp->edge_param[2][1] = Cp->edge_param[2][2] = 0;
   edge_param[0][0] = 1e6; edge_param[0][1] = edge_param[0][2] = 0;
   edge_param[1][0] = 1e6; edge_param[1][1] = edge_param[2][2] = 0;
   edge_param[2][0] = 1e6; edge_param[2][1] = edge_param[2][2] = 0;

   // номер группы проверки
   ngroup = NumNameGroup[0];
   Nelem = NelemInGroup[ngroup];
   // Максимальная высота полки двутавра
   double t_max = MAX(Sect_Elem_Group[ngroup].com_sect.dvutavr.h1, Sect_Elem_Group[ngroup].com_sect.dvutavr.h2);
   //  Получить таблицу свойств стали по марке стали
   rc = Get_Mater_param(MaterPropU_prof.title, &mater_param);
   if (rc>0) return rc;
   // Проверить границы толщин и получить диапазон толщин
   double thick_range[2];
   rc = Get_thick_range(MaterPropU_prof.title, t_max, thick_range);
   if (rc==1 || rc==2) {  // толщины не попадают в диапазон толщин
	 krit[0] = 100;
	 *n_krit = 1;
	 return 0;
   }
   SelectProfilSectForm->Data_select.t0 = thick_range[0];
   SelectProfilSectForm->Data_select.t1 = thick_range[1];

	// Расчетное сопротивление растяжению, сжатию и изгибу по пределу текучески
   Ry = Steel_param_Ry(MaterPropU_prof.title, t_max, &rc, true);
	// Расчетное сопротивление растяжению, сжатию и изгибу по пределу текучески
   SelectProfilSectForm->Data_select.Ry = Ry;
   SelectProfilSectForm->Data_select.Run = Steel_param_Run(MaterPropU_prof.title, t_max, &rc, false);

   //---Material_Number = data_check->index_mater_polka;


   Ey = MaterPropU_prof.E;
   //Rs = 0.58*Ry;

   if (Sect_Elem_Group[ngroup].com_sect.dvutavr.n_group==-1) { // Сварной двутавр
	  Ryw = Steel_param_Ry(MaterPropU_prof.title, Sect_Elem_Group[ngroup].com_sect.dvutavr.b, &rc, true);
	  if (rc>0) {
		krit[0] = 100;
		return rc;
	  }
   }
   else  // Прокатной (фасонный)
	  Ryw = Ry;

   Rsw = 0.58*Ryw;               // Предел сдвига

   gamma_m = MaterPropU_prof.gamma_m;           // Коэффициент надежности по материалу

   rc = Steel_param(MaterPropU_prof.title, t_max, &(steel_param), false);
   if (rc>0)
	 return rc;

   // Расчетное временное сопротивление по растяжению, сжатию и изгибу
   double Ru = steel_param.Ru;

   // Учет дополнительного коэфффициента условий работы (сейсмического)
   //---data_check->gamma_c *= gamma_tr;
   // Вычислить геометрические характеристики сечения группы
   //---------------------------------------------------------------------------------------
   // Модификация сечения перфорированной балки
   if (data_check->flag_perfor) {
	  Modif_perfor(data_check, &(Sect_Elem_Group[ngroup].com_sect.dvutavr));
   }
   Get_param_sect_comm(Sect_Elem_Group[ngroup].type_sect, &(Sect_Elem_Group[ngroup].com_sect), &param_sect);

   memcpy((char*)&param_netto, (char*)&param_sect, sizeof(GEOM_PARAM_SECT));
   i_zz = sqrt(param_sect.Izz/param_sect.Ar);
   i_yy = sqrt(param_sect.Iyy/param_sect.Ar);
   //-----
   if (data_check->flag_netto) {
	 Get_param_sect_netto(&(Sect_Elem_Group[ngroup].com_sect.dvutavr), &param_netto,
						   data_check->diametr, data_check->num_holes, data_check->space, data_check->step);
	 //i_zz = sqrt(param_netto.Izz/param_netto.Ar);
	 // i_yy = sqrt(param_netto.Iyy/param_netto.Ar);
   }
   type_sect = Sect_Elem_Group[ngroup].type_sect;
   if (Sect_Elem_Group[ngroup].type_sect==TAVR &&  data_check->flag_composed)
	 type_sect = DVUTAVR;
   // Гибкость элемента
   for (i=0; i<NRSU; i++) {
	 n_elem = ListElem_RSU[i];

	 lambdaX[n_elem] = data_check->length_XZ[n_elem]/i_zz;
	 lambdaY[n_elem] = data_check->length_YZ[n_elem]/i_yy;
   // Условная гибкость элемента
	 lambda_x[n_elem] = lambdaX[n_elem]*sqrt(Ry/Ey);     // в плоскости стенки
	 lambda_y[n_elem] = lambdaY[n_elem]*sqrt(Ry/Ey);     // в плоскости поясов
   // Вычисление fi_y - коэффициент устойчивости в плоскости поясов при центальном сжатии
	 fi_y[n_elem] = Round(Fun_fi_713(type_sect, lambda_y[n_elem], 1), 3);
	 fi_y[n_elem] = MAX(0.001, fi_y[n_elem]);

   // Вычисление fi_x коэффициент устойчивости в плоскости стенки при центальном сжатии
	 fi_x[n_elem] = Round(Fun_fi_713(Sect_Elem_Group[ngroup].type_sect, lambda_x[n_elem], 0), 3);
	 fi_x[n_elem] = MAX(0.001, fi_x[n_elem]);
   // Значение условной предельной гибкости стенки при центальном сжатии
	 double lambda_r = MAX(lambda_x[n_elem], lambda_y[n_elem]);
	 lambda_uw[n_elem] = Fun_lambda_uw_cent(type_sect, lambda_r );
   // Значение условной предельной гибкости в плоскости поясов при центральном сжатии
	 lambda_uf[n_elem] = Fun_lambda_uf_cent(type_sect, lambda_r);

   }

   type_sect = Sect_Elem_Group[ngroup].type_sect;

   h_ = Sect_Elem_Group[ngroup].com_sect.dvutavr.h;
   h_sect = Sect_Elem_Group[ngroup].com_sect.dvutavr.h + Sect_Elem_Group[ngroup].com_sect.dvutavr.h1 +
			Sect_Elem_Group[ngroup].com_sect.dvutavr.h2;
   b_sect = Sect_Elem_Group[ngroup].com_sect.dvutavr.b1;
   hef = h_ - 2*param_sect.Rad;

   t_ = Sect_Elem_Group[ngroup].com_sect.dvutavr.b;
   bef_1 = Sect_Elem_Group[ngroup].com_sect.dvutavr.b1;
   tef_1 = Sect_Elem_Group[ngroup].com_sect.dvutavr.h1;
   bef_2 = Sect_Elem_Group[ngroup].com_sect.dvutavr.b2;
   tef_2 = Sect_Elem_Group[ngroup].com_sect.dvutavr.h2;
   Af = MIN(bef_1*tef_1, bef_2*tef_2);   // меньшая площадь пояса
   Aw = t_*h_;

   lambda_w = (hef/t_)*sqrt(Ryw/Ey);
   // Условные гибкости свеса поясов
   lambda_f1 = (((bef_1 - t_)*0.5 - param_sect.Rad)/tef_1)*sqrt(Ry/Ey);
   lambda_f2 = (((bef_2 - t_)*0.5 - param_sect.Rad)/tef_2)*sqrt(Ry/Ey);
   for (i=0; i<NRSU; i++) {
	 n_elem = ListElem_RSU[i];
   // Гибкости поясов в плоскости поясов
	 Lambda_f1Y[n_elem] = (data_check->step_ext[n_elem]*3.4641/bef_1);    // 3.4641 = sqrt(12)
	 Lambda_f2Y[n_elem] = (data_check->step_int[n_elem]*3.4641/bef_2);
   // Условные гибкости поясов в плоскости поясов
	 lambda_f1Y[n_elem] = Lambda_f1Y[n_elem]*sqrt(Ry/Ey);
	 lambda_f2Y[n_elem] = Lambda_f2Y[n_elem]*sqrt(Ry/Ey);
   }

   //--------------------------------------------------------------------------
   // Центрально-растянутые
   if (data_check->index_type == CENTR_TENSION) {
	  double k_, lambda_u;
	  double krit_tens_max = 0;
	  int RSU_tens_max;

	  // Зануление критериев
	  for (i=0; i<data_check->num_krit; i++)
		krit[i] = 0;
	  for (i=0; i<NRSU; i++) {
		n_elem = ListElem_RSU[i];
		if (!CheckElem[i][0])
		  continue;
		n_elem_rep = n_elem;
		N_ = Elem_RSU[i][0]*1000;

		//sigma_beam_comm(&param_sect, Forces, sigma_comm);
		// 1. ------------------------------------------------------
		if (data_check->Checked[0]) {
		  double Ryn;
		// Расчет на прочность, п.7.1.1. ф.(5)
		  if (steel_param.Ryn <= 440)
			Ryn = Ry;
		  else
			Ryn = steel_param.Ru/data_check->koeff_material_nadeghn;
		  double krit_0 = (ABS(N_))/(param_netto.Ar*Ryn*data_check->gamma_c);
		  if (krit[0] < krit_0) {
			 Cp->NT_ = ABS(N_);
			 Cp->Ry = Ryn;
		  }

		  MAXNNEL(krit[0], krit_0, 0);
		}
		// Определение коэффициента k_ в сответствии с п. 10.4.2
		if ((data_check->index_otvetstv == 0 || data_check->index_otvetstv == 1) &&
			   data_check->index_group < 3)
			k_=1;
		else
			k_=1.1;
		if (data_check->Checked[1]) {
		// Проверка предельной гибкости в плоскости поясов, п. 10.4.1, 10.4.2, табл. 33
		   lambda_u = data_check->Limit_lambda_plus;
		   if (krit[2] < lambdaY[n_elem]/(k_*lambda_u)) {
			 Cp->lambdaY = lambdaY[n_elem];
		   }
		   MAXNNEL(krit[1], lambdaX[n_elem]/(k_*lambda_u), 1);
		}
		if (data_check->Checked[2]) {
		// Проверка предельной гибкости в плоскости стенки, п. 10.4.1, 10.4.2, табл. 33
		   lambda_u = data_check->Limit_lambda_plus;
		   if (krit[2] < lambdaY[n_elem]/(k_*lambda_u)) {
			 Cp->lambdaX = lambdaX[n_elem];
		   }
		   MAXNNEL(krit[2], lambdaY[n_elem]/(k_*lambda_u), 2);
		}
		for (int j=0; j<3; j++) {
		  if (krit[j] > krit_tens_max) {
			krit_tens_max = krit[j];
			RSU_tens_max = n_elem;
		  }
		}
	  }
	  n_elem = ListElem_RSU[RSU_tens_max];
		  memcpy((char*)&(Cp->param_sect), (char*)&(param_sect), sizeof(GEOM_PARAM_SECT));
		  memcpy((char*)&(Cp->param_netto), (char*)&(param_netto), sizeof(GEOM_PARAM_SECT));
		  memcpy((char*)&(Cp->Sect_Elem), (char*)&(Sect_Elem_Group[0]), sizeof(DATA_SECT_SCAD));
		  Cp->RSU[0][0] = Elem_RSU[RSU_tens_max][0];
		  Cp->num_elem[0] = n_elem;
		  strcpy(Cp->Steel, MaterPropU_prof.title);
		  Cp->Ryn = steel_param.Ryn;
		  Cp->hsect = h_sect;
		  Cp->bsect = b_sect;
		  Cp->bef = bef_1;
		  Cp->hef = hef;
		  Cp->A_netto = param_netto.Ar;
		  Cp->k_ = k_;
		  Cp->lambda_x = lambda_x[n_elem];
		  Cp->lambda_y = lambda_y[n_elem];
		  Cp->lambda_w = lambda_w;
		  Cp->lambda_uw = lambda_uw[n_elem];
		  Cp->lambda_f = lambda_f;
		  Cp->lambda_ux = lambda_u;
		  Cp->lambda_uy = lambda_u;
		  Cp->lambda_f1 = lambda_f1;
		  Cp->lambda_f2 = lambda_f2;
		  Cp->fi_x = fi_x[n_elem];
		  Cp->fi_y = fi_y[n_elem];
		  Cp->Ad = Ad[n_elem];

	  memcpy((char*)&Data_check_U, (char*)data_check, sizeof(DATA_CHECK_U));
   }


#include "CheckExecuteU%Centr_Compression.cpp"
#include "CheckExecuteU%Compression_Bending_CV.cpp"
#include "CheckExecuteU%Tension_Bending.cpp"

   //--------------------------------------------------------------------------
   // Изгибаемые 1-го класса с переменной высотой стенки , табл. 2.2.3 ТЗ
   if (data_check->index_type == BENDING) {
	  rc = CheckBending(data_check, n_krit, krit, nnel_krit);
   }
   //!!! Здесь должно быть реальное количество
   // *n_krit = data_check->num_krit;
   *n_krit = 100;

   return 0;
}
//---------------------------------------------------------------------------
// Модификация сечения перфорированной балки
void Modif_perfor(DATA_CHECK_U *data_check, SECT_DVUTAVR *sect_perfor)  {
	double h0 = sect_perfor->h + sect_perfor->h1 + sect_perfor->h2;
	double k_att = data_check->perfor_attit/3;
	data_check->diametr[0] = data_check->diametr[1] = data_check->diametr[2] = 0;
	data_check->space[0] = data_check->space[1] = data_check->space[2] = 0;
	data_check->step[0] = data_check->step[1] = data_check->step[1] = 0;
	data_check->perfor_h = Round(k_att*h0, 0) - 1;
	data_check->perfor_b = Round(k_att*h0/tan(data_check->perfor_alfa/RADIAN), 0);
	data_check->perfor_a = Round(k_att*h0/sin(data_check->perfor_alfa/RADIAN), 0) + 2;
	data_check->diametr[3] = 2*data_check->perfor_h;
	data_check->space[3] = Round(data_check->perfor_attit*h0 - 2*data_check->perfor_h, 0);
	data_check->step[3] = 2*(data_check->perfor_a + data_check->perfor_b);
	data_check->num_holes[0] = data_check->num_holes[1] = data_check->num_holes[2] = 0;
	data_check->num_holes[3] = 1;
		// Диаметр отверстий: внешний пояс, внутренний пояс, стенка внешняя, стенка внутренняя
		// Расстояние от оси стенки до первого отверстия: внешний пояс, внутренний пояс, стенка внешняя, стенка внутренняя
		// Шаг отверстий: внешний пояс, внутренний пояс, стенка внешняя, стенка внутренняя
		// Количество отверстий: внешний пояс, внутренний пояс, стенка

}
//---------------------------------------------------------------------------
//--------------------------------------------------------------
// Получить тип НДС для участка
int GetIndex_NDS(DATA_CHECK_U *data_check, double N_, double M_, double ix_sect, double l_ef, double m_ef)
{
	int TypeNDS;
	int type_check;
	TypeNDS = -1;
	type_check = -1;
	//1. Центрально-растянутые
	  if (N_ >= data_check->N_plus*1e3 && (ABS(M_)) < data_check->M_max_i*1e6) {
		type_check = CENTR_TENSION;
		TypeNDS = chCENTR_TENSION;
	  }
	  //2. Центрально сжатые
	  if (N_ <= data_check->N_minus*1e3 &&
		 (ABS(M_/N_)) <= ix_sect/20 + l_ef/750) {
		type_check = CENTR_COMPRESSION;
		TypeNDS = chCENTR_COMPRESSION;
	  }
	  //3. Изгибаемые
	  if ((ABS(M_)) > data_check->M_max_i*1e6 && m_ef > 20) {
		type_check = BENDING;
		TypeNDS = chBENDING;
	  }
	  //4. Растянуто-изгибаемые (внецентренно-растянутые)
	  if (N_ >= data_check->N_plus*1e3 && (ABS(M_)) >= data_check->M_max_i*1e6 && m_ef <= 20) {
			type_check = TENSION_BENDING;
			TypeNDS = chTENSION_BENDING;
	  }
	  //5. Сжато-изгибаемые (внецентренно-сжатые)
	  if (N_ <= data_check->N_minus*1e3 && (ABS(M_)) >= data_check->M_max_i*1e6 &&
		 (ABS(M_/N_)) > ix_sect/20 + l_ef/750 && m_ef <= 20) {
		type_check = COMPRESSION_BENDING;
		TypeNDS = chCOMPRESSION_BENDING;
	  }
	  return type_check;
	  //return TypeNDS;
}
//----------------------------------------------------------------
#include "CheckExecuteU%SetConditionCheck.cpp"

#include "CheckExecuteU%CheckExecuteU_Tube.cpp"

//#include "CheckElementU%CheckWeld.cpp"
#include "CheckElementU%CheckWeld_CV.cpp"
#include "CheckExecuteU%Bending_CVfunc.cpp"


