Contents - Index


Source Code for GEN_EOS.DLL

The following source code implements the Compress, EnthDep, EntrDep, and FugCoef EES external functions in file GEN_EOS.DLL.  This code is written in DELPHI 10. 

library GEN_EOS;
{This library uses the Redlich-Kwong-Soave equation of state in reduced coordinates
to provide a general equation of state.}

uses
  SysUtils;

const
  doExample = -1;

{***********************************************************************}

type
  ParamRecPtr = ^ParamRec;
  ParamRec =
    record
      Value : Extended;
      Next  : ParamRecPtr;
    end;

{***********************************************************************}
{There are 4 functions; names are separated with commas}
procedure DLFNames(Names : PChar); export; stdcall;
begin
  StrCopy(Names,'COMPRESS,ENTHDEP,ENTRDEP,FUGCOEF');
end;

{***********************************************************************}
procedure DLPNames(Names : PChar); export; stdcall;
{no DLP procedures}
begin
  StrCopy(Names,'');
end;

{***********************************************************************}
{no FDL procedures}
procedure FDLNames(Names : PChar); export; stdcall;
begin
  StrCopy(Names,'');
end;

{***************** General functions used by all routines**********************}
  function CountValues (P: ParamRecPtr): Integer;
  var
    N: Integer;
  begin
    N := 0;
    while (P <> nil) do begin
      N := N + 1;
      P := P^.Next
    end;
    Result := N;
  end;

  procedure GetCheckInputs(FuncName:shortString; ParamPtr:ParamRecPtr; var PString:shortString;  var A,B,m,Tr:extended);
    var Ptr: ParamRecPtr;
        Pr,w:extended;
        NArgs:integer;
    begin
       PString:='';
       NArgs:=CountValues(ParamPtr);
       if (NArgs <> 2) and (NArgs <> 3) then begin
         PString := 'Wrong number of arguments for '+FuncName+' function.';
         exit;
       end;
       A:=-999; B:=-999; m:=-999;
       Ptr := ParamPtr;
       Tr := Ptr^.value;
       if (Tr<0) then begin
         PString:='Temperature input to '+FuncName+' is negative.';
         exit;
       end;
       Ptr := Ptr^.next;
       Pr := Ptr^.value;
       if (Pr<0) then begin
         PString:='Pressure input to '+FuncName+' is negative.';
         exit;
       end;
       Ptr := Ptr^.next;
       if (Ptr <> nil) then
         w := Ptr^.Value
       else
         w := 0.1; {acentric factor}
       m := 0.480 + 1.574 * w - 0.176 * w * w;
       A := 0.42747 * sqr(1 + m * (1 - sqrt(Tr))) * Pr / sqr(Tr);
       B := 0.08664 * Pr / Tr;
    end;

  function Compressibility(A,B:extended): extended;
    const
      NMax = 50; {maximum number of iterations}
    var
      NIter, NCut: integer;
      F1, F2, Fnew, Z1, Z2, Znew, DeltaZ: extended;

    function F (Z: extended): extended;
      begin {Redlich Kwong Soave eqn of state in reduced form}
        F := Z * Z * Z - Z * Z + Z * (A - B - B * B) - A * B;
      end; {F}

     begin {Compressibility}
       Z1 := 1;{ideal gas}
       F1 := F(Z1);
       Z2 := 0.9 * Z1;
       F2 := F(Z2);
       NIter := 0;
       while (NIter < NMax) and (abs(F2) > 1E-6) do begin
         NIter := NIter + 1;
         DeltaZ := F2 / (F2 - F1) * (Z2 - Z1);
         NCut := 0;
         repeat
           Znew := Z2 - DeltaZ;
           Fnew := F(Znew);
           DeltaZ := DeltaZ / 2;
           NCut := NCut + 1;
         until (NCut > 5) or (abs(Fnew) < abs(F2));
         Z1 := Z2;
         F1 := F2;
         Z2 := Znew;
         F2 := Fnew;
       end; {while}
       if (NIter < NMax) then
         Compressibility := Z2
       else
         Compressibility := -1; {function did not converge.}
    end;
{***********************************************************************}

function COMPRESS (var PString: ShortString; Mode: integer;
       Inputs: ParamRecPtr): extended; export; stdCall;
var
   A,B,Z,m,Tr:extended;
begin
   Compress:=-999;
   if (Mode = doExample) then
     PString := 'Compress(Tr, Pr [,w])'
   else begin
     GetCheckInputs('Compress',Inputs,PString,A,B,m,Tr);
     if (length(PString)>0) then exit; {error}
     Z:=Compressibility(A,B);
     if (Z<0) then
       PString:='Compress function did not converge.'
     else
       Compress:=Z;
    end;
  end; {Compress}

{***********************************************************************}
function ENTHDEP (var PString: string; Mode: integer;
    Inputs: ParamRecPtr): extended; export; stdCall;
  var
     Z, A, B, m, Tr,temp: extended;
  begin {EnthDep}
    EnthDep:=-999;
    if (Mode = doExample) then
      PString := 'EnthDep(Tr, Pr [,w])'
    else begin
      GetCheckInputs('EnthDep',Inputs,PString,A,B,m, Tr);
      if (length(PString)>0) then exit; {error}
      temp := (sqr(1 + m) - m * (1 + m) * sqrt(Tr));
      Z := Compressibility(A,B);
      if (Z > 0) then
        EnthDep := -Tr * (Z - 1) + 0.42747 / 0.08664 * temp * ln((Z + B) / Z)
      else
        PString:='EnthDep function did not converge';
    end; {else}
  end; {EnthDep}

function ENTRDEP (var PString: string; Mode: integer;
    Inputs: ParamRecPtr): extended; export; stdCall;
{Returns the entropy departure divided by R using RKS equation of state}
  var
    Tr, Z, A, B, m, EnthalpyDep, lnFugacityCoef, temp: extended;
  begin
    EntrDep:=-999;
    if (Mode = doExample) then
      PString := 'EntrDep(Tr, Pr [,w])'
    else begin
      GetCheckInputs('EntrDep',Inputs,PString,A,B,m,Tr);
      if (length(PString)>0) then exit; {error}
      Z := Compressibility(A,B);
      if (Z > 0) then begin
        temp := (sqr(1 + m) - m * (1 + m) * sqrt(Tr));
        EnthalpyDep := (Z - 1) - 0.42747 / (0.08664 * Tr) * temp * ln((Z + B) / Z);
                  {EnthalpyDep is non-dimensionalized with RT}
        lnFugacityCoef := Z - 1 - ln(Z - B) - A / B * ln((Z + B) / Z);
        EntrDep := -(EnthalpyDep - lnFugacityCoef);
      end else
        PString:='EntrDep function did not converge';
    end;
  end;

function FUGCOEF (var PString: Shortstring; Mode: integer;
    Inputs: ParamRecPtr): extended; export; stdCall;
  var
    Tr, Z, A, B, m: extended;
  begin {fugCoef}
    FugCoef:=-999;
    if (Mode = doExample) then
       PString := 'FugCoef(Tr, Pr [,w])'
    else begin
      GetCheckInputs('FugCoef',Inputs,PString,A,B,m,Tr);
      if (length(PString)>0) then exit; {error}
      Z := Compressibility(A,B);
      if (Z > 0) then
        fugCoef := exp(z - 1 - ln(Z - B) - A / B * ln((Z + B) / Z))
      else
        PString:='FugCoef function did not converge.';
    end;{else}
  end; {fugCoef}

exports
  DLFNames,
  DLPNames,
  FDLNames,
  COMPRESS,
  ENTHDEP,
  ENTRDEP,
  FUGCOEF;

begin

end.