LIBPF® SDK - EXE Interface
This document is part of the developer manuals for (LIBrary for Process Flowsheeting) Software Development Kit (SDK) version 1.1; 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:
-
The executable should never stop waiting for user input;
-
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;
-
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;
-
The executable should accept inputs (inlet streams flows, composition and thermodynamical state, operating conditions) in any format, provided it’s documented;
-
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
-
-
The executable should provide any additional result that must be shown in the LIBPF® User Interface, with an English-text description;
-
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;
-
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 library that support reading / writing XML: https://xml-fortran.sourceforge.net/.
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>