{+doc
+NOMBRE: Act_Bat
+CREACION: 23.02.1994
+AUTORES:  gcp,rch
+REGISTRO:
+TIPO: Unidad Pascal.
+PROPOSITO:    Implementaci¢n del TActor Bater¡a.
+PROYECTO: SOLAR.

+REVISION:
+AUTOR:
+DESCRIPCION:
  Definici¢n del Actor TBateriaHD
  En este actor se agrega la definicion de los par metros que definen
la forma en que se degrada la bater¡a.-
  Al igual que TBateriaHD (definido en ActBat02) TBateriaHD construye
internamente un histograma de ciclado diario. El agregado es la definicion
en el actor de los par metros de degradaci¢n.-
-doc}
unit ActBat04;

interface

uses
  SysUtils, ActBat02, xMatDefs, autoesca;

type

  TBateriaHD = class(TBateria01)
    x1, { [pu] profundidad de descarga x1 }
    x2, { [pu] profundidad de descarga x2 }
    y1, { [u] ciclos de vida a x1 }
    y2: { [u] ciclos de vida a x2 }
    NReal;

    A_Degradante: NReal; // Valor al final de la vida de la suma degradante
    beta_Degradante: NReal; // beta de la formula de cálculo dela SumaDegradante
    SumaDegradante: NReal; // degradación acumulada de la batería.
    NHorasEnSumaDegradante: integer; // cantidad de días acumulados

    ultima_fDeg: NReal; // ultimo valor calculado de f_degradante
{$IFDEF WRCAPBAT}
    fcapbat: textfile;
{$ENDIF}

    constructor Create(xNombre: string;
      xCN, xTN, xCT, xImaxR, xImaxD, xVN, xPM: NReal; xng: NReal;
      xx1, xx2, xy1, xy2: NReal);
    function DegradacionAnual: NReal; virtual;


    // Mira la variación de energía Co y aumenta la SumaDegradante
    procedure CadaHora; override;

    // en caso de cambiar el banco de baterías, corresponde
    // llamar eta función para reiniciar el acumulador de degradación.
    procedure LimpiarSumaDegradante;

    function f_degradante(xCo: NReal): NReal;

    procedure Free; override;
  end;



implementation

{ m‚todos de TBateriaHD }

procedure TBateriaHD.Free;
begin
{$IFDEF WRCAPBAT}
  closefile(fcapbat);
{$ENDIF}
  inherited Free;
end;

constructor TBateriaHD.Create(xNombre: string;
  xCN, xTN, xCT, xImaxR, xImaxD, xVN, xPM: NReal; xng: NReal;
  xx1, xx2, xy1, xy2: NReal);
begin
  inherited Create(xNombre, xCN, xTN, xCT, xImaxR, xImaxD, xVN, xPM, 'xx', xng);

{$IFDEF WRCAPBAT}
  assignfile(fcapbat, 'capbat.xlt');
  rewrite(fcapbat);
{$ENDIF}

  x1 := xx1;
  x2 := xx2;
  if x1 > x2 then
    raise Exception.Create('TBateriaHD.Create ...> xx1, debe ser menor que xx2');

  y1 := xy1;
  y2 := xy2;

  if y2 > y1 then
    raise Exception.Create('TBateriaHD.Create ...> xy1, debe ser mayor que xy2');


  (*
      y = A_degradante * exp( - beta_degradante * x )

      y2/y1= exp( -beta_degradante * ( x2-x1 ) )

      ln( y2/y1 ) = -beta_degradante * (x2-x1 )

      beta_degradante= -ln(y2/y1)/(x2-x1)
      A_degradante= y1* exp(beta_degradante*x1)


  *)

  beta_Degradante := -ln(y2 / y1) / (x2 - x1);
  A_Degradante := y1 * exp(beta_degradante * x1);
  SumaDegradante := 0;

end;

function TBateriaHD.f_degradante(xCo: NReal): NReal;
var
  u: NReal;
begin
  u := (CN - xCo) / CN;
  if u >= Self.x1 then
    Result := 0.5 * exp(beta_Degradante * u)
  else
    Result := 0.5 * exp(beta_Degradante * x1) / x1 * u;
end;

procedure TBateriaHD.CadaHora;
var
  fdeg: NReal;
begin

  // Ahora calculamos la degradación asociada a la variación de Co
  fdeg := f_degradante(CargaActual);
  SumaDegradante := SumaDegradante + abs(fdeg - Self.ultima_fDeg);
  Self.ultima_fDeg := fdeg;

  Inc(NHorasEnSumaDegradante);

{$IFDEF WRCAPBAT}
  writeln(fcapbat, CargaActual, #9, NHorasEnSumaDegradante, #9,
    SumaDegradante, #9, Self.A_Degradante);
{$ENDIF}

end;

procedure TBateriaHD.LimpiarSumaDegradante;
begin
  NHorasEnSumaDegradante := 0;
  SumaDegradante := 0;
  ultima_fDeg := 0;
end;

function TBateriaHD.DegradacionAnual: NReal;
var
  k: integer;
  x: NReal;
  PDD, Deg, ciclos: NReal;
begin
  Deg := 0;
  x := Ciclado.x1 - Ciclado.ddx / 2;
  for k := 1 to Ciclado.NPDiv do
  begin
    x := x + Ciclado.ddx;
    PDD := x / CN;
    ciclos := exp10(log(y2) + (log(y2) - log(y1)) / (x2 - x1) * (PDD - x2));
    Deg := Deg + Ciclado.res_peso(k) * 0.2 / ciclos * 365;
  end;
  DegradacionAnual := Deg;
end;


end.
