unit UMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  mm = 0.001;
  um = 0.000001;
  t0oC = 273.15;
  epsilon = 0.000001;

type
    ChlazPole = array[1..201,1..2] of real;
    VstupPole = array[1..729,1..3] of real;
    TFormMain = class(TForm)
    BtnRun: TButton;
    LabelStep: TLabel;
    Label1: TLabel;
    procedure BtnRunClick(Sender: TObject);

  private
    { Private declarations }
    vstup:VstupPole;
    chlazeni:ChlazPole;
    procedure NactiVstup;
    procedure NactiChlaz;
    function GetHtc(x,int,s:real; mat:ChlazPole):real;
  public
    { Public declarations }
  end;

var
  FormMain: TFormMain;

implementation

uses Math, HCArrays, HCConduct, HCMaterial, HCModel, UPohMath, UPohStrConv;

{$R *.dfm}

function AddLeadingZeroes(const aNumber, Length : integer) : string;
begin
   result := SysUtils.Format('%.*d', [Length, aNumber]) ;
end;

procedure TFormMain.NactiVstup;
var
  soubor:textfile;
  numb:double;
  i,j:integer;
begin
  AssignFile(soubor,GetCurrentDir+'\vstupt.txt');
  i:=1; j:=1;
  Reset(soubor);
  while not Eof(soubor) do
  begin
    Read(soubor, numb);
    vstup[i,j]:=numb;
    if j=3 then begin
      j:=1;
      i:=i+1;
    end
    else j:=j+1;
  end;
  closefile(soubor);
end;


procedure TFormMain.NactiChlaz;
var
  soubor:textfile;
  numb:double;
  i,j:integer;
begin
  AssignFile(soubor,GetCurrentDir+'\chlazeni.txt');
  i:=1; j:=1;
  Reset(soubor);
  while not Eof(soubor) do
  begin
    Read(soubor, numb);
    chlazeni[i,j]:=numb;
    if j=2 then begin
      j:=1;
      i:=i+1;
    end
    else j:=j+1;
  end;
  closefile(soubor);
end;

function TFormMain.GetHtc(x,int,s:real; mat:ChlazPole):real;
var i:integer;
begin
i:=1;
x:=x-s;
while mat[i,1]<x do i:=i+1;
result:=int*(mat[i-1,2]+(x-mat[i-1,1])*(mat[i,2]-mat[i-1,2])/(mat[i,1]-mat[i-1,1]));
end;

procedure TFormMain.BtnRunClick(Sender: TObject);
var
  matDB: tMatDB;
  model: tHCModel;
  TinitC, TinitK, TokoliC: double;
  matIdxDeska: integer;
  matIdxOxid: byte;
  ai:integer; // aktualni index
  dt: double;
  max_err: double;
  s, filepref, radek:string;
  i, j:integer;
  dif:double; // pomocna promenna pro pocitani plochy
  tim:double; // pomocna promenna pro cas (porovnavani uvnitr cyklu)
  r:integer; // radek v souboru parametru
  TsC:real; // teplota povrchu ve stupnich celsia
  TinC:real; // teplota unvitr desky (ve zvolene hloubce) ve stupnich celsiovych
  soubor:TextFile; // pomocny soubor na ukladani dat
  minSize: double; // presnost modelu
  d:double; // tloustka vrstvy oxidu
  area:array[0..1] of real; // pole pro pocitani obsahu oblasti
  time:array[0..1] of real; // casy potrebne na ochlazeni
  coefs:array[0..1] of real; // koeficienty pro porovnani casu chlazeni
  temps:array[0..10000,0..1] of double; // pole s teplotami na povrchu oceli
  int, shift:double; //chlazeni
  TstopC:double;           // stop teplota
  sl:TStringList;
  TempFile:TextFile;
begin
  DecimalSeparator := '.';
  AssignFile(soubor,'vystupt.txt');
  ReWrite(soubor);
  filepref:=ExtractFilePath(Application.ExeName)+'Data\';

  NactiVstup;
  NactiChlaz;

  dt:=0.1;
  TstopC:=500;
  TokoliC:=17;

  for r:=1 to 110 do    { 729 }
   begin
   ai:=r;
   LabelStep.Caption:=IntToStr(r);

   tim:=vstup[ai,2];   // priradeni tepelne vodivosti okuji
   sl:=TStringList.Create;
   sl.LoadFromFile('MaterialDB.TXT');
   s:='373.15 '+Format('%.2f',[tim]);
   sl[88] := s;
   s:='1473.15 '+Format('%.2f',[tim]);
   sl[89] := s;
   sl.SaveToFile('MaterialDB.TXT');
   sl.Free;
   fHC_Init(matDB);
   fHC_LoadMatDB(matDB, PChar(ExtractFilePath(Application.ExeName)+'MaterialDB.TXT'));
   fHC_Prepare(matDB); // prepare material database

   minSize:=0.00001*mm;
   fHC_SetModelAccuracy(minSize);

   matidxOxid:=fHC_Find(matDB, PChar('scale'));
   matIdxDeska:=fHC_Find(matDB, PChar('ocel_reg'));

   tim:=vstup[ai,3];   // priradeni chlazeni
   int:=tim*1.6+1;
   shift:=tim*800+0;

   for j:=0 to 1 do
   begin
      time[j]:=0;
      area[j]:=0;
      coefs[j]:=0;

      i:=0;
      while temps[i,j]<>0 do
        begin
        temps[i,j]:=0;
        Inc(i);
        end;

      fHC_Init(model);

      if j=0
        then d:=0 else d:=vstup[ai,1]*um;

      s:='';
      for i:=1 to 3 do
        s:=s+Format('%.3f',[vstup[ai,i]])+' ';
      Label1.Caption:=s;      // zobrazeni aktualniho radku do Labelu1

      TinitC:=1200;
      TsC:=TinitC;
      TinitK:=TinitC+t0oC;
      temps[0,j]:=TinitC;

      fHC_Create1D(model, 0*mm, 500*mm, TinitK, matIdxDeska, 0);

      fHC_ReduceVolSizeX(model, 4*mm, 1, model.vBorderX.n-1);
      fHC_ReduceVolSizeX(model, 0.2*mm, 1, 2);
      fHC_ReduceVolSizeX(model, 10*um, 1, 4);
      fHC_ReduceVolSizeX(model, 1*um, 1, 2);

      fHC_InsertBox(model, 0, d, 0, 0, 0, 0, TinitK, matIdxOxid, 0);

      fHC_PrepareModel(model);

      fHC_SetBoundaryIntWE(model, model.bW_kind, 3); // kind of boundary condition - convection
      fHC_SetBoundaryFloatWE(model, model.bW_v, GetHtc(TsC,int,shift,chlazeni)); // temperature
      fHC_SetBoundaryFloatWE(model, model.bW_t, TokoliC+t0oC); // must be zero for kind=1,2
      fHC_SetBoundaryFloatWE(model, model.bW_e, 0.8); // must be zero for kind=1,2

      fHC_SetBoundaryIntWE(model, model.bE_kind, 2); // kind of boundary condition - heat flux
      fHC_SetBoundaryFloatWE(model, model.bE_v, 0); // heat flux
      fHC_SetBoundaryFloatWE(model, model.bE_t, 0); // must be zero for kind=1,2
      fHC_SetBoundaryFloatWE(model, model.bE_e, 0); // must be zero for kind=1,2

      fHC_ClearAccuracy(model);
      i:=0;
      // s:=Format('%5.5d', [i]);
      // fHC_SaveFloatChart4D_HCModel(model, model.vT, PChar(filepref+IntToStr(j)+'T'+s), -t0oC, 1/mm);
      // fHC_SaveIntChart4D_HCModel(model, model.vMat, PChar(filepref+IntToStr(j)+'Material'), 0, 1/mm); // ulozeni vytvoreneho modelu jako 2D graf

        repeat
        Inc(i);
        max_err:=Max(0.0001, 0.25*dt);
        fHC_HC1TimeStep(model, matDB, dt, 5, max_err);

        TinC:=fHC_GetInterpValHCModel(model.vT, model, d, 0, 0)-t0oC; // teplota na povrchu oceli
        TsC:=model.vT.r[0]-t0oC; // teplota na povrchu
        fHC_SetBoundaryFloatWE(model, model.bW_v, GetHtc(TsC,int,shift,chlazeni)); // aktualizace tepelneho toku

        Application.ProcessMessages;
        temps[i,j]:=TinC; // ulozeni teploty na povrchu oceli
        dif:=temps[i,0]-temps[i,j]; // rozdil s cistym povrchem
        area[j]:=area[j] + (dif + Abs(dif))/2; // obsah
        tim:=i*dt;
        if (TinC<=TstopC) and (time[j]=0) then time[j]:=tim; // cas potrebny k ochlazeni na zvolenou teplotu
        until (TinC<=TstopC) and (tim>=time[0]);
      fHC_Free(model);
      area[j]:=dt*area[j];
      end;

      for j:=1 to 1 do
        begin
        coefs[j]:=time[j]/time[0];
        radek:='';
        radek:=Format('%.f',[vstup[ai,1]]);
        radek:=radek+' '+Format('%.2f',[vstup[ai,2]]);
        radek:=radek+' '+Format('%.3f',[vstup[ai,3]]);
        radek:=radek+' '+Format('%.3f',[coefs[j]]);
        radek:=radek+' '+Format('%.3f',[area[j]]);
        writeln(soubor,radek);
        end;

      { AssignFile(TempFile,GetCurrentDir+'\temps.txt');
      ReWrite(TempFile);
      for i:=0 to 10000 do
        begin                       // zapsani teplot do souboru
        s:='';
        for j:=0 to 1 do
          s:=s+Format('%.1f',[temps[i,j]])+' ';
        writeln(TempFile,s);
        end;
      Closefile(TempFile);  }

  fHC_Free(matDB);
  end;
  // vne cyklu
  closefile(soubor);
  LabelStep.Caption:='konec';
end;

end.