unit uGNLGasoducto;

interface

uses
  Math, Classes, xMatDefs, uSimplex, uGlobs, uFechas, uEstados,
  uActores, uFichasLPD, uNodos,
  uGeneradores, uGNLListaContratoSuministro,
  UGNLSuministroMultiCliente,
  USuministroCombustible,
  uCosa,
  uConversions,
  uFuentesAleatorias,
  uconstantesSimSEE, SysUtils;

type

  { TGNLFichaGasoducto }

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

    T_ToP: NInt; // [dias] Tiempo de Take or Pay.
    V_ToP: NReal; // [unidad e Volumen] Volumen comprometido por el contrato Take Or Pay
    P_ToP: NReal;
    // [U$] Precio por Unidad de Volumen de combustible dentro del comprometido por Take or Pay
    P_ExtraToP: NReal;
    // [U$] Precio por Unidad de Volumen de combustible consumido por encima del volumen comprometido por Take or Pay

    (**************************************************************************)


    constructor Create(capa: integer; fecha: TFecha; periodicidad: TPeriodicidad;
      nombrecombustible: string; T_ToP: NInt; V_ToP: NReal; P_ToP: NReal;
      P_ExtraToP: NReal; ListaContratos: TGNLListaContratoSuministro);

     
    constructor Create_ReadFromText(f: TArchiTexto); override;
    procedure WriteToText(f: TArchiTexto); override;
    

    function infoAd_: string; override;
    procedure Free; override;
    



  published
    






  end;


  { TGNLGasoducto }
  (* Esta clase representará posibles suministros de combustible para
     los generadores termicos *)
  TGNLGasoducto = class(TGNLSuministroMultiCliente)
  public

    (**************************************************************************)
    (*               A T R I B U T O S   P E R S I S T E N T E S              *)
    (**************************************************************************)

    //Variables de Estado
    VDisp_ToP_Ini: NReal;  //Volumen disponible de ToP (varia entre V_ToP y 0
    NDisc: NInt; //Cantidad de discretizaciones del volumen

    (**************************************************************************)

    pa: TGNLFichaGasoducto;


    // El valor de la variable de estado X_V en el paso k y representa
    // el volumen restante (sin consumir) del contrato de ToP
    // vigente al inicio del paso  k.
    //Es lo que Tengo disponible en el tanque al inicio del paso
    //  (Xs_VDisp_ToP  es el estado al final del paso)
    X_VDisp_ToP: NReal;
    Xs_VDisp_ToP: NReal;

    // derivada del costo futuro respecto del Volumen Disponible ToP
    dCFdV: NReal;

    cvExtraToP: NReal;  //Costo Variable de lo consumido por sobre del ToP
    cvToP: NReal;  //Costo Variable del ToP (dCF/dV)
    cfToP: NReal;  //Costo Fijo del ToP (VToP * PTop)


    //Variables calculadas en el paso de tiempo durante la simulación
    //Volumen que despacho de combustible por debajo del disponible
    //en el paso de simulación (por lo tanto no aporta un costo extra al paso)
    VConsumido_ToP: NReal;

    //Volumen que despacho de combustible por sobre el disponible.
    //En este caso aporto al paso un costo P_ExtraToP por cada unidad de combustible
    VConsumido_Extra_Top: NReal;

    //Este es el volumen de combustible del ToP que se "tiró" al no ser consumido.
    VSobrante_ToP: NReal;


    V_ToP_sig: NReal;  //Volumen ToP del proximo embarque;

    fase: integer; // 1 = Inicio del TOP; 0= Dentro del periodo de TOP




    constructor Create(capa: integer; nombre: string; nombreCombustible: string;
      nacimiento, muerte: TFecha; lpdUnidades, lpd: TFichasLPD;
      VDisp_ToP_Ini: NReal; NDisc: NInt); virtual;


     
    constructor Create_ReadFromText(f: TArchiTexto); override;
    procedure WriteToText(f: TArchiTexto); override;
    

    function get_ires_volumen: NInt; override;
    function get_precio_combustible: NReal; override;
    function get_combustible: TCombustibleSGE; override;

    class function TipoFichaLPD: TClaseDeFichaLPD; virtual; abstract;
    //      procedure sim_PrintResultados_Encab_PotFirme(var fsal: textfile; kencab: integer ); virtual;
    //      procedure sim_PrintResultados_PotFirme(var fsal: textfile); virtual;
    procedure Free; override;
    class function DescClase: string; override;


    procedure PrepararMemoria(globs: TGlobs); override;
    procedure RegistrarParametrosDinamicos; override;


    procedure SorteosDelPaso(sortear: boolean); override;
    procedure PrepararPaso_ps; override;

    procedure Sim_Cronica_Inicio; override;

    procedure opt_nvers(var ivar, ivae, ires: integer); override;

    procedure opt_cargue(s: TSimplex); override;

    procedure EvolucionarEstado; 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;

    procedure PosicionarseEnEstrellita; override;
    procedure optx_nvxs(var ixr, ixd, iauxr, iauxd: integer); override;

    // imprime tabla de delta costo futuro de la variable de estado..
    procedure opt_PrintResultados_Encab(var fsal: textfile); override;
    procedure opt_PrintResultados(var fsal: textfile); override;

    procedure optx_RegistrarVariablesDeEstado(adminEstados: TAdminEstados); override;
    procedure ActualizarEstadoGlobal(flg_Xs: boolean); override;

    //      procedure Sim_PrintResultados_Encab(var fsal: textfile; kencab: integer ); override;
    //      procedure Sim_PrintResultados(var fsal: textfile); override;

    procedure PubliVars; override;
    //          function varsPSimRes3PorDefecto: TStringList; override;

    




    procedure AfterInstantiation; override;

  published
    




  end;

procedure AlInicio;
procedure AlFinal;
procedure TGNLGasoducto_cambioFichaPD(Actor: TCosa);

implementation


//------------------------------
// Métodos de TGNLFichaGasoducto
//==============================
constructor TGNLFichaGasoducto.Create(capa: integer; fecha: TFecha;
  periodicidad: TPeriodicidad; nombrecombustible: string; T_ToP: NInt;
  V_ToP: NReal; P_ToP: NReal; P_ExtraToP: NReal;
  ListaContratos: TGNLListaContratoSuministro);

begin
  inherited Create(capa, fecha, periodicidad, nombrecombustible,
    indicePreciosPorCombustible, bornePreciosPorCombustible, ListaContratos);

  self.T_ToP := T_ToP;
  self.V_ToP := V_ToP;
  self.P_ToP := P_ToP;
  self.P_ExtraToP := P_ExtraToP;

end;

 
constructor TGNLFichaGasoducto.Create_ReadFromText(f: TArchiTexto);
begin
  inherited Create_ReadFromText(f);
  f.IniciarLecturaRetrasada;
  f.rd('T_ToP', T_ToP);
  f.rd('V_ToP', V_ToP);
  f.rd('P_ToP', P_ToP);
  f.rd('P_ExtraToP', P_ExtraToP);
  f.EjecutarLectura;
end;

procedure TGNLFichaGasoducto.WriteToText(f: TArchiTexto);
begin
  inherited WriteToText(f);
  f.wr('T_ToP', T_ToP);
  f.wr('V_ToP', V_ToP, uconstantesSimSEE.CF_PRECISION, uconstantesSimSEE.CF_DECIMALES);
  f.wr('P_ToP', P_ToP, uconstantesSimSEE.CF_PRECISION, uconstantesSimSEE.CF_DECIMALES);
  f.wr('P_ExtraToP', P_ExtraToP, uconstantesSimSEE.CF_PRECISION,
    uconstantesSimSEE.CF_DECIMALES);
end;




function TGNLFichaGasoducto.infoAd_: string;
begin
  Result := inherited  infoAd_;
  Result := 'T_ToP= ' + IntToStr(T_ToP) + 'dias' + 'V_ToP= ' +
    FloatToStrF(V_ToP, ffGeneral, 10, 1) + ' ' + combustible.Unidades +
    ', ' + 'P_ToP= ' + FloatToStrF(P_ToP, ffGeneral, 10, 1) +
    ' USD/' + combustible.Unidades + ', ' + 'P_ExtraToP= ' +
    FloatToStrF(P_ExtraToP, ffGeneral, 10, 2) + ' USD/' + combustible.Unidades + ', ';
end;

procedure TGNLFichaGasoducto.Free;
begin
  inherited Free;
end;














//------------------------------
// Métodos de TGNLGasoducto
//==============================

constructor TGNLGasoducto.Create(capa: integer; nombre: string;
  nombreCombustible: string; nacimiento, muerte: TFecha;
  lpdUnidades, lpd: TFichasLPD; VDisp_ToP_Ini: NReal; NDisc: NInt);
begin
  inherited Create(capa, nombre, nombreCombustible, nacimiento, muerte,
    lpdUnidades, lpd);
  self.VDisp_ToP_Ini := VDisp_ToP_Ini;
  self.NDisc := NDisc;
end;

 
constructor TGNLGasoducto.Create_ReadFromText(f: TArchiTexto);
begin
  inherited Create_ReadFromText(f);
  f.IniciarLecturaRetrasada;
  f.rd('VDisp_ToP', VDisp_ToP_Ini);
  f.rd('NDisc', NDisc);
  f.EjecutarLectura;
  pa := nil;
end;

procedure TGNLGasoducto.WriteToText(f: TArchiTexto);
begin
  inherited WriteToText(f);
  f.wr('VDisp_ToP', VDisp_ToP_Ini);
  f.wr('NDisc', NDisc);
end;



procedure TGNLGasoducto.PrepararMemoria(globs: TGlobs);
begin
  inherited prepararMemoria(globs);
end;


function TGNLGasoducto.get_ires_volumen: NInt;
begin
  Result := self.ires;
end;

function TGNLGasoducto.get_precio_combustible: NReal;
begin
  if (VConsumido_ToP > 0) and (VConsumido_Extra_Top = 0) then
    Result := dCFdV
  else
  if (VConsumido_ToP > 0) and (VConsumido_Extra_Top > 0) then
    Result := pa.P_ExtraToP
  else
  if (VConsumido_ToP = 0) and (VConsumido_Extra_Top > 0) then
    Result := (dCFdV * VConsumido_ToP + pa.P_ExtraToP * VConsumido_Extra_Top) /
      (VConsumido_ToP + VConsumido_Extra_Top);
end;


function TGNLGasoducto.get_combustible: TCombustibleSGE;
begin
  Result := self.combustible;
end;

procedure TGNLGasoducto.RegistrarParametrosDinamicos;
var
  i: integer;
  ficha: TGNLFichaGasoducto;
begin
  inherited registrarParametrosDinamicos;
  lpd.expandirFichas(globs);
  lpd.RegistrarFichasAActualizar(Self, globs.ActualizadorLPD, @pA, nil,
    TGNLGasoducto_cambioFichaPD);
  for i := 0 to lpd.Count - 1 do
  begin
    ficha := TGNLFichaGasoducto(lpd[i]);
    if ficha.indicePreciosPorCombustible <> nil then
      ficha.nroBornePreciosPorCombustible :=
        ficha.indicePreciosPorCombustible.IdBorne(ficha.bornePreciosPorCombustible);
  end;
end;

procedure TGNLGasoducto.Free;
begin
  inherited Free;
end;

class function TGNLGasoducto.DescClase: string;
begin
  Result := 'Gasoducto Multiusuario con Linepack';
end;



procedure TGNLGasoducto.SorteosDelPaso(sortear: boolean);
var
  fecha_ToP_ant: TDateTime;  //Fecha del ultimo embarque recibido (anterior al paso)
  fecha_ToP_sig: TDateTime;  //Fecha del siguiente embarque
  i, cntDias: integer;
  ficha: TGNLFichaGasoducto;
begin
  V_ToP_sig := 0;

  //Calculamos cuando fué el último embarque (más reciente) para la fecha de inicio del paso.
  //Esto puede dar la fecha de vigencia de la ficha (cuando comienza a reguir una ficha entra combustible)
  //o una fecha posterior tal que es múltiplo de T_ToP
  cntDias := Trunc(globs.FechaInicioDelpaso.dt) - Trunc(pa.Fecha.dt);
  cntDias := cntDias mod pa.T_ToP;
  fecha_ToP_ant := globs.FechaInicioDelpaso.dt - cntDias;

  //Calculamos la siguiente fecha de ingreso de TakeOrPay y la hacemos igual a la fecha anterior + T dias
  //Si hay un cambio de ficha antes de esa fecha, colocamos como fecha del proximo ingreso la proxima fecha de vigencia
  fecha_ToP_sig := fecha_ToP_ant + pa.T_ToP;

  //Las Fechas de TOP corresponden a la hora 00:00:00

  V_ToP_sig := pa.V_ToP;

  //Ahora debemos detectar si hay una ficha que comienza a regir en el paso de simulación.
  //En este caso, en el paso no se actualiza el volumen, se consume todo lo que resta
  //y el volumen se actualizará al final del paso de tiempo
  for i := 0 to lpd.Count - 1 do
  begin
    ficha := TGNLFichaGasoducto(lpd[i]);
    if (ficha.fecha.dt > globs.FechaInicioDelpaso.dt) and
      (ficha.fecha.dt < globs.FechaFinDelpaso.dt) then
      if (fecha_ToP_sig > ficha.fecha.dt) then
      begin
        fecha_ToP_sig := ficha.fecha.dt;
        V_ToP_sig := ficha.V_ToP;
      end;
  end;


  //Ahora determinamos la fase en función de cuando ingreso el cargamento anterior y cuando ingresa el siguiente
  // no utilizo globs.FechaInicioDelpaso.dt porque tiene una hora menos!!!!!
  if (globs.FechaInicioDelpaso.dt <= fecha_ToP_sig) and
    ((globs.FechaInicioDelpaso.dt + globs.dt_DelPaso) >= fecha_ToP_sig) then
    //Atención: se pone globs.FechaFinDelPaso.dt > fecha_ToP_sig pues en caso de la igualdad
    //se toma en el inicio del siguiente paso.
    fase := 1     //En este paso de simulación ingresa un volumen T_ToP del contrato
  else
    fase := 0;     //En este paso de simulación no ingresa combustible

  //Si estamos en la fase 1, debemos actualizar el volumen disponible al final del paso
  //y el volumen restante lo ponemos como perdido
  //Si estamos en la fase 0, significa que tenemos un contrato vigente y estamos a la espera de un cargamento ToP

end;


procedure TGNLGasoducto.PrepararPaso_ps;
var
  dCFdV_Inc, dCFdV_Dec: NReal;
  rescod: integer;
  xrpos: double;
begin

  self.VConsumido_ToP := 0;
  self.VConsumido_Extra_Top := 0;
  self.VSobrante_ToP := 0;
  //Los suministros de combustible se preparan antes que los generadores. Esto permite que
  //el generador tenga las cosas que necesita del suministro de combustible.

  cvToP := 0;
  cvExtraToP := 0;

  globs.CF.devxr_continuo(ixr, globs.kPaso_ + 1, dCFdV_Inc, dCFdV_Dec, rescod, xrpos);

  dCFdV := dCFdV_Dec;
  cvToP := -dCFdV;

  if fase = 1 then
  begin
    if pa.indicePreciosPorCombustible <> nil then
    begin
      cfToP := pa.P_ToP * pa.V_ToP *
        pa.indicePreciosPorCombustible.bornera[pa.nroBornePreciosPorCombustible];
      cvExtraToP := pa.P_ExtraToP *
        pa.indicePreciosPorCombustible.bornera[pa.nroBornePreciosPorCombustible];
    end
    else
    begin
      cfToP := pa.P_ToP * pa.V_ToP;
      cvExtraToP := pa.P_ExtraToP;
    end;
  end
  else
  begin
    cfToP := 0;         //No ingresa combustible en esta etapa
    if pa.indicePreciosPorCombustible <> nil then
      cvExtraToP := pa.P_ExtraToP *
        pa.indicePreciosPorCombustible.bornera[pa.nroBornePreciosPorCombustible]
    else
      cvExtraToP := pa.P_ExtraToP;
  end;

end;

procedure TGNLGasoducto.opt_nvers(var ivar, ivae, ires: integer);
begin
  self.ivar := ivar; //CAntidad de variables (columnas)
  self.ires := ires;  //Cantidad de restricciones (filas)


  ivar := ivar + 2; // Columnas de VExtraTop y VConsumido_ToP
  ires := ires + 1;
  // 1 restricción. Luego los generadores deberán completar en sus columnas y en esta fila la restricción de volumen
end;

procedure TGNLGasoducto.opt_cargue(s: TSimplex);
begin
{$IFDEF SPXCONLOG}
  spx_NombrarVariables(s);
{$ENDIF}

  //Restricción de balance de volumen (Sumatoria de lo consumido por las maquinas - VExtraTop - VConsumitoTop debe ser igual a 0
  s.pon_e(ires, ivar, -1);
  s.pon_e(ires, ivar + 1, -1);

  //Aporte a la función de Costo
  s.pon_e(s.nf, ivar, -cvExtraToP);
  s.pon_e(s.nf, ivar + 1, -cvToP);

  //Termino independiente (vale o o Vtop*Ptop)
  s.acum_e(s.nf, s.nc, -cfToP);

  //Cada uno de los generadores conectados debe ser responsable de cargar sus
  //columnas en la restricción de volumen  y en la función de costo objetivo

end;

procedure TGNLGasoducto.Sim_Cronica_Inicio;
begin
  inherited Sim_Cronica_Inicio;
  X_VDisp_ToP := VDisp_ToP_Ini;   //Inicializo la variable de estado.
end;

procedure TGNLGasoducto.opt_fijarRestriccionesDeCaja(s: TSimplex);
var
  iposte: integer;
begin

  s.FijarRestriccionIgualdad(ires);

  //Agregamos la restricción de caja que dice que el  0 <= VConsumidoToP >= VDisponibleTop
  s.cota_sup_set(ivar + 1, X_VDisp_ToP);
end;

procedure TGNLGasoducto.opt_leerSolucion(s: TSimplex);
var
  VDisp_ToP_: NReal;
begin

  self.VConsumido_Extra_Top := s.xval(ivar);
  self.VConsumido_ToP := s.xval(ivar + 1);
  //Calculo del costo directo del paso y actualizo el estado al final del paso

  //Costo Fijo mas variable. El fijo es 0 si no estoy fecha de renovación de contrato, o VTop*PTop
  //y cvExtraTop es el Volumen Extra por el Precio extra Top (esto ya se calculo al preparar el paso)

  CostoDirectoDelPaso := cfToP + cvExtraToP * self.VConsumido_Extra_Top;


  VSobrante_ToP := 0;
  if fase = 1 then
  begin
    VSobrante_ToP := Xs_VDisp_ToP;
    //Lo que quedó disponible en el tanque es sobrante (sin consumir)
    Xs_VDisp_ToP := V_ToP_sig;       //Actualizo el estado, ingreso el combustible
  end
  else
  if Xs_VDisp_ToP >= 0 then
    Xs_VDisp_ToP := X_VDisp_ToP - self.VConsumido_ToP
  //En esta fase, simplemente consumí y actualize el estado
  else
    Xs_VDisp_ToP := 0;

end;

procedure TGNLGasoducto.EvolucionarEstado;
begin
  X_VDisp_ToP := Xs_VDisp_ToP;
end;

function TGNLGasoducto.getNombreVar(ivar: integer; var nombre: string): boolean;
begin
  if (ivar = self.ivar) then
  begin
    nombre := self.Nombre + '_V_Extra_ToP[' + pa.combustible.Unidades + ']';
    Result := True;
  end
  else
  if (ivar = self.ivar + 1) then
  begin
    nombre := self.Nombre + '_V_Consumido_ToP[' + pa.combustible.Unidades + ']';
    Result := True;
  end
  else
    Result := False;
end;

function TGNLGasoducto.getNombreRes(ires: integer; var nombre: string): boolean;
begin
  if (ires = self.ires) then
  begin
    nombre := self.nombre + '_VolumenDepachado = Consumo de las maquinas';
    Result := True;
  end
  else
    Result := False;
end;

procedure TGNLGasoducto.PubliVars;
var
  unidades: string;
  ficha: TGNLFichaGasoducto;
  i: NInt;
begin
  inherited PubliVars;

  unidades := self.combustible.Unidades;

  PublicarVariableNR('Costo_Directo_Paso', '[USD]', 6, 1, CostoDirectoDelPaso, True);
  PublicarVariableNR('CV_combustible', '[USD/' + unidades + ']', 6, 1, self.dCFdV, True);
  PublicarVariableNR('V_Consumido_ToP', '[' + unidades + ']', 6, 1,
    self.VConsumido_ToP, True);
  PublicarVariableNR('V_Consumid_Extra_ToP', '[' + unidades + ']', 6, 1,
    self.VConsumido_Extra_Top, True);
  PublicarVariableNR('V_Sobrante_ToP', '[' + unidades + ']', 6, 1,
    self.VSobrante_ToP, True);
  PublicarVariableNR('V_Disponible_ToP', '[' + unidades + ']', 6, 1,
    self.X_VDisp_ToP, True);
  PublicarVariableNI('Fase', '-', fase, True);
end;
























procedure TGNLGasoducto.AfterInstantiation;
begin
  inherited AfterInstantiation;
  pa := nil;
end;

{
function TGNLGasoducto.varsPSimRes3PorDefecto: TStringList;
var
  res: TStringList;
begin
  res:= inherited varsPSimRes3PorDefecto;

  res.Add('Costo_Directo_Paso');
  res.Add('CV_combustible');
  res.Add('V_Consumido_ToP');
  res.Add('V_Consumido_Extra_ToP');
  res.Add('V_Sobrante_ToP');
  res.Add('V_Disponible_ToP');
  res.Add('Fase');

  result:= res;
end;
}

procedure TGNLGasoducto.optx_nvxs(var ixr, ixd, iauxr, iauxd: integer);
begin
  self.ixr := ixr;
  ixr := ixr + 1;
end;

procedure TGNLGasoducto.PosicionarseEnEstrellita;
begin
  X_VDisp_ToP := globs.CF.xr[ixr];
end;

procedure TGNLGasoducto.ActualizarEstadoGlobal(flg_Xs: boolean);
begin
  // OJO mirar pertinencia de usar flg_Xs
  globs.CF.xr[ixr] := X_VDisp_ToP;
end;

procedure TGNLGasoducto.optx_RegistrarVariablesDeEstado(adminEstados: TAdminEstados);
begin
  adminEstados.Registrar_Continua(
    ixr,
    0.0,
    pa.V_ToP,
    NDisc,
    nombre + '_V_Disponible_ToP', // nombre de la variable
    combustible.Unidades // unidades
    );
end;


procedure TGNLGasoducto.opt_PrintResultados_Encab(var fsal: textfile);
begin
  Write(fsal, #9, FloatToStrF(X_VDisp_ToP, ffgeneral, 6, 3));
end;

procedure TGNLGasoducto.opt_PrintResultados(var fsal: textfile);
begin
  Write(fsal, #9, FloatToStrF(dCFdV, ffgeneral, 6, 3));
end;

{
// imprime volumenes de combustible despachados, h_actual, cv_agua_Dec
procedure TGNLGasoducto.Sim_PrintResultados_Encab(var fsal: textfile; kencab: integer );
begin

  if kencab = 0 then
  begin
    Write(fsal, #9,  Nombre, #9, Nombre, #9, Nombre, #9, Nombre,#9, Nombre,#9, Nombre,#9, Nombre);
  end
  else if kencab = 1 then
  begin
    write(fsal, #9, '[VConsumido_ToP]', #9, '[VConsumido_Extra_Top]', #9, '[VDisponible_ToP]', #9, '[VSobrante_ToP]', #9, '[CostoVariableCombustible]', #9, '[CostoDirectoDelPaso]', #9, '[Fase]');
  end
  else if kencab = 2 then
  begin
    write(fsal, #9, '[1VConsumido_ToP]', #9, '[1VConsumido_Extra_Top]', #9, '[1VDisponible_ToP]', #9, '[1VSobrante_ToP]', #9, '[1CostoVariableCombustible]', #9, '[1CostoDirectoDelPaso]', #9, '[1Fase]');
  end
  else
  begin
    write(fsal, #9, '[2VConsumido_ToP]', #9, '[2VConsumido_Extra_Top]', #9, '[2VDisponible_ToP]', #9, '[2VSobrante_ToP]', #9, '[2CostoVariableCombustible]', #9, '[2CostoDirectoDelPaso]', #9, '[2Fase]');
  end;
end;

procedure TGNLGasoducto.Sim_PrintResultados(var fsal: textfile);

begin
   write( fsal, #9, FloatToStrF(VConsumido_ToP, formatoReales, 6, 1));
  write( fsal, #9, FloatToStrF(VConsumido_Extra_Top, formatoReales, 6, 1));
  write( fsal, #9, FloatToStrF(X_VDisp_ToP, formatoReales, 6, 1));
  write( fsal, #9, FloatToStrF(VSobrante_ToP, formatoReales, 6, 1));
  write( fsal, #9, FloatToStrF(dCFdV, formatoReales, 6, 1 ) );
  write( fsal, #9, FloatToStrF(CostoDirectoDelPaso, formatoReales, 6, 1 ) );
  write( fsal, #9, IntToStr(fase));

end;
}

procedure TGNLGasoducto_cambioFichaPD(Actor: TCosa);
begin
end;

procedure AlInicio;
begin
  registrarClaseDeCosa(TGNLGasoducto.ClassName, TGNLGasoducto);
  registrarClaseDeCosa(TGNLFichaGasoducto.ClassName, TGNLFichaGasoducto);
end;

procedure AlFinal;
begin
end;

end.
