This document is part of the developer manuals for (LIBrary for Process Flowsheeting) Software Development Kit (SDK) version 1.0; the target audience is model developers wishing to interface third-party models available as separate executables with LIBPF™.

For more information on developing with LIBPF™ SDK see LIBPF™ SDK Developer manual.

Introduction

The canonical approach for developing models with LIBPF™ (C++ LIBrary for Process Flowsheeting) is to implement them in the programming language C++.

But LIBPF™ can also be interfaced with third-party models provided as separate executables; the advantages and disadvantages of this alternative approach are summarized in this table:

Pros Cons
The license of the third-party models is not affected by the LIBPF™ license; Resolution is slower because of the overhead associated with starting the external executable;
The third-party model can be developed using any programming language / technology; The flow-sheets incorporating the third-party model can only be run in sequential mode and can not exploit the benefits of simultaneous resolution;
Minimal changes are required to adapt an existing model and interface it with LIBPF™. The flow-sheets incorporating the third-party model can not be executed in parallel (they become non-reentrant);
Supporting all LIBPF™ architectures is a daunting task.

Requirements

The minimum requirements for a third-party model provided as separate executables are:

  1. The executable should never stop waiting for user input;

  2. The executable should never crash in case of severe error: it should exit gracefully, returning one of the documented exit codes, that can be used by the calling program (LIBPF™) to pass the information about what went wrong to the user;

  3. The executable should accept input data and provide results via UTF-8 encoded plain text files, or even better via structured formats such as XML or JSON;

  4. The executable should accept inputs (inlet streams flows, composition and thermodynamical state, operating conditions) in any format, provided it’s documented;

  5. The executable should provide the minimal set of results required by LIBPF™, i.e.:

    • if power enters / exits the unit in any form (mechanical or thermal), the amount of subtracted / supplied power (this is used to perform the heat balance)

    • for each outlet stream:

      • total flow (mass or molar) and composition (mass or molar)

      • thermodynamical state (preferably P and T)

      • document the phases present so that LIBPF™ can flash the streams with the same thermodynamical assumptions

    • in case of non-severe error or warnings, human-readable messages must be placed in the results file

  6. The executable should provide any additional result that must be shown in the LIBPF™ User Interface, with an English-text description;

  7. All input and results will be in scientific notation with at least 10 significant digits (i.e. 1.23456789E0) and the units of measurement must be documented;

  8. A separate executable must be supplied for each supported platform; at a minimum, for Microsoft Windows, 32- and 64-bit versions of the executable must be supplied.

In the appendix, an example shows XML input / results files for an hypothetical a third-party model for a membrane module.

Stateful calculation

During the sequential resolution of the flow-sheets, typically each unit is repeatedly called with similar input values; if the third-party unit model internally makes use of an iterative algorithm, it is a waste to start over and over from the generic initialization.

Stateful calculation is a calculation that can be forced to initialize from a previous solution point. If the third-party unit model supports stateful calculation, it can make use of the similarity of input values passed by LIBPF™ along the flow-sheet solution path, accelerating the overall solution time of 1-2 orders of magnitude.

Stateful calculation can be implemented as follows:

  • at the end of each calculation, the third-party unit model must save a state input / output file, in any format (text or binary), with a snapshot of all internal data structures used internally to store the unknowns;

  • the input file has a setting to force stateful calculation;

  • on start of the flow-sheet resolution, the first input file passed by LIBPF™ to the third-party unit model will have this setting set to false so that the model performs generic initialization;

  • on successive evaluations LIBPF™ will set the stateful calculation flag to true in the input file, forcing the third-party unit model to initialize from the previous solution point, saved in the state file.

Validation

At least one reference case should be provided. Ideally a set of tests should be supplied to cover a reasonable set of input values.

Thermodynamical consistency

LIBPF™ and the supplied third-party model will inevitably implement different thermodynamical calculations, so a misalignment will occur, in the form of a “ghost” heat load. To make sure this misalignment is not the effect of some error in communication, care should be taken to establish a test case for a “trivial” operating condition, i.e. for a compressor: zero shaft speed, for a fuel cell: zero current, for a membrane unit: zero driving force.

If the  third-party model can calculate the “trivial” operating condition, this can be used as a test case to bracket the entity of the misalignment.

References

FORTRAN libraries that support reading / writing XML: http://xml-fortran.sourceforge.net/ and http://fisica.ehu.es/ag/xml/.

Appendix - Example

Input file

<?xml version="1.0" encoding="UTF-8"?>
<inputs>
  <input name="A" description="Membrane area" units="m2">1.000000000E2</input>
  <input name="Ppermeate" description="Pressure of permeate compartment" units="bar">1.000000000E0</input>
  <input name="permeance[N2]" description="Permeance for component N2" units="GPU">2.000000000E2</input>
  <input name="permeance[CO2]" description="Permeance for component CO2" units="GPU">1.000000000E3</input>
  <inlet name="feed stream">
    <input name="P" description="pressure" units="bar">1.23456789E2</input> 
    <input name="T" description="temperature" units="°C">2.981500000E2</input> 
    <input name="mdot" description="mass flow" units="kg/h">1.23456789E2</input> 
    <input name="x[N2]" description="Molar fraction for component N2" units="">4.000000000E-1</input>
    <input name="x[CO2]" description="Molar fraction for component CO2" units="">6.000000000E-1</input>
  </inlet>
</inputs>

Results file

<?xml version="1.0" encoding="UTF-8"?>
<results>
  <warning text="No permeate pressure drop supplied"</>
  <input name="power" description="Net power" units="W">1.000000000E2</input>
  <outlet name="permeate" phase="vapor">
    <input name="P" description="pressure" units="bar">1.000000000E0</input> 
    <input name="T" description="temperature" units="°C">2.981500000E2</input> 
    <input name="mdot" description="mass flow" units="kg/h">0.123456789E2</input> 
    <input name="x[N2]" description="Molar fraction for component N2" units="">1.000000000E-1</input>
    <input name="x[CO2]" description="Molar fraction for component CO2" units="">9.000000000E-1</input>
  </outlet>
  <outlet name="retentate" phase="vapor">
    <input name="P" description="pressure" units="bar">1.23456789E1</input> 
    <input name="T" description="temperature" units="°C">2.981500000E2</input> 
    <input name="mdot" description="mass flow" units="kg/h">1.00000000E2</input> 
    <input name="x[N2]" description="Molar fraction for component N2" units="">5.000000000E-2</input>
    <input name="x[CO2]" description="Molar fraction for component CO2" units="">5.000000000E-1</input>
  </outlet>
</inputs>