Introduction

Model developers use the C++ the full, low-level LIBPF™ C++ API to develop process models. Once a process model is complete and tested, it can be deployed to model users as a calculation kernel or remotely-accessible service supporting a predefined set of model types.

Programmatic access to the models via scripts or automation is possible using the same C++ LIBPF™ low-level API used during development.

But the low-level API is too complex for the model user role, therefore a high-level Model User API is provided, as a subset of the full C++ API, accessible via:

Intended audience

System integrator and client developers who want to develop solutions based on the modeling of industrial continuous processes with the LIBPF™ enabling technology.

Scope

This document is a starting point for the LIBPF™ Model User API, a simple, high level API to manage and use process models who have been previously prepared and deployed by model developers.

Prerequisites

  • general IT competences

  • acquaintance with the field of industrial continuous processes

  • know about the different roles involved with the lifecycle of solutions developed using the LIBPF™ enabling technology, see LIBPF™ Technology Introduction

Objects

The Model User API involves the following objects:

  • Kernel: matches the capabilities of a standalone calculation kernel or service, i.e. knows the list of components and the available model types and enumerators that can be used to instantiate Cases; can instantiate a Case and return a Handle to a case instance; currently only one Kernel object time can be alive at a time, and its lifecycle coincides with the time the executable / scripting session is alive - therefore the Kernel object methods are exposed by the Model User API as global functions

  • Case: an instance of a model type, potentially comprising a hierarchical tree of sub-models; knows about variables, can be calculated, can export results to various (SVG, XML, TXT, HTML, JSON and SQLITE) formats

  • Handle; an opaque pointer to a persistent Case; has a recognizable invalid value used when the operation that should have returned a handle is not successful; is persistent i.e. given an handle, the Case state can be restored.

Cases

Cases are top-level instances of model types. They are complex objects, and have the following properties:

  • type: a string that identifies the model type

  • tag: a string identifier

  • full tag: a string with the complete path to the object in the hierarchy of models, recursively obtained by concatenating the full tag of its parent with the tag, separated by colon (":")

  • description: a string with a descriptive text

  • separate collections of Integer, String and Quantity variables

  • other sub-models in a hierarchical fashion, to build a tree-like structure.

Variables

Variables are contained in models and can be:

  • Integers: integral values used for configuration options such as number of stages, number of streams, number of reaction; generally positive or zero values are legitimate while the negative -1 value is used as a placeholder for "missing" or "unspecified"

  • Strings: UTF-8 strings used for configuration options such as reaction types, the name of inert component, heat transfer modeling options etc.; generally non-empty strings are legitimate while the empty string is used as a placeholder for "missing" or "unspecified"

  • Quantities: floating point numbers stored in SI units.

Variables have the following properties:

  • tag: a string identifier

  • full tag: a string with the complete path to the variable in the hierarchy of models, obtained by concatenating the full tag of its parent model with the Variable tag, separated by dot .

  • description: a string with a descriptive text

Additionally Quantities can be one or of both of:

  1. inputs: user-supplied values

  2. results: values calculated by LIBPF™

Naming constraints

Model tags must be unique among siblings, i.e. within the direct descendants of a model.

Nothing bars duplicate tags at different locations in the hierarchy like in A:A:A:A or A:(B (A, B)). Therefore tags can not be used to uniquely identify objects and sub-objects in a tree.

Full tags are unique in each tree, but nothing bars creating different trees containing with equally fulltagged models.

Variable tags are unique among each of the different variable groups (Strings, Integers are Quantities) of a model: we can have T as a Quantity, and as an Integer and as a String in the same model.

Models and Variables can be arranged in multi-dimensional arrays:

  • Vectors of variables (such as compositions, flows) or matrices of variables (such as stoichiometric coefficients, diffusivity coefficients);

  • Vectors of models (such as the stages in a multi-stage unit operation) or matrices of models (such as the 2-D arrangement of sub-units in a two-dimensionally discretized unit operation)

Multi-dimensional arrays are in general indexed with 0-based integers using the square bracket operators [-] and [-,-], but for collections indexed by the components (such as composition vectors or coefficient matrices) the components names can be used as keys.

The model tag must have the first character of alphabetical type. The following characters can be alphanumeric or space or ,-_{}<>. Thus .:[] are excluded.

The model description must have the first character of alphabetical type. The subsequent characters can be alphanumeric or space or .,:-_{}<>[].

Notes:

  • Alphabetical character: as reported in Annex A (Recommended extended repertoire for user-defined identifiers) of TR 10176:2003, TECHNICAL REPORT ISO/IEC TR 10176, Fourth edition (2003): Guidelines for the preparation of programming language standards;

  • Alphanumeric character: alphabetical character or 0 – 9.

Examples:

  • S01.T is the variable T (temperature) in sub-model S01 (a material Stream)

  • S01:Tphase.x[C6H14] is the element matching component C6H14 of the vector variable x (the molar fraction) in sub-model Tphase (a Phase) of sub-model S01 (a material Stream)

  • FC:multiReactions[0].coeff[0][H2] is the element matching index 0 and component H2 of the matrix variable coeff (the stoichiometric coefficients for each reacting phase) in the 0-th (i.e. the first) element of the vector of sub-models multiReactions (for generic multiphase reactions) of sub-model FC (a fuel cell)

Instantiating and using a Case

Cases can be instantiated via the Kernel createCase method by supplying:

  • tag, description and type

  • optionally, a list of String options and a list of Integer options to configure its construction process.

The model developer can set up model types such that their construction process can be steered by passing certain String and / or Integer options. This feature is used for example to configure multi-stage unit operations (passing an integer nStage to set the number of stages), to set-up feed stream compositions based on pre-sets (i.e. setting the "feedType" option to "MSW", "cow manure" etc.) or to define process conditions (i.e. settings the "processType" option to "high-temperature", "low-temperature" etc.).

The available model types and their configurability options are accessible via the Kernel API so that each LIBPF™ application / service is self-documenting. These information are made available via the listTypes and listEnumerators methods.

Once a Case has been instantiated, the Kernel createCase method returns a Handle object that can be used to access the Case instance at any time.

Any future access to this Case instance must be performed by instantiating a Model User API Case object, passing the Case instance Handle to it.

The Model User API Case object allows the following operations on a Case instance:

  • changing tag and description with the setTag and setDescription methods

  • retrieving:

  • the SI values of Quantity Variables with the get method

  • the values of Integer Variables with the getInteger method

  • the values of String Variables with the getString method

  • setting the values of one or more Quantity Variables at a time the set method

  • performing synchronous calculations with the calculateSync, homotopySync and sensitivitySync methods

  • exporting the Case to a variety of formats (SVG, XML, TXT, HTML, JSON and SQLITE) with the export* (i.e. exportSvg, exportXml, exportTxt, exportHtml, exportJson and exportSqlite) methods.