unit unodocombustible;

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

interface

uses
  xmatdefs, usimplex, uglobs,
  SysUtils,
  Classes,
  ucosa,
  uCosaConNombre,
  uActores,
  ufichasLPD,
  uCombustible,
  uFuentesAleatorias,
  ufechas;

resourcestring
  rsNodoCombustible = 'Nodo Combustible';

type

  { TNodoCombustible }

  TNodoCombustible = class(TActor)
  public
    (**************************************************************************)
    (*               A T R I B U T O S   P E R S I S T E N T E S              *)
    (**************************************************************************)

    combustible: TCombustible;
    (**************************************************************************)

    cmg: TDAOfNReal;


    constructor Create(capa: integer; nombre: string; nacimiento, muerte: TFecha;
      lpdUnidades: TFichasLPD; combustible: TCombustible;
  xFuenteIdxP: TFuenteAleatoria; xBorneIdxP: string);

    function Rec: TCosa_RecLnk; override;
    procedure BeforeRead(version, id_hilo: integer); override;
    procedure AfterRead(f:TArchiTexto); override;


    procedure PrepararMemoria( Catalogo: TCatalogoReferencias; globs: TGlobs); override;

    function InfoAd_: string; override;
    class function DescClase: string; override;

    procedure opt_nvers(var ivar, ivae, ires: integer); override;
    procedure opt_cargue(s: TSimplex); override;
    procedure opt_fijarRestriccionesDeCaja(s: TSimplex); override;
    procedure opt_leerSolucion(s: TSimplex); override;

    function getNombreVar(ivar: integer; var nombre: string): boolean; override;
    function getNombreRes(ires: integer; var nombre: string): boolean; override;
    destructor destroy; override;
    procedure PubliVars; override;
  end;


procedure AlInicio;
procedure AlFinal;

implementation

//-------------------
// Métodos de TNodoCombustible
//===================
constructor TNodoCombustible.Create(capa: integer; nombre: string;
  nacimiento, muerte: TFecha; lpdUnidades: TFichasLPD;
  combustible: TCombustible;
  xFuenteIdxP: TFuenteAleatoria; xBorneIdxP: string );
begin
  inherited Create(capa, nombre, nacimiento, muerte, lpdUnidades,
  xFuenteIdxP, xBorneIdxP );
  self.combustible := Combustible;

end;

function TNodoCombustible.Rec: TCosa_RecLnk;
begin
  Result:=inherited Rec;
  Result.addCampoDef_ref('combustible', TCosa(combustible), Self);
end;

procedure TNodoCombustible.BeforeRead(version, id_hilo: integer);
begin
  inherited BeforeRead(version, id_hilo);
end;

procedure TNodoCombustible.AfterRead(f:TArchiTexto);
begin
  inherited AfterRead(f);
end;


procedure TNodoCombustible.PrepararMemoria(Catalogo: TCatalogoReferencias;
  globs: TGlobs);
begin
  inherited prepararMemoria(Catalogo, globs);
  setlength(cmg, globs.NPostes);
end;

function TNodoCombustible.InfoAd_: string;
begin
  Result := '';
end;

class function TNodoCombustible.DescClase: string;
begin
  Result := rsNodoCombustible;
end;

procedure TNodoCombustible.opt_nvers(var ivar, ivae, ires: integer);
begin
  // el nodo no agreaga variables de control
  Self.ires := ires;
  // El NODO agrega una restricción por cada POSTE
  ires := ires + globs.NPostes; //incremento ires en la cantidad de POSTES
end;

procedure TNodoCombustible.opt_cargue(s: TSimplex);
var
  ip: integer;
begin
  // nada, cada demanda carga el termino constante y cada generador los variables
  for ip := 0 to globs.NPostes - 1 do
    s.FijarRestriccionIgualdad(ires + ip);
end;

procedure TNodoCombustible.opt_fijarRestriccionesDeCaja(s: TSimplex);
begin
  // no tiene variables no tiene restricciones de caja
end;

procedure TNodoCombustible.opt_leerSolucion(s: TSimplex);
var
  iposte: integer;
  acmg: NReal;
begin
  // no tiene variables no tiene que leer las variables.
  // lo que podemos leer es el multiplicador de Lagrange para tener
  // el costo marginal del nodo.
  for iposte := 0 to globs.NPostes - 1 do
  begin
    //    cmg[iposte] := -s.ymult(ires + iposte) * globs.invDurPos[iposte] / combustible.MWh_por_Q1h;

    // USD/m3
    acmg := -s.ymult(ires + iposte) * globs.invDurPos[iposte] / 3600;

    acmg := acmg / combustible.pa.ro; // USD/kg
    acmg := acmg / combustible.pa.PCS; // USD/J
    acmg := acmg * J_por_BTU * 1.0e6; // USD/MBTU
    cmg[iposte] := acmg;
  end;

end;


function TNodoCombustible.getNombreVar(ivar: integer; var nombre: string): boolean;
begin
  Result := False;
end;

function TNodoCombustible.getNombreRes(ires: integer; var nombre: string): boolean;
begin
  if (ires >= self.ires) and (ires < self.ires + globs.NPostes) then
  begin
    nombre := self.nombre + 'res-nodo' + IntToStr(ires - self.ires + 1);
    Result := True;
  end
  else
    Result := False;
end;

destructor TNodoCombustible.destroy;
begin
  setlength(cmg, 0);
  inherited destroy;
end;

procedure TNodoCombustible.PubliVars;
begin
  inherited PubliVars;
  PublicarVariableVR('cmg', '[USD/MWh]', 6, 1, cmg, True, True);
end;











procedure AlInicio;
begin
  registrarClaseDeCosa(TNodoCombustible.ClassName, TNodoCombustible);
end;

procedure AlFinal;
begin
end;

end.
