ALFAsim-SDK

Documentation for the ALFAsim-SDK

Plugins

The ALFAsim-SDK help developers to create plugins for ALFAsim application. Plugins can extend the ALFAsim capabilities in a lot of ways, from adding a simple input to a custom calculation of solver equations.

Some examples of the capabilities that can be extended are:

  • Creation of user-defined GUI models, allowing custom models to be available over the Tree and in the Model Explorer.

  • Registration of additional variables that are not nonlinear system’s unknowns, for the ALFAsim solver. Also called “secondary variables”

  • Customization of the hydrodynamic models, supporting the additions of custom Phases/Fields/Layers.

  • Support for inclusion of custom mass, momentum and energy equations.

  • Support for calculating source terms to solver equations.

  • Support for calculating/updating plugin-registered Simulation Variables

For a list of all capabilities that can be expanded check the Full API Reference in the documentation.

Anyone with programming skills can create a Plugin for ALFAsim. To make it possible, ALFAsim-SDK provides hooks to customize the solver and the user interface. To customize the solver, an API in C is provided for application written in C/C++, while, for user interface customization, an API in Python allows the developer to customize the interface in a declarative way.

To get quick and running with ALFAsim-SDK you can read the Quick Start and the Plugin by Example sections

Quick Start

In this section, it is shown how to create a plugin from scratch with the template command provided by ALFAsim-SDK. With this template, you can easily customize your application to extend ALFAsim functionality.

This allows you to experience the complete creation of a plugin workflow in a short time.

Set up the environment

The ALFAsim-SDK is a Python package that helps developers in the process to create a Plugin for ALFAsim, to use this tool it is necessary to have a Python Interpreter with at least version 3.6. For more details on how to install Python check the official docs.

Note

It is recommended that you install the ALFAsim-SDK using a Python Virtual Environment. For more details, see Virtual Environments and Packages in Python documentation.

From a terminal, and inside a virtual environment, update pip:

>>> python -m pip install -U pip

Install the ALFAsim-SDK with:

>>> pip install alfasim-sdk

Also, make sure to have at least the following version for this software:

  • CMake at least version 3.5.2

  • Ninja at least version 1.7.0

The alfasim-sdk package has several commands that can be visualized by running the help option.

>>> alfasim-sdk --help

Creating a Plugin Project

To create a new project, run:

>>> alfasim-sdk template

After the execution of the command above, you will be prompted to fill the following options (all required):

>>> alfasim-sdk template
... -- Plugin Caption: Myplugin
... -- Plugin Id: myplugin
... -- Author Name: ESSS
... -- Author Email: <email>@<server>
Plugin Caption

The caption to be used across the application to identify the plugin.

Plugin Id

The name of the plugin to be referenced during the development.

Author Name

Name of the plugin author to be displayed.

Author Email

Email of the plugin author to be displayed.

To check all options, call the help command:

>>> alfasim-sdk template --help

After the execution of the template command the generated plugin project will have the following structure:

\---myplugin
    |   CMakeLists.txt
    |   compile.py
    |
    +---assets
    |       plugin.yaml
    |       README.md
    |
    \---src
        |   CMakeLists.txt
        |   hook_specs.h
        |   myplugin.cpp
        |
        \---python
                myplugin.py

The highlights here are for:

plugin.yaml

File with all information about the plugin that will be used by ALFAsim.

myplugin.py

Implementation of the hooks for customization of the UI interface, or the solver configuration hooks.

myplugin.c

Implementation of the hooks for customization of solver.

Check out the Plugin Structure section for more details about how the folder and files are structured, and also, check the Plugin by Example that shows how to create simple plugins that make use of the User Interface Hooks and the Solver Hooks.

Creating a package

From the root directory of the plugin, execute the command alfasim-sdk package. This command will compile your C/C++ implementation and include the shared libraries inside a artifacts directory and the generated plugin on the root directory with the extension hmplugin.

>>> cd myplugin
>>> alfasim-sdk package
... -- Package Name: myplugin

The plugin directory will have the following structure when executing from a Windows Operating System:

\---myplugin
    |   CMakeLists.txt
    |   compile.py
    |   myplugin-1.0.0-win64.hmplugin
    |
    +---artifacts
    |       myplugin.dll
    |       myplugin.lib
    |
    +---assets
    |       plugin.yaml
    |       README.md
    |
    +---build
    |       < ... >
    |       < ... >
    |
    +---package
    |       myplugin.dll
    |       plugin.yaml
    |       README.md
    |
    \---src
        |   CMakeLists.txt
        |   hook_specs.h
        |   myplugin.cpp
        |
        \---python
                myplugin.py

Installing the plugin

With myplugin.hmplugin file, it is now possible to install it on ALFAsim application. From the menu bar select the Plugin Manager option, as illustrated in the figure below:

_images/menu_bar.png

In the Plugin Manager windows, install myplugin.hmplugin file plugin.

_images/plugin_manager_empty.png

By clicking on the plugin name, it is possible to visualize the content from the README.md file.

_images/plugin_manager_with_plugin.png

Restart the application and check the recently installed plugin available over the Tree.

_images/tree_with_plugin.png

Plugin by Example

In this section, we will continue to customize the template plugin created from the previous section, this plugin will calculate the liquid velocity to the power of a given exponent provided by the user from the user interface.

The following equation describes the plugin:

\[var = U_{\text{liq}}^{n}\]

Where

\(U_{\text{liq}}\)

Liquid Velocity

\(n\)

Exponent, input from user interface

\(var\)

Plugin calculated value, that will be shown on the output.

For this, we will need to:

  1. Create a simple input, on the user interface.

  2. Add a secondary variable, to keep track of the value.

  3. Retrieve the input data on the HOOK_INITIALIZE.

  4. Save the input data on a plugin internal data.

  5. Get the liquid velocity from the solver, during run-time.

  6. Export the value into the created/registered plugin secondary variable.

Application customization

ALFAsim-SDK allows plugins to customize the user interface of ALFAsim by adding custom models, the image below shows the locations where a custom model can be inserted using the hook alfasim_get_data_model_type().

_images/alfasim_get_data_model_type_main.png

marker_1 illustrates the section where the models alfasim_sdk.container_model() or alfasim_sdk.data_model() will be placed.
marker_2 illustrates the section where the inputs fields will be placed.

For this example we will use a data_model() entry over the Tree, using a Quantity() field to get exponent value from the user.

The hook alfasim_get_data_model_type() needs to be implemented on the myplugin.py, located on myplugin/src/python folder.

Implementation of myplugin.py

import alfasim_sdk
from alfasim_sdk import data_model
from alfasim_sdk import Quantity

@data_model(caption='My plugin model', icon='')
class MyPluginModel:
    exponent = Quantity(value=1, unit='-', caption='Exponent value')

@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyPluginModel]

Notice that only models that are returned by the hook alfasim_get_data_model_type() will be included on the user interface of ALFAsim.

The image below illustrates the application with the output from the snippet above.

_images/user_interface_hook.png

For more details about all input fields available, check the section Types. And for more detail about the available models, check the section Models.

Solver Configuration

ALFAsim-SDK provides hooks to customize the settings of the application that configures the solver internally, some of these configurations are:

  • Creation/Registration of new secondary variables

  • Creation of new phases/fields/layers.

  • Update of default phases and layers from the application.

For this example, a new alfasim_sdk.SecondaryVariable() will be created, to track the liquid velocity to the power of a custom value provided from the user.

A Secondary Variable is a variable that can be calculated along the Network. Also, if configured as external, this variable will be set an Output, and will be available within the Trends and Profiles plots.

To create these variables, the hook alfasim_get_additional_variables() must be implemented in the myplugin.py file.

Implementation of myplugin.py

@alfasim_sdk.hookimpl
def alfasim_get_additional_variables():
    import alfasim_sdk
    from alfasim_sdk import SecondaryVariable
    from alfasim_sdk import Visibility
    from alfasim_sdk import Location
    from alfasim_sdk import Scope

    return [
        SecondaryVariable(
            name='U_liq_n',
            caption='Powered Liquid Velocity',
            unit='-',
            visibility=Visibility.Output,
            location=Location.Center,
            multifield_scope=Scope.Global,
            checked_on_gui_default=True,
        ),
    ]

The image below illustrates the application with the output from the snippet above.

_images/secondary_variable_trend_output.png

For more details about SecondaryVariable, check the section Secondary Variables.

Hooks for Solver

ALFAsim-SDK provides hooks that can customize the Solver behavior, this customization are implemented in C/C++ and can make use of the ALFAsim-SDK C/C++ API in order to fetch information from the application.

At this point, we are going to implement the Solver Hooks that updates the secondary variable declared from myplugin.py file and retrieve the Liquid Velocity from the ALFAsim’s Solver.

First, we need to implement two mandatory hooks, the HOOK_INITIALIZE and the HOOK_FINALIZE

With them it is possible to initialize any custom data (to store any important information) for internal use. Also it is needed to load and unload the ALFAsim-SDK API, in which will allows the plugin to use the API in any implemented hook.

Implementation of myplugin.cpp

ALFAsimSDK_API alfasim_sdk_api;

struct MyPluginModel {
    double exponential = 0.0;
};

HOOK_INITIALIZE(ctx)
{
    alfasim_sdk_open(&alfasim_sdk_api);

    int errcode = -1;
    double n = 0.0;

    errcode = alfasim_sdk_api.get_plugin_input_data_quantity(
        ctx,
        &n,
        get_plugin_id(),
        (const char*) "MyPluginModel.exponent");
    if (errcode != 0) {
        std::cout << "input_data_quantity error=" << errcode << "\n";
        return errcode;
    }

    int n_threads = -1;

    errcode = alfasim_sdk_api.get_number_of_threads(ctx, &n_threads);

    for (int thread_id = 0; thread_id < n_threads; ++thread_id) {
        // MyPluginModel is a class or struct defined by plugin
        auto* model = new MyPluginModel();
        model->exponential = n;
        errcode = alfasim_sdk_api.set_plugin_data(
            ctx,
            get_plugin_id(),
            (void*) model,
            thread_id
        );
    }

    return OK;
}

HOOK_FINALIZE(ctx)
{

    auto errcode = -1;
    auto number_of_threads = -1;
    errcode = alfasim.get_number_of_threads(ctx, &number_of_threads);
    for (int thread_id = 0; thread_id < n_threads; ++thread_id) {
        MyPluginModel* model = nullptr;
        errcode = alfasim.get_plugin_data(ctx, (void**) (&model), get_plugin_id(), thread_id);
        delete model;
    }
    alfasim_sdk_close(&alfasim_sdk_api);

    return OK;
}

Then, since the plugin wants to calculate its own secondary variable, the HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES must be implemented. As can be seen in the example below, to retrieve the velocity of the continuous liquid field it is necessary to use the get_simulation_array() API function.

HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES(ctx)
{
    int errcode = -1;

    // Get Liquid Field ID
    int liquid_field_id = -1;
    errcode = alfasim_sdk_api.get_field_id(
        ctx,
        &liquid_field_id,
        "liquid"
    )
    if (errcode != 0) {
        std::cout << "get_field_id error = " << errcode << "\n";
        return errcode;
    }

    // Get Liquid Field Velocity
    int n_faces = -1;
    double* U_liq = nullptr;
    errcode = alfasim_sdk_api.get_simulation_array(
        ctx,
        &U_liq,
        (char*) "U",
        VariableScope {
            GridScope::CENTER,
            MultiFieldDescriptionScope::FIELD,
            TimestepScope::CURRENT
        },
        liquid_field_id,
        &n_faces);
    if (errcode != 0) {
        std::cout << "get_simulation_array error = " << errcode << "\n";
        return OK;
    }

    // Get Exponent input data
    double n = 0.0;
    {
        int thread_id = -1;
        errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);

        MyPluginModel* model = nullptr;
        errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) (&model),
            get_plugin_id(), thread_id
        );
        n = model->exponential;
    }

    // Get Plugin Secondary Variable
    int size = -1;
    double* U_liq_n_ptr = nullptr;
    errcode = alfasim_sdk_api.get_plugin_variable(
        ctx,
        (void**) &U_liq_n_ptr,
        "U_liq_n",
        0, // Global Scope
        TimestepScope::CURRENT,
        &size);
    if (errcode != 0) {
        std::cout << "get_plugin_variable error = " << errcode << "\n";
        return errcode;
    }
    // Calculating the 'U_liq' to power of 'n'
    for (int i = 0; i < size; ++i) {
        U_liq_n_ptr[i] = std::pow(U_liq[i], n);
    };

    return OK;
}

The image below illustrates the output from the solver, when running the plugin created in this section with the given network.

_images/output_graph.png

After reading the quick start section and the plugin by example section, check out these additional resources to help better understand the plugins infrastructure:

Plugins Structure

As mentioned in Quick Start, the ALFAsim-SDK package has some utilities to help in the process to create a new plugin project and to create a plugin file.

At any moment, it is possible to invoke the help command to list all commands available.

>>> alfasim-sdk --help

You can also learn about the available options of each command invoking the –help option for each command:

>>> alfasim-sdk template --help
>>> alfasim-sdk package --help
>>> alfasim-sdk compile --help

alfasim-sdk template

Generate a template with the necessary files and structure to create a plugin.

The template folder will be placed on the dst option, that by default is the current directory from where the command was invoked.

The files generated and their contents are ready to be used or customized and have the following structure:

\---myplugin
|   CMakeLists.txt
|   compile.py
|
+---assets
|       plugin.yaml
|       README.md
|
\---src
    |   CMakeLists.txt
    |   hook_specs.h
    |   myplugin.cpp
    |
    \---python
            myplugin.py
alfasim-sdk template [OPTIONS]

Options

--dst <dst>

A path to where the plugin project should be created. Default: Current directory

--caption <caption>

Caption to be used across the application to identify the plugin

--plugin-id <plugin_id>

The name of the plugin

--author-name <author_name>

Name of the plugin author, this value is stored in plugin metadata and not displayed on the application explicitly

--author-email <author_email>

Email of the plugin author, this value is stored in plugin metadata and not displayed on the application explicitly

alfasim-sdk package

Creates a new <package-name>.hmplugin file containing all the necessary files.

This command will first invoke the compile command to generate the shared library, and after that, the plugin package will be generated with all the content available from the directory assets and artifacts.

By default, the package command will assume that the plugin project is the current directory and the generated file will be placed also in the current directory.

In order to change that, it’s possible to use the options plugin-dir and dst

alfasim-sdk package [OPTIONS]

Options

--plugin-dir <plugin_dir>

Path to the plugin directory, where configuration and the shared library is located.

--dst <dst>

A path to where the output package should be created.

--package-name <package_name>

Name of the package

alfasim-sdk package_only

Generate a <package_name>.hmplugin file with all the content from the directory assets and artifacts.

By default, the package will be created inside the folder plugin_dir, however, it’s possible to give another path filling the dst argument.

alfasim-sdk package_only [OPTIONS]

Options

--plugin-dir <plugin_dir>

Path to the plugin directory, where configuration and the shared library is located.

--dst <dst>

A path to where the output package should be created.

--package-name <package_name>

Name of the package

alfasim-sdk compile

Compile the plugin from the given plugin-dir option. When not provided plugin-dir will be the current folder location.

This command basically calls the compile.py informing the location of the header files of alfasim_sdk_api. For more details about the build steps, check the compile.py generated for your plugin project.

alfasim-sdk compile [OPTIONS]

Options

--plugin-dir <plugin_dir>

Path to the plugin directory, where configuration and the shared library is located.

Application Hooks

The application hooks allow plugins to add custom models or custom checks in the application. To add an application hook it is necessary to implement the given hook in a python file that is already available on your plugin project folder.

As an example, if the alfasim-sdk template command was created with the name myplugin, the necessary file to be customized will be located on: myplugin ‣ src ‣ python ‣ myplugin.py

Plugin Model

alfasim_get_data_model_type()

This hook allows the creation of models in ALFAsim, models can:

  • Customize items on ALFAsim application, by adding new components over the Tree.

  • Hold input data information to be accessed from the solver.

  • Validate input data or configuration made on ALFAsim, to ensure that the plugin has all configuration necessary to be run successfully.

This hook needs to return a class decorated with one of the following options:

  • alfasim_sdk.models.container_model()

  • alfasim_sdk.models.data_model()

The image below shows the locations where a custom model can be inserted implementing the hook.

_images/tree_plugin_marker.png _images/model_explorer_with_marker.png

m_1 Location to where the models container_model() or data_model() will be placed.
m_2 Location to where the inputs fields will be placed.

Example 1: The following example shows how to create a new model.

import alfasim_sdk
from alfasim_sdk import data_model
from alfasim_sdk import Quantity

@data_model(icon="", caption="My Plugin")
class MyModel:
    distance = Quantity(value=1, unit="m", caption="Distance")

@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModel]

The image below shows the output of example 1 when executing on ALFAsim.

_images/alfasim_get_data_model_type_example_1.png

Example 2: This second example shows how to create a new container model.

Notice that when using the container_model() you only need to inform the container class to the alfasim_get_data_model_type() hook

import alfasim_sdk
from alfasim_sdk import data_model, container_model
from alfasim_sdk import Quantity, String

@data_model(icon="", caption="My Child")
class ChildModel:
    distance = Quantity(value=1, unit="m", caption="Distance")


@container_model(icon='', caption='My Container', model=ChildModel)
class MyModelContainer:
    my_string = String(value='Initial Value', caption='My String')


@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModelContainer]

The image below shows the output of example 2 when executing on ALFAsim.

_images/alfasim_get_data_model_type_example_2.png

Example 3: This third example demonstrates that it’s possible to create multiple models within the plugin

import alfasim_sdk
from alfasim_sdk import data_model, container_model
from alfasim_sdk import Quantity, String

@data_model(icon="", caption="My Model")
class MyModel:
    distance = Quantity(value=1, unit="m", caption="Distance")

@data_model(icon="", caption="My Child")
class ChildModel:
    distance = Quantity(value=1, unit="m", caption="Distance")

@container_model(icon='', caption='My Container', model=ChildModel)
class MyModelContainer:
    my_string = String(value='Initial Value', caption='My String')


@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModelContainer, MyModel]

The image below shows the output of example 3 when executing on ALFAsim.

_images/alfasim_get_data_model_type_example_3.png

Status Monitor

alfasim_get_status(ctx)

Allows plugins to execute custom checks on ALFAsim. These checks can be used to guarantee the consistency of the data or compatibility with some configuration made on ALFAsim.

The status monitor accepts two types of message:

  • ErrorMessage():

    Signalize the application to block the simulation until the error is fixed.

  • WarningMessage():

    Signalize the application that the user needs to fix this problem, but does not need to block the simulation.

When no errors are detected, an empty list must be returned.

The alfasim_get_status will be called for:

  • Each time a model from the plugin is modified.

  • Each time a Physics options from ALFAsim are modified.
    Ex.: Hydrodynamic model changed

The ctx parameter is provided to retrieve information about the current state of the application and the current value of the models implemented by the user.

Check out the full documentation of alfasim_sdk.context.Context for more details.

The following example shows how to display an ErrorMessage when a Quantity() field does not have the desired value.

import alfasim_sdk
from alfasim_sdk import data_model
from alfasim_sdk import Quantity
from alfasim_sdk import ErrorMessage

# Define MyModel used in this plugin
@data_model(icon="", caption="My Plugin Model")
class MyModel:
    distance = Quantity(
        value=1, unit="m", caption="Distance"
    )


@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModel]


# Add status monitor in the plugin
@alfasim_sdk.hookimpl
def alfasim_get_status(ctx):
    results = []
    distance = ctx.GetModel("MyModel").distance.value
    if distance < 0:
        message = f"Distance must be greater than 0, got {distance}"

        results.append(
            ErrorMessage(
                model_name="MyModel",
                message=message,
            )
        )
    return results

For the status monitor above, the application will show the following message when the distance is less than 0:

_images/status_monitor_with_distance_error.png

Solver Configuration Hooks

The solver configuration hooks allow plugins to configure internal settings from ALFAsim. To add a configuration hook it is necessary to implement the given hook in a python file that is already available on your plugin project folder.

As an example, if a plugin was created using alfasim-sdk template command and named as myplugin the necessary file to be customized would be located on: myplugin ‣ src ‣ python ‣ myplugin.py

Additional Variables

alfasim_get_additional_variables()

Allows plugins to register new additional variables on ALFAsim.

It can be used to store the internal variable from the plugin (on solver), or it can be used to expose as an output to the user in the plot window (on application). To calculate and update the registered variables the Solver hooks described on Update plugin variables section must be implemented.

This method expects to return a list of alfasim_sdk.variables.SecondaryVariable(), for more details checkout the reference section with all details about variables

Usage example:

from alfasim_sdk import SecondaryVariable
from alfasim_sdk import Visibility
from alfasim_sdk import Location
from alfasim_sdk import Scope

@alfasim_sdk.hookimpl
def alfasim_get_additional_variables():
    return [
        SecondaryVariable(
            name='dummy_variable',
            caption='Plugin 1',
            unit='m',
            visibility=Visibility.Internal,
            location=Location.Center,
            multifield_scope=Scope.Global,
            checked_on_gui_default=True,
        )]

Hydrodynamic Model

ALFAsim provides a way to customize the hydrodynamic model available within the application, with the usage of the hook listed below, the plugin can:

  • Add new fields

  • Add/update phases

  • Add/update layers

Note

For each new added field is considered a mass conservation equation and for each new added layer is considered a momentum conservation and an energy conservation equations, depending on the energy model used at ALFAsim.

alfasim_configure_fields()

Allows plugins to configure new fields to be added in ALFAsim’s hydrodynamic model.

An added field must be associated with:

  • Phase, defined by AddPhase or UpdatePhase.

  • Layer, defined by AddLayer or UpdateLayer.

Example of usage:

@alfasim_sdk.hookimpl
def alfasim_configure_fields():
   return [
       AddField(name='plugin_continuous_field'),
       AddField(name='plugin_dispersed_field'),
   ]
alfasim_configure_phases()

Allows plugins to configure new phases or associate a new field with a existing phase from the application. In order to configure a new phase it is necessary to return an AddPhase object defining the required fields.

Example of usage:

@alfasim_sdk.hookimpl
def alfasim_configure_phases():
    return [
        AddPhase(
            name='plugin_phase',
            fields=[
                'plugin_continuous_field',
                'plugin_dispersed_field',
            ],
            primary_field='plugin_continuous_field',
            is_solid=False,
        )
    ]

With this new phase, all existing hydrodynamic models from the application will have this additional phase. Notice that the fields parameter must be a field registered from the hook alfasim_configure_fields().

Note

You can restrict the operation of your plugin in the application to certain settings by using the status monitor. For example, if your plugin does not work with the water phase you can block the simulation if the user is using a hydrodynamic model with water.

For more details check out the documentation of alfasim_get_status()

The image below shows the new added phase on the application.

_images/alfasim_configure_phase_example_1.png

It is also possible to add additional fields to existent phases using the UpdatePhase.

Example of usage:

@alfasim_sdk.hookimpl
def alfasim_configure_phases():
    return [
        UpdatePhase(
            name=OIL_PHASE,
            additional_fields=['plugin_dispersed_field'],
        )
    ]
alfasim_configure_layers()

Allows plugins to configure new layers or associate a new field with a existing layer for ALFAsim’s hydrodynamic model

In order to configure a new layer, it is necessary to return an AddLayer object defining the required fields.

Example of usage:

@alfasim_sdk.hookimpl
def alfasim_configure_layers():
   return [
       AddLayer(
           name='plugin_layer',
           fields=['plugin_continuous_field'],
           continuous_field='plugin_continuous_field',
       ),
       UpdateLayer(
           name=OIL_LAYER,
           additional_fields=['plugin_dispersed_field'],
       ),
   ]

The image below shows the new added phase on the application.

_images/alfasim_configure_layer_example_1.png

In order to complement the Hydrodynamic model customization, it is possible to inform ALFAsim which phases (added from plugin or not) will have the state variables calculated by plugin.

alfasim_get_phase_properties_calculated_from_plugin()

Allows the plugin to calculate the properties (state variables) of a phase.

Must return a list of phase names in which state variables will be computed for. If the plugin implements this hook four C/C++ Solver hooks also must be implemented. They are:

  • HOOK_INITIALIZE_STATE_VARIABLE_CALCULATOR

  • HOOK_CALCULATE_STATE_VARIABLE

  • HOOK_CALCULATE_PHASE_PAIR_STATE_VARIABLE

  • HOOK_FINALIZE_STATE_VARIABLE_CALCULATOR

The first and last hooks are called immediately before and after the state variables are calculated, respectively.

Example of usage:

from alfasim_sdk import GAS_PHASE

@alfasim_sdk.hookimpl
def alfasim_get_phase_properties_calculated_from_plugin():
    return [GAS_PHASE, 'solid']
alfasim_get_phase_interaction_properties_calculated_from_plugin()

Allows the plugin to calculate the properties that are related to a pair of phases, like surface tension.

Must return a list of tuple of phases in which state variables will be computed for. In order to implement the properties, HOOK_CALCULATE_PHASE_PAIR_STATE_VARIABLE must be implemented on the C/C++ part of the plugin.

Example of usage:

from alfasim_sdk import GAS_PHASE, OIL_PHASE, WATER_PHASE

@alfasim_sdk.hookimpl
def alfasim_get_phase_interaction_properties_calculated_from_plugin():
return [
    (GAS_PHASE, OIL_PHASE),
    (GAS_PHASE, WATER_PHASE),
]

User Defined Tracers

Warning

This is advanced customization. We strongly encourage the plugin developer to read the Tracers chapter of ALFAsim’s Technical Report available on the Help menu at ALFAsim application.
manual

alfasim_get_user_defined_tracers_from_plugin()

Allows the plugin to add new tracers in the ALFAsim’s Tracer Solver, in which the transport equation will be modified by Solver hooks listed below.

Must return a list of tracers in which the internal tracer model hooks will be implemented. The following C/C++ Solver hooks must be implemented:

  • HOOK_INITIALIZE_MASS_FRACTION_OF_TRACER

  • HOOK_COMPUTE_MASS_FRACTION_OF_TRACER_IN_PHASE

  • HOOK_COMPUTE_MASS_FRACTION_OF_TRACER_IN_FIELD

  • HOOK_SET_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER

  • HOOK_UPDATE_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER

Example of usage:

@alfasim_sdk.hookimpl
def alfasim_get_user_defined_tracers_from_plugin():
    return ['my_tracer']

Note

The tracer added in the user-defined tracers from plugin list will not be considered as a standard tracer, which has an output of its mass fraction and appears in the tracer container at ALFAsim’s User Interface. The user-defined tracer is hidden (does not appear in the User Interface) and the plugin developer can modify the transport equation to use its results internally. However, the user-defined tracers will be solved together with the standard tracers (Added via User Interface).

Solver Hooks

The present section describes all solver Hooks available on ALFAsim plugin infrastructure. Solver Hooks are ALFAsim’s pre-defined functions that allows the plugin developer to modify/extend ALFAsim’s Solver. As already informed in Quick Start section once created a plugin using template option on ALFAsim-SDK’s CLI a new file named plugin.c will be available to implement those hooks.

Note

There is no need to implement all solver hooks in the plugin. It depends on which functionality the developer wants to extend in the ALFAsim model.

In order to help the developer to decide which hooks to implement in the plugin, they are shown below according to their classification which identifies what part of the solver workflow is related to.

To better visualize the interaction of the hooks with the solver, the Simulator WorkFlow chapter has several graphs illustrating the solver’s walkthrough, showing where each hook will be called. The following graph is the same one available at Main Overview section from Simulator WorkFlow. It illustrates where the HOOK_INITIALIZE and the HOOK_FINALIZE will be called.

digraph { nodesep = 0.6; newrank=true node [fillcolor="#FAAC2C" style="rounded, filled" color="#FAAC2C" fontcolor="#ffffff"] edge [color="#8699A3" fontcolor="#2c3e50"] init [label="Initialize Simulation"] end [label="End of Simulation"] node [shape=point, width=0] invisible_point hook_initialize_point [peripheries="2"] hook_finalize_point [peripheries="2"] time [fixedsize=true, label="Time Step", width="1.0", shape="circle"]; decision [label="Final \n Time?", shape="diamond", fixedsize=true, width=2.0, height=1.0, labelcolor="#8699A3", style="filled"] node[shape="rectangular", target="_top"] config [label="Solver Configuration"] hyd_solver [label="Hydrodynamic Solver", URL="../07_workflow.html#hydrodynamic-solver"] tracer_solver [label="Tracer Solver" URL="../07_workflow.html#tracer-solver"] output [label="Output Variables"] node[peripheries="0" shape="cds", color="#DA5961", fontcolor="#DA5961", style=""] hook_initialize [ label="HOOK_INITIALIZE", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.initialize"] hook_finalize [label="HOOK_FINALIZE", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.finalize"] {rank = same; hook_initialize_point; hook_initialize} {rank = same; hook_finalize_point; hook_finalize; } {rank=same; time;tracer_solver} {rank=same; invisible_point;hyd_solver} init -> config; config -> hook_initialize_point [arrowhead= none]; hook_initialize_point -> invisible_point [arrowhead=none]; hook_initialize_point -> hook_initialize [style=dotted, color="#DA5961"]; subgraph cluster_a{ label="Transient Solver" style="dashed, rounded" shape="reactangular" color="#8699A3" fontcolor="#2c3e50" labeljust="l" invisible_point -> time; time:ne -> hyd_solver:w [style=dashed]; hyd_solver -> tracer_solver [weight=1000]; tracer_solver -> output [weight=1000]; output:nw -> time:se [style=dashed]; time:s -> decision:n [weight=10]; decision:w -> time:sw [label="No"]; } decision -> hook_finalize_point [arrowhead= none, label="Yes"]; hook_finalize_point -> hook_finalize [style=dotted, color="#DA5961"]; hook_finalize_point -> end; }

Initial configuration and plugin internal data

In the User Interface Hooks section is explained that the plugins are allowed to customize the ALFAsim’s user interface extending it in order to get some input data from the user. Using the solver HOOK_INITIALIZE the developer can obtain the input data from user interface and use it to initialize the plugin internal data.

As already mentioned, it is allowed that the plugins have internal data, in which can hold some important information that will be used during the simulation, and also by other hooks.

Warning

The plugin internal data will be hold by ALFAsim’s solver, however the plugin has full responsibility to allocate and deallocate its data from memory.

initialize(ctx)

c++ signature : HOOK_INITIALIZE(void* ctx)

This hook allows the plugin to initialize its internal data and also some simulator configurations available via API. If any API function is used the ALFAsim-SDK API must be loaded, see ALFAsim-SDK API Loading section for more information.

Parameters

ctx – ALFAsim’s plugins context

Returns

Return OK if successful or anything different if failed

Examples of usage:

A minimal HOOK_INITIALIZE needed could be:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
ALFAsimSDK_API alfasim_sdk_api;

HOOK_INITIALIZE(ctx) {
    const char* plugin_id = get_plugin_id()
    // Loading ALFAsim-SDK API
    int load_error_code = alfasim_sdk_open(alfasim_sdk_api)
    if (load_error_code != 0){
        return load_error_code;
    }
    return OK;
}

Where OK is an error_code value and get_plugin_id() function is created automatically to each plugin template and accessible from hook_specs.h file. As can be seen in the example above at least the ALFAsim-SDK API should be loaded.

However, if the plugin has internal data the minimal HOOK_INITIALIZE implementation would be

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ALFAsimSDK_API alfasim_sdk_api;

HOOK_INITIALIZE(ctx)
{
    const char* plugin_id = get_plugin_id()
    // Loading ALFAsim-SDK API
    int load_error_code = alfasim_sdk_open(alfasim_sdk_api)
    if (load_error_code != 0){
        return load_error_code;
    }
    // Threads Information
    int n_threads = -1;
    int errcode = alfasim_sdk_api.get_number_of_threads(
        ctx, &n_threads);
    if (errcode != 0){
        return errcode;
    }
    // Setting internal data to each thread
    for (int thread_id = 0; thread_id < n_threads; ++thread_id){
        double value;
        alfasim_sdk_api.get_plugin_input_data_quantity(
            ctx, &value, plugin_id, thread_id);
        void* data = new double(value);
        alfasim_sdk_api.set_plugin_data(
            ctx, plugin_id, data, thread_id);
    }
    return OK;
}

It is important to note that void* data at line 22 could be a more complex data structure, like a class object for example.

As can be seen in the example above the function set_plugin_data() is used to tell the ALFAsim’s solver to hold the plugin internal data.

Note

Since ALFAsim’s solver uses multi-threading to perform all possible parallelizable calculation, it is important that the plugins provide internal data to each thread to avoid data access concurrency problems. As can be seen the HOOK_INITIALIZE example above, a for-loop is performed over the threads to set the plugin internal data. The ALFAsim-SDK API function get_number_of_threads() is used to do it properly. See Plugin Internal Data section for more information.

finalize(ctx)

c++ signature : HOOK_FINALIZE(void* ctx)

This Hook must be used to delete all plugin internal data and unload the ALFAsim-SDK API. Otherwise, a memory leak could occur from your plugin.

Parameters

ctx – ALFAsim’s plugins context

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
HOOK_FINALIZE(ctx)
{
    // Threads information
    int n_threads = -1;
    int errcode = alfasim.get_number_of_threads(ctx, &n_threads);
    f (errcode != 0){ // or errcode != OK
        return errcode;
    }
    const char* plugin_id = get_plugin_id();
    // Plugin internal data
    for (int thread_id = 0; thread_id < n_threads; ++thread_id) {
        void* data = nullptr;
        errcode = alfasim.get_plugin_data(
            ctx, &data, plugin_id, thread_id);
        delete data;
    }
    // Unloading ALFAsim-SDK API
    int load_error_code = alfasim_sdk_close(alfasim_sdk_api)
    if (load_error_code != 0){
        return load_error_code;
    }
    return OK;
}

Where OK is an error_code value.

As can be seen in the example above the function get_plugin_data() is used to retrieved the plugin internal data for each thread identified as thread_id.

Note

In the examples of usage of both HOOK_INITIALIZE and HOOK_FINALIZE there are many times where an error code is returned (return errcode; or return OK;). As can be seen, it is possible to return error codes from ALFAsim-SDK API functions, however the developer can intercept this error code and handle it instead of returning it to the ALFAsim’s Solver.

Update plugin variables

The hooks described in this section are related to plugin secondary variables that were registered in the python config file, as already explained in Solver Configuration section. They are called secondary variables because they are not obtained from ALFAsim’s Solver, these ones are called primary variables and examples of those variables are pressure, temperature, volume fractions and velocities.

Using the following hooks the plugin is able to calculate/update those variables in three different moments of the simulation step. Two of them are called in the Hydrodynamic Solver scope and the last one is called in the Tracers Solver scope as illustrated on Hydrodynamic Solver and Tracer Solver workflow section. Once the solver obtain results for primary variables, it updates all secondary variables in which depend on primary variables. After that, HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES is called, but if it is running the first time step HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES_ON_FIRST_TIMESTEP is called before. It is necessary because usually during the first time step some initialization tasks are needed. Then, if the plugin needs to initialize with some value that is different from the initial nan value, this hook is the place to do that.

Note

Different from plugin internal data, the secondary variables registered by plugins are allocated, deallocated and held by ALFAsim’s Solver. It is necessary because the variables arrays are dependent on network with its discretization and on hydrodynamic model, which defines the fluid flow’s phases, fields and layers.

update_plugins_secondary_variables(ctx)

c++ signature : HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES(void* ctx)

Internal simulator hook to update plugin’s secondary variables. This is called as the last step on ALFAsim’s update internal secondary variables workflow.

Parameters

ctx – ALFAsim’s plugins context

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES(ctx)
{
    int errcode = -1;
    int size_U = -1;
    int size_E = -1;
    int liq_id = -1;
    errcode = alfasim_sdk_api.get_field_id(
        ctx, &oil_id, "oil");
    double* vel;
    VariableScope Fields_OnFaces = {
        GridScope::FACE,
        MultiFieldDescriptionScope::FIELD,
        TimestepScope::CURRENT
    }
    errcode = alfasim_sdk_api.get_simulation_array(
        ctx, &vel, (char*) "U", Fields_OnFaces, liq_id, &size_U);
    double* kinetic_energy;
    char* name = "kinetic_energy_of_oil";
    int global_idx = 0;
    errcode = alfasim_sdk_api.get_plugin_variable(
        ctx,
        (void**) (&kinetic_energy),
        name,
        global_idx,
        TimestepScope::CURRENT,
        &size_E);
    if (size_U != size_E){
        return OUT_OF_BOUNDS;
    }
    for (int i =0; i < size_U; ++i){
        kinetic_energy[i] = vel[i] * vel[i] / 2.;
    }
    return OK;
}

In the example above the variable kinetic_energy_of_oil was registered as a global variable, but its value is obtained for oil field. If this variable would be calculated to all fields then the global_idx would be substituted by field_idx and it would be performed to each field.

update_plugins_secondary_variables_on_first_timestep(ctx)

c++ signature : HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES_ON_FIRST_TIMESTEP(void* ctx)

Internal simulator hook to update plugin’s secondary variables on the first timestep. This is called as the first step on ALFAsim’s update internal variables workflow. This method is specially important when you have a plugin which the secondary variables depend on old values. In the first timestep, there is no old values, so you may use this hook to initialize your variables contents.

Parameters

ctx – ALFAsim’s plugins context

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES_ON_FIRST_TIMESTEP(ctx)
{
    int errcode = -1;
    int size_E = -1;
    double* kinetic_energy;
    char* name = "kinetic_energy_of_oil";
    int global_idx = 0;
    errcode = alfasim_sdk_api.get_plugin_variable(
        ctx,
        (void**) (&kinetic_energy),
        name,
        global_idx,
        TimestepScope::CURRENT,
        &size_E);
    for (int i =0; i < size_U; ++i){
        kinetic_energy[i] = 0.0;
    }
    return OK;
}

The ALFAsim’s Solver is divided in two non-linear solvers solvers that will solve different group of equations. The first one is the hydrodynamic solver which solves the Mass Conservation of fields, Momentum Conservation of layers and Energy Conservation equations all together for all elements in the network. The second one is the Tracer Solver which solves the Mass Conservation Equation for each added tracer. Since the tracers mass conservation is a transport equation it is solved after hydrodynamic solver and using its results (such as velocities) as input data in the Tracer Solver. See the ALFAsim’s Technical Report for more information.

To complete the group of hooks related to the plugins secondary variables there is the HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES_ON_TRACER_SOLVER. This hook is used to update plugin’s variables that depends on Tracer’s mass fractions and has to be updated in the Tracer Solver scope.

update_plugins_secondary_variables_on_tracer_solver(ctx)

c++ signature : HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES_ON_TRACER_SOLVER(void* ctx)

Internal simulator hook to update plugin’s secondary variables in the Tracer Solver scope. Tracer Solver is used to solve the tracer transport equation. This is called as the last step on ALFAsim’s Tracer Solver update variables workflow.

Parameters

ctx – ALFAsim’s plugins context

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES_ON_TRACER_SOLVER(ctx)
{
    const char* plugin_id = get_plugin_id()
    int errcode = -1;
    int size_t = -1;
    int size_p_var = -1;
    int liq_id = -1;
    errcode = alfasim_sdk_api.get_field_id(
        ctx, &oil_id, "oil");
    double* tracer_mass_fraction;
    VariableScope global_OnCenters = {
        GridScope::FACE,
        MultiFieldDescriptionScope::FIELD,
        TimestepScope::CURRENT
    }
    // Tracer information
    void* tracer_ref;
    errcode = alfasim_sdk_api.get_tracer_ref_by_name(
        ctx,
        &tracer_ref,
        "my_tracer", // Added by User interface
        plugin_id);
    int tracer_id = -1;
    errcode = alfasim_sdk_api.get_tracer_id(
        ctx, &tracer_id, tracer_ref);
    double *tracer_mass_fraction
    errcode = alfasim_sdk_api.get_simulation_tracer_array(
        ctx,
        &tracer_mass_fraction,
        (char*) "phi",
        global_OnCenters,
        tracer_id,
        0,  // GLOBAL
        &size_t);
    // Plugin secondary variable array
    double* plugin_var;
    errcode = alfasim_sdk_api.get_plugin_variable(
        ctx,
        (void**) (&plugin_var),
        name,
        0,  // GLOBAL
        TimestepScope::CURRENT,
        &size_p_var);
    if (size_t != size_p_var){
        return OUT_OF_BOUNDS;
    }
    for (int i =0; i < size_t; ++i){
        // Do some calculations with plugin_var
        // using tracer_mass_fraction values
    }
    return OK;
}

Note that functions like get_tracer_ref_by_name(), get_tracer_id() and get_simulation_tracer_array() were used to obtain information related to tracers.

Warning

It is important that the plugin developer take care of registered plugin’s secondary variables, since their values will be set equal to nan at first place and it will not be changed by ALFAsim’s Solver at any time during the simulation.

Source Terms

The hooks showed in this section can be considered as the most important. Since they allow the plugin to change the conservation equations. This is achieved by adding source terms in the residual function of mass, momentum and energy conservation equations. Since the equations are in residual form, the negative values of source terms indicate that mass, momentum and energy will be consumed. Otherwise, some amount of mass, momentum, and energy will be generated.

calculate_mass_source_term(ctx, mass_source, n_fields, n_control_volumes)

c++ signature : HOOK_CALCULATE_MASS_SOURCE_TERM(void* ctx, void* mass_source, int n_fields, int n_control_volumes)

Internal simulator hook to calculate source terms of mass equation. This is called after all residual functions are evaluated.

The plugin is supposed to change the given mass_source array pointer. Its values are contiguous in memory and the dimensions are given by n_fields and n_control_volumes. It has unit equal to [kg/s].

Parameters
  • ctx – ALFAsim’s plugins context

  • mass_source – Source term of mass equation

  • n_fields – Number of fields

  • n_control_volumes – Number of control volumes

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
HOOK_CALCULATE_MASS_SOURCE_TERM(
    ctx, mass_source, n_fields, n_control_volumes)
{
    int liq_id = -1;
    errcode = alfasim_sdk_api.get_field_id(
        ctx, &oil_id, "oil");
    // Convertion from void* to double* and getting the
    // array range related to oil field
    double* oil_mass_source =
        (double*) mass_source + n_control_volumes * liq_id;
    // Make some calculations and add it to oil_mass_source.
    // In this example, we add a mass source of 3.1415 kg/s to all control volumes.
    for (int i = 0; i < n_control_volumes; ++i) {
        oil_mass_source[i] = 3.1415; // [kg/s]
    }
    return OK;
}

In the example above is shown how to manage the mass_source array to get the mass source term array related to a specific field (oil field in this case). Note that oil_mass_source has size equal to n_control_volumes.

calculate_momentum_source_term(ctx, momentum_source, n_layers, n_faces)

c++ signature : HOOK_CALCULATE_MOMENTUM_SOURCE_TERM(void* ctx, void* momentum_source, int n_layers, int n_faces)

Internal simulator hook to calculate source terms of momentum equation. This is called after all residual functions are evaluated.

The plugin is supposed to change the given momentum_source array pointer. Its values is contiguous in memory and the dimensions are given by n_layers and n_faces. It has unit equal to [N].

Parameters
  • ctx – ALFAsim’s plugins context

  • momentum_source – Source term of momentum equation

  • n_layers – Number of layers

  • n_faces – Number of faces (equal to n_control_volumes minus 1)

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
HOOK_CALCULATE_MOMENTUM_SOURCE_TERM(
    ctx, momentum_source, n_layers, n_faces)
{
    int gas_id = -1;
    errcode = alfasim_sdk_api.get_layer_id(
        ctx, &gas_id, "gas");
    // Convertion from void* to double* and getting the
    // array range related to gas layer
    double* gas_momentum_source =
        (double*) momentum_source + n_faces * gas_id;
    // Make some calculations and add it to gas_momentum_source
    return OK;
}

In the example above is shown how to manage the momentum_source array to get the momentum source term array related to a specific layer (gas layer in this case). Note that gas_momentum_source has size equal to n_faces.

calculate_energy_source_term(ctx, energy_source, n_energy_equation, n_control_volumes)

c++ signature : HOOK_CALCULATE_ENERGY_SOURCE_TERM(void* ctx, void* energy_source, int n_energy_equation, int n_control_volumes)

Internal simulator hook to calculate source terms of energy equation. This is called after all residual functions are evaluated.

The plugin is supposed to change the given energy_source array pointer. Its values is contiguous in memory and the dimensions are given by n_energy_equation and n_control_volumes. It has unit equal to [J/s].

Since ALFAsim considers two energy models, if n_energy_equation is equal to 1 it means that the global energy model is being used. Otherwise the layers energy model is being used. See the ALFAsim’s Technical Report for more information about the equations system.

Parameters
  • ctx – ALFAsim’s plugins context

  • energy_source – Source term of energy equation

  • n_energy_equation – Number of Energy Equation being solved

  • n_control_volumes – Number of control volumes

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
HOOK_CALCULATE_ENERGY_SOURCE_TERM(
    ctx, energy_source, n_energy_equation, n_control_volumes)
{
    double* gas_energy_source;
    if (n_energy_equation > 1){
        // Layers Energy model
        // One energy equation for each layer
        int gas_id = -1;
        errcode = alfasim_sdk_api.get_layer_id(
            ctx, &gas_id, "gas");
        // Convertion from void* to double* and getting the
        // array range related to gas layer
        gas_energy_source =
            (double*) energy_source + n_faces * gas_id;
    } else {
        // Global energy model
        // Only one global energy equation

        // Convertion from void* to double*
        gas_energy_source = (double*) energy_source;
    }
    // Make some calculations and add it to gas_energy_source
    return OK;
}

In the example above is shown how to manage the energy_source array to get the energy source term array related to a specific layer (gas layer in this case). Note that gas_energy_source has size equal to n_control_volumes.

calculate_tracer_source_term(ctx, phi_source, n_tracers, n_control_volumes)

c++ signature : HOOK_CALCULATE_TRACER_SOURCE_TERM(void* ctx, void* phi_source, int n_tracers, int n_control_volumes)

Internal simulator hook to calculate source terms of tracer transport equation. This is called after all residual functions are evaluated.

The plugin is supposed to change the given phi_source array pointer. Its values is contiguous in memory and the dimensions are given by n_tracers and n_control_volumes. It has unit equal to [kg/s].

Parameters
  • ctx – ALFAsim’s plugins context

  • phi_source – Source term of tracers mass equation

  • n_tracers – Number of tracers

  • n_control_volumes – Number of control volumes

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
HOOK_CALCULATE_TRACER_SOURCE_TERM(
    ctx, phi_source, n_tracers, n_control_volumes)
{
   // Tracer information
    void* tracer_ref;
    errcode = alfasim_sdk_api.get_tracer_ref_by_name(
        ctx,
        &tracer_ref,
        "my_tracer", // Added by User interface
        plugin_id);
    int tracer_id = -1;
    errcode = alfasim_sdk_api.get_tracer_id(
        ctx, &tracer_id, tracer_ref);
    // Convertion from void* to double* and getting the
    // array range related to gas layer
    double* my_tracer_phi_source =
        (double*) phi_source + n_control_volumes * tracer_id;
    // Make some calculations and add
    // it to my_tracer_phi_source
    return OK;
}

In the example above is shown how to manage the phi_source array to get the tracer source term array related to a specific tracer (my_tracer in this case). Note that gas_energy_source has size equal to n_control_volumes.

State Variables for additional phases

As can be seen in Hydrodynamic Model section the plugins can add new fields, phases and layers. Also, it is possible to indicate if a phase will have its state variables calculated from plugin implementing the alfasim_get_phase_properties_calculated_from_plugin().

initialize_state_variables_calculator(ctx, P, T, T_mix, n_control_volumes, n_layers)

c++ signature : HOOK_INITIALIZE_STATE_VARIABLES_CALCULATOR(void* ctx, void* P, void* T, void* T_mix, int n_control_volumes, int n_layers)

Hook for the state variables calculator initialization (internal ALFAsim structure).

At this point, it is possible to pre-calculate and cache any relevant information. Then, for each state variable of the phases in the python configuration file, the hook HOOK_CALCULATE_STATE_VARIABLE is called and return the pre-calculated values.

Parameters
  • ctx – ALFAsim’s plugins context

  • P – Pressure values array

  • T – Temperature values array

  • T_mix – Mixture temperature values array

  • n_control_volumes – Number of control volumes

  • n_layers – Number of layers

Returns

Return OK if successful or anything different if failed

The P and T_mix have size equal to n_control_volumes. However, T has values contiguous in memory and its dimensions are given by n_layers and n_control_volumes

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
HOOK_INITIALIZE_STATE_VARIABLES_CALCULATOR(
    void* ctx, void* P, void* T, void* T_mix,
    int n_control_volumes, int n_layers)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    // MyStruct is a developer defined struct to hold
    // all important information for plugin hooks.
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    // MyFunction is a function implemented by
    // plugin developer that computes de density
    data.density = MyFunction(P, T_mix, n_control_volumes);
    return OK;
}
// Then, to use the cached value:
HOOK_CALCULATE_STATE_VARIABLE(
    void* ctx, void* P, void* T, int n_control_volumes, i
    nt n_layers, int phase_id, int property_id, void* output)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    if (phase_id != data.my_added_phase_id) {
        return OK;
    }
    if (property_id == StateVariable::RHO) {
        for (int i = 0; i < n_control_volumes; ++i) {
            output[i] = data.density[i];
        }
    }
    return OK;
}

Note

For pre-calculated values, the plugin developer must cache it in the plugin internal data. See the example above.

However, if the state variable is considered constant or the developer doesn’t need to cache the values, just return OK.

calculate_state_variable(ctx, P, T, n_control_volumes, phase_id, property_id, output)

c++ signature : HOOK_CALCULATE_STATE_VARIABLE(void* ctx, void* P, void* T, int n_control_volumes, int n_layers, int phase_id, int property_id, void* output)

Hook to calculate the state variable given by the property_id (See StateVariable values), for the phase with phase_id (Note that the phase id is the same as the one retrieved from the get_phase_id() API function - It is not advisable to use hardcoded numbers).

List of affected variables:
- Density
- Viscosity
- Heat Capacity
- Partial Derivative of Density in Relation to Pressure
- Partial Derivative of Density in Relation to Temperature
- Enthalpy
- Thermal Conductivity

Parameters
  • ctx – ALFAsim’s plugins context

  • P – Pressure values array

  • T – Temperature values array

  • n_control_volumes – Number of control volumes

  • n_layers – Number of layers

  • n_phase_id – Id of phase in which the property must be calculated

  • property_id – A StateVariable value. It indicates which property must be calculated

  • output – Output values array

Returns

Return OK if successful or anything different if failed

The output parameter must be filled with the calculated property for each control volume. The pressure P and layer or mixture temperature T (Depending on the energy model being used) are given in order to perform the calculation. The number of control volumes is also given for convenience.

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
HOOK_CALCULATE_STATE_VARIABLE(
    void* ctx, void* P, void* T,
    int n_control_volumes, int n_layers,
    int phase_id, int property_id, void* output)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    if (phase_id != data.my_added_phase_id) {
        return OK;
    }
    if (property_id == StateVariable::RHO) {
        for (int i = 0; i < n_control_volumes; ++i) {
            // If the property has a constant value
            output[i] = data.constant_density;
            // If the property must be computed
            // MyStruct has a function called 'compute_density()'
            output[i] = data.compute_density(
                (double *)P[i], (double *)T[i]);
        }
    }
    return OK;
}

Warning

The plugin developer must NOT change any variable other than the output. The output size is n_control_volumes .

calculate_phase_pair_state_variable(ctx, P, T_mix, n_control_volumes, phase1_id, phase2_id, property_id, output)

c++ signature : HOOK_CALCULATE_PHASE_PAIR_STATE_VARIABLE(void* ctx, void* P, void* T_mix, int n_control_volumes, int phase1_id, int phase2_id, int property_id, void* output)

Hook to calculate the state variable given by the property_id (See :cpp:enum:StateVariable values), for the phase pair (phase1_id, phase2_id) (Note that the phase id is the same as the one retrieved from the get_phase_id() API function - It is not advisable to use hardcoded numbers).

List of affected variables:
- Interfacial Tension

Parameters
  • ctx – ALFAsim’s plugins context

  • P – Pressure values array

  • T_mix – Mixture temperature values array

  • n_control_volumes – Number of control volumes

  • n_phase1_id – Id of phase one in which the property must be calculated

  • n_phase2_id – Id of phase two in which the property must be calculated

  • property_id – A StateVariable value. It indicates which property must be calculated

  • output – Output values array

Returns

Return OK if successful or anything different if failed

The output parameter must be filled with the calculated property for each control volume. The pressure P and mixture temperature T_mix are given in order to perform the calculation. The number of control volumes is also given for convenience.

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
HOOK_CALCULATE_PHASE_PAIR_STATE_VARIABLE(
    void* ctx, void* P, void* T_mix, int n_control_volumes,
    int phase1_id, int phase2_id, int property_id, void* output)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    int gas_phase_id = -1;
    errcode = alfasim_sdk_api.get_phase_id(
        ctx, &gas_phase_id, "gas");

    if ((
        (phase1_id == data.my_added_phase_id)
        && (phase1_id == gas_phase_id)
        ) || (
        (phase1_id == gas_phase_id)
        && (phase1_id == data.my_added_phase_id)
        ))
    {
        for (int i = 0; i < n_control_volumes; ++i) {
            // If the property has a constant value
            output[i] = data.constant_surface_tension;
            // If the property must be computed
            // MyStruct has a function
            // called 'compute_surface_tension()'
            output[i] = data.compute_surface_tension(
                (double *)P[i], (double *)T_mix[i]);
        }
    }
    return OK;
}

Warning

The plugin developer must NOT change any variable other than the output. The output size is n_control_volumes.

finalize_state_variables_calculator(ctx)

c++ signature : HOOK_FINALIZE_STATE_VARIABLES_CALCULATOR(void* ctx)

Hook for the state variables calculator finalization. The plugin developer should free/delete any allocated data from the HOOK_INITIALIZE_STATE_VARIABLE_CALCULATOR.

Parameters

ctx – ALFAsim’s plugins context

Returns

Return OK if successful or anything different if failed

If there is no need memory deallocation a minimal implementation would be:

Example of usage:

1
2
3
4
HOOK_FINALIZE_STATE_VARIABLES_CALCULATOR(void* ctx)
{
    return OK;
}

Additional solid phase

When a new phase is added to the hydrodynamic model using the AddPhase type, it is possible to set as a solid phase. In this case, the particle size of fields that are solid phase can be calculated by implementing the following Solver Hooks.Otherwise, the particle size will be considered constant and equal to \(1\times10^{-4}\) meters.

initialize_particle_diameter_of_solids_fields(ctx, particle_diameter, n_control_volumes, solid_field_id)

c++ signature : HOOK_INITIALIZE_PARTICLE_DIAMETER_OF_SOLIDS_FIELDS(void* ctx, void* particle_diameter, int n_control_volumes, int solids_field_id)

Internal simulator hook to initialize particle diameter of solid fields. This hook follows the same idea of HOOK_UPDATE_PLUGIN_SECONDARY_VARIABLES_ON_FIRST_TIMESTEP, which makes the initialization in the moment that there is no previous time step data available.

Parameters
  • ctx – ALFAsim’s plugins context

  • particle_diameter – Particle diameter of a given solid field,

  • n_control_volumes – Number of control volumes,

  • solid_field_id – Index of the solid field in which the particle_diameter Should be calculated.

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
HOOK_INITIALIZE_PARTICLE_DIAMETER_OF_SOLIDS_FIELDS(
    void* ctx, void* particle_diameter,
    int n_control_volumes, int solids_field_id)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    if (solids_field_id != data.my_added_solid_field_id) {
        return OK;
    } else {
        for (int i = 0; i < n_control_volumes; ++i) {
            // If the particle size is constant
            output[i] = data.constant_particle_size;
            // The value is calculated
            // MyStruct has a function
            // called 'initial_particle_size()'
            output[i] = data.initial_particle_size(
                     // List of params that can be
                     // retrieved by get_simulation_array()
                     );
        }
    }
    return OK;
}
update_particle_diameter_of_solids_fields(ctx, particle_diameter, n_control_volumes, solid_field_id)

c++ signature : HOOK_UPDATE_PARTICLE_DIAMETER_OF_SOLIDS_FIELDS(void* ctx, void* particle_diameter, int n_control_volumes, int solids_field_id)

Internal simulator hook to update/calculate particle diameter of solid fields. It is called right before any update secondary variable from ALFAsim’s Solver, because they may depend on the solids particle size (for example Slurry Viscosity calculated by Solids Model)

Parameters
  • ctx – ALFAsim’s plugins context

  • particle_diameter – Particle diameter of a given solid field,

  • n_control_volumes – Number of control volumes,

  • solid_field_id – Index of the solid field in which the particle_diameter Should be calculated.

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
HOOK_UPDATE_PARTICLE_DIAMETER_OF_SOLIDS_FIELDS(
    void* ctx, void* particle_diameter,
    int n_control_volumes, int solids_field_id)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    if (solids_field_id != data.my_added_solid_field_id) {
        return OK;
    } else {
        for (int i = 0; i < n_control_volumes; ++i) {
            // If the particle size is constant
            output[i] = data.constant_particle_size;
            // The value is calculated
            // MyStruct has a function
            // called 'compute_particle_size()'
            output[i] = data.compute_particle_size(
                     // List of params that can be
                     // retrieved by get_simulation_array()
                     );
        }
    }
    return OK;
}

Internal deposit layer

When a new phase is added to the hydrodynamic model using the AddPhase type, it is possible to consider the deposition inside the pipeline walls. If so, calculate the thickness of the deposited layer on a given phase through the usage of update_internal_deposition_layer(). By default, the layer thickness will be considered equal to zero meters.

update_internal_deposition_layer(ctx, thickness, density, heat_capacity, thermal_conductivity, n_control_volumes)

c++ signature : HOOK_UPDATE_INTERNAL_DEPOSITION_LAYER(void* ctx, void* thickness, void* density, void* heat_capacity, void* thermal_conductivity, int n_control_volumes)

Internal simulator hook to evaluate the thickness and thermal properties of the deposited layer at the inside of the pipeline walls. This is called for accounting the diameter reduction and wall thermal effects.

The plugin is supposed to change the given thickness, density, heat_capacity, thermal_conductivity array pointers. Its values are contiguous in memory and the dimension is given by n_control_volumes. It has unit equal to [m].

Parameters
  • ctx – ALFAsim’s plugins context

  • thickness – Thickness of the internal deposit layer

  • density – Density of the internal deposit layer [kg/m3]

  • heat_capacity – Heat capacity of the internal deposit layer [J/(kg.K)]

  • thermal_conductivity – Thermal conductivity of the internal deposit layer [W/(m.K)]

  • n_control_volumes – Number of control volumes

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
HOOK_UPDATE_INTERNAL_DEPOSITION_LAYER(
    ctx, thickness, density, heat_capacity, thermal_conductivity, n_control_volumes)
{
    auto errcode = -1;

    double dt = -1.0;
    errcode = alfasim.get_simulation_quantity(
        ctx, &dt, TimestepScope::CURRENT, (char*) "dt");
    if (errcode != 0) {
        return errcode;
    }

    // Handle first time step, because you won't have the previously information
    double current_time = -1.0;
    errcode = alfasim.get_simulation_quantity(
        ctx, &current_time, TimestepScope::CURRENT, (char*) "time");
    if (errcode != 0) {
        return errcode;
    }

    double wax_density = 900.0 // [kg/m3]
    double wax_heat_capacity = 2140.0 // [J/(kg.K)]
    double wax_thermal_conductivity = 0.25 // [W/(m.K)]

    if (current_time == 0.0){
        // Set a value for the deposition layer thickness
         for (int i = 0; i < n_control_volumes; ++i) {
           (double*) thickness[i] = 0.0; // [m]
           (double*) density[i] = wax_density; // [kg/m3]
           (double*) heat_capacity[i] = wax_heat_capacity; //  [J/(kg.K)]
           (double*) thermal_conductivity[i] = wax_thermal_conductivity; // [W/(m.K)]
        }
    } else{
        // Get previously deposition layer thickness to obtain the current
        void* thickness_old_raw_ptr;
        errcode = alfasim.get_plugin_variable(
            ctx,
            &thickness_old_raw_ptr,
            "thickness",
            0,
            TimestepScope::PREVIOUS,
            &size);
        if (errcode != 0) {
            return errcode;
        }
        auto* thickness_old =
            (double*) (thickness_old_raw_ptr);

        // Calculate the variation of the deposition layer in one time step
        double* d_deposit_layer_dt = 0.0001; // [m/s]

        // Sum this variation with the thickness of the older time step
        for (int i = 0; i < n_control_volumes; ++i) {
            (double*) thickness[i] =
                thickness_old[i] + d_deposit_layer_dt * dt; // [m]
           (double*) density[i] = wax_density; // [kg/m3]
           (double*) heat_capacity[i] = wax_heat_capacity; //  [J/(kg.K)]
           (double*) thermal_conductivity[i] = wax_thermal_conductivity; // [W/(m.K)]
        }
    }

    return OK;
}

In the example above is shown how to manage the thickness, density, heat_capacity and thermal_conductivity arrays for each control volume. Note that the thickness should be always the total value for that time step, so the first time step should be handle in a separately way, since there is no previously information.

Unit Cell Model (UCM) Friction Factor

When the Unit Cell Model is used in ALFAsim simulation any plugin can implement your own friction factor correlation. For that, two hooks MUST be implemented, one for stratified flow and one for annular flow. Both of them must be implemented because the ALFAsim’s Solver will call them depending on which flow pattern the fluid flow is in the control volume.

Note

It is important to know that the main input variables needed to compute the friction factor is available in the API function get_ucm_friction_factor_input_variable(). Note that, the variables listed in the documentation of the cited function are related to one control volume, in which the Unit Cell Model is applied.

calculate_ucm_friction_factor_stratified(ctx, ff_wG, ff_wL, ff_i)

c++ signature : HOOK_CALCULATE_UCM_FRICTION_FACTOR_STRATIFIED(void* ctx, double* ff_wG, double* ff_wL, double* ff_i)

Internal unit cell model hook to calculate the wall and interfacial friction factors for stratified fluid flow pattern. The unit cell model represents a two phase flow with Gas and Liquid Phases. The output variables ff_wG, ff_wL and ff_i are the Gas-Wall friction factor, Liquid-Wall friction factor and interfacial Gas-Liquid friction factor, respectively.

This hook allows the developer to implement your own correlation for friction factor in a stratified flow.

Parameters
  • ctx – ALFAsim’s plugins context

  • ff_wG – Gas-Wall Friction Factor

  • ff_wL – Liquid-Wall Friction Factor

  • ff_i – Interfacial Gas-Liquid Friction Factor

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int HOOK_CALCULATE_UCM_FRICTION_FACTOR_STRATIFIED(
    void* ctx, double* ff_wG, double* ff_wL, double* ff_i)
{
    int errcode = -1;
    int G = TwoPhaseSystem::GAS
    int L = TwoPhaseSystem::LIQUID

    // Getting friction factor input data from context
    double alpha[2];
    errcode = alfasim_sdk_api.get_ucm_friction_factor_input_variable(
        ctx, &alpha[G], "alpha", TwoPhaseSystem::GAS);
    if (errcode != OK){ return errcode; }
    errcode = alfasim_plugins_api.get_ucm_friction_factor_input_variable(
        ctx, &alpha[L], "alpha", TwoPhaseSystem::LIQUID);
    if (errcode != OK){ return errcode; }
    // And so on to each friction factor input variable
    // U(velocities), rho(densities), mu(viscosities) and D(pipe diameter)

     // Getting the fluid geometrical properties
    double S_w[2];
    double S_i;
    double H[2];
    errcode = alfasim_sdk_api.get_ucm_fluid_geometrical_properties(
        ctx, S_w, &S_i, H, alpha[G], D);
    if (errcode != OK){ return errcode; }

    // Compute the friction factors using your own correlation.
    // Also, using the variables: alpha, U, rho, mu, D, S_w, S_i and H

    *ff_wG = gas_wall_ff;
    *ff_wL = liq_wall_ff;
    *ff_i = gas_liq_ff;

    return OK;
}
calculate_ucm_friction_factor_annular(ctx, ff_wG, ff_wL, ff_i)

c++ signature : HOOK_CALCULATE_UCM_FRICTION_FACTOR_ANNULAR(void* ctx, double* ff_wG, double* ff_wL, double* ff_i)

Internal unit cell model hook to calculate the wall and interfacial friction factors for annular fluid flow pattern. The unit cell model represents a two phase flow with Gas and Liquid Phases. The output variables ff_wG, ff_wL and ff_i are the Gas-Wall friction factor, Liquid-Wall friction factor and interfacial Gas-Liquid friction factor, respectively.

This hook allows the developer to implement your own correlation for friction factor in a annular flow.

Parameters
  • ctx – ALFAsim’s plugins context

  • ff_wG – Gas-Wall Friction Factor

  • ff_wL – Liquid-Wall Friction Factor

  • ff_i – Interfacial Gas-Liquid Friction Factor

Returns

Return OK if successful or anything different if failed

Example of usage:

The same example presented in HOOK_CALCULATE_UCM_FRICTION_FACTOR_STRATIFIED can be used, just change the hook name to HOOK_CALCULATE_UCM_FRICTION_FACTOR_ANNULAR.

Note

Another important API function for UCM is get_ucm_fluid_geometrical_properties(). This function computes the geometrical properties properly in each previous presented hooks depending on the flow pattern.

User Defined Tracers

The hooks described in this section must be implemented when at least one user defined tracer is added via alfasim_get_user_defined_tracers_from_plugin() hook.

Warning

This is advanced customization. We strongly encourage the plugin developer to read the Tracers chapter of ALFAsim’s Technical Report available on the Help menu at ALFAsim application.
manual

These hooks can modify the tracer transport equation from the initialization to configuration of boundary conditions. The plugin developer has complete freedom to change the equations, however it is important to be aware that it can be made manipulating the transport equation terms inside the hooks. For that, it is important to read the Tracers Chapter at ALFAsim’s Technical Manual.

initialize_mass_fraction_of_tracer(ctx, phi_initial, tracer_index)

c++ signature : HOOK_INITIALIZE_MASS_FRACTION_OF_TRACER(void* ctx, void* phi_initial, int tracer_index)

Internal tracer model Hook to initialize the mass fraction of tracer, given by tracer_id, in the entire network. The output variable phi_initial is the initial mass fraction of the given tracer in respect to the mass of the mixture.

Parameters
  • ctx – ALFAsim’s plugins context

  • phi_initial – Initial mass fraction of tracer in respect to the mass of the mixture

  • tracer_index – Tracer ID

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
HOOK_INITIALIZE_MASS_FRACTION_OF_TRACER(
    void* ctx, void* phi_initial, int tracer_index)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    if (tracer_index != data.my_user_defined_tracer_id) {
        return OK;
    } else {
        // Set a initial value to the tracer mass fraction
        // phi_initial has size equal to 1
        *static_cast<double*>(phi_initial) = 0.0;
    }
    return OK;
}
calculate_mass_fraction_of_tracer_in_phase(ctx, phi, phi_phase, tracer_index, phase_index, n_control_volumes)

c++ signature : HOOK_CALCULATE_MASS_FRACTION_OF_TRACER_IN_PHASE(void* ctx, void* phi, void* phi_phase, int tracer_index, int phase_index, int n_control_volumes)

Internal tracer model Hook to calculate the mass fraction of tracer, given by tracer_index, in phase, given by phase_index. The input variable phi is the mass fraction of the given tracer in respect to the mass of the mixture. The output variable phi_phase is the mass fraction of the given tracer in respect to the mass of the given phase. Both phi and phi_phase have size equal to n_control_volumes.

Parameters
  • ctx – ALFAsim’s plugins context

  • phi – Array of mass fraction of tracer in respect to the mass of the mixture

  • phi_phase – Array of mass fraction of tracer in respect to the mass of the phase given by phase_index

  • tracer_index – Tracer ID

  • phase_index – Phase ID

  • n_control_volumes – Number of control volumes

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
HOOK_CALCULATE_MASS_FRACTION_OF_TRACER_IN_PHASE(
    void* ctx, void* phi, void* phi_phase,
    int tracer_index, int phase_index, int n_control_volumes)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    // Casting to double pointer
    double* phi_ptr = static_cast<double*>(phi);
    double* phi_phase_ptr = static_cast<double*>(phi_phase);
    // Check if the tracer_index was added by this plugin
    if (tracer_index != data.my_user_defined_tracer_id){
        return OK
    }
    // Let suppose that this tracer is only in the gas phase
    if(phase_index != data.gas_id) {
         for (int i = 0; i < n_control_volumes; ++i) {
            phi_phase_ptr[i] = 0.0;
         }
    } else {
        // Calculate and set the Phi_phase value
        for (int i = 0; i < n_control_volumes; ++i) {
            phi_phase_ptr[i] =
                data.calculate_mass_fraction_of_tracer_in_gas(
                    phi_ptr[i],
                    // List of params that can be
                    // retrieved by get_simulation_array()
                    );
        }
    }
    return OK;
}

Warning

The plugin developer must NOT change phi variable, only the output variable phi_phase.

calculate_mass_fraction_of_tracer_in_field(ctx, phi_phase, phi_field, tracer_index, field_index, phase_index_of_field, n_control_volumes)

c++ signature : HOOK_CALCULATE_MASS_FRACTION_OF_TRACER_IN_FIELD(void* ctx, void* phi_phase, void* phi_field, int tracer_index, int field_index, int phase_index_of_field, int n_control_volumes)

Internal tracer model Hook to calculate the mass fraction of tracer, given by tracer_index, in field, given by field_index. The input variable phi_phase is the mass fraction of the given tracer in respect to the mass of the given phase, in which the ID is phase_index_of_field. The output variable phi_field is the mass fraction of the given tracer in respect to the mass of the given field. Both phi_phase and phi_field have size equal to n_control_volumes.

Parameters
  • ctx – ALFAsim’s plugins context

  • phi_phase – Array of mass fraction of tracer in respect to the mass of the phase given by phase_index_of_field

  • phi_field – Array of mass fraction of tracer in respect to the mass of the field given by field_index

  • tracer_index – Tracer ID

  • field_index – Field ID

  • phase_index_of_field – Phase ID of field

  • n_control_volumes – Number of control volumes

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
HOOK_CALCULATE_MASS_FRACTION_OF_TRACER_IN_FIELD(
    void* ctx, void* phi_phase, void* phi_field,
    int tracer_index, int field_index,
    int phase_index_of_field, int n_control_volumes)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    // Casting to double pointer
    double* phi_phase_ptr = static_cast<double*>(phi_phase);
    double* phi_field_ptr = static_cast<double*>(phi_field);
    // Check if the tracer_index was added by this plugin
    if (tracer_index != data.my_user_defined_tracer_id){
        return OK
    }
    // Let suppose that this tracer is only in the gas phase
    if(phase_index_of_field != data.gas_phase_id) {
         for (int i = 0; i < n_control_volumes; ++i) {
            phi_field_ptr[i] = 0.0;
         }
    } else {
        // Calculate and set the Phi_field value
        for (int i = 0; i < n_control_volumes; ++i) {
            phi_field_ptr[i] =
                data.mass_fraction_of_tracer_in_gas_fields(
                    phi_phase_ptr[i],
                    // List of params that can be
                    // retrieved by get_simulation_array()
                    );
        }
    }
    return OK;
}

Warning

The plugin developer must NOT change phi_phase variable, only the output variable phi_field.

set_prescribed_boundary_condition_of_mass_fraction_of_tracer(ctx, phi_presc, tracer_index)

c++ signature : HOOK_SET_PRESCRIBED_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER(void* ctx, void* phi_presc, int tracer_index)

Internal tracer model hook to set the initial prescribed boundary condition of mass fraction of tracer, given by tracer_index`. The output variable ``phi_presc is the prescribed mass fraction of the given tracer in respect to the mass of the mixture. Note that all boundary nodes will be populated with phi_presc value set by this hook.

Please note that this hook sets the first mass fraction related boundary conditions value to the user defined tracer. However the hook HOOK_UPDATE_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER allows the plugin developer to update this value.

Parameters
  • ctx – ALFAsim’s plugins context

  • phi_presc – Prescribed mass fraction of tracer

  • tracer_index – Tracer ID

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
HOOK_SET_PRESCRIBED_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER(
    void* ctx, void* phi_presc, int tracer_index)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    if (tracer_index != data.my_user_defined_tracer_id) {
        return OK;
    } else {
        // Set a initial boundary condition
        // to the tracer mass fraction.
        // phi_presc has size equal to 1.
        *static_cast<double*>(phi_presc) = 0.0;
    }
    return OK;
}
update_boundary_condition_of_mass_fraction_of_tracer(ctx, phi_presc, tracer_index, vol_frac_bound, n_fields)

c++ signature : HOOK_UPDATE_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER(void* ctx, void* phi_presc, void* phi_field, int tracer_index, void* vol_frac_bound, int n_fields)

Internal tracer model hook to update the prescribed mass fraction of tracer, given by tracer_id. The output variable phi_presc is the prescribed mass fraction of the given tracer in respect to the mass of the mixture. The vol_frac_bound is the volume fraction of fields at the boundary in which the phi_presc is being calculated.

This hook allows the developer to update the boundary conditions of mass fraction that may depend on ALFAsim’s internal variables that may change during the simulation. So, this update will be performed to each time step.

Parameters
  • ctx – ALFAsim’s plugins context

  • phi_presc – Prescribed mass fraction of tracer

  • tracer_index – Tracer ID

  • vol_frac_bound – Volume fraction of fields in the boundary

  • n_fields – Number of fields

Returns

Return OK if successful or anything different if failed

Example of usage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
HOOK_UPDATE_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER(
    void* ctx, void* phi_presc, int tracer_index)
{
    // getting plugin internal data
    int errcode = -1;
    int thread_id = -1;
    errcode = alfasim_sdk_api.get_thread_id(ctx, &thread_id);
    if (errcode != OK) {
        return errcode;
    }
    MyStruct* data = nullptr;
    errcode = alfasim_sdk_api.get_plugin_data(
            ctx, (void**) &data, plugin_id, thread_id);
    // Casting to double pointer
    double* phi_presc_ptr = static_cast<double*>(phi_presc);
    double* vol_frac_bound_ptr = static_cast<double*>(vol_frac_bound);
    // Let suppose that this tracer is only in the gas field
    if (tracer_index != data.my_user_defined_tracer_id) {
        return OK;
    } else {
        // Update the boundary condition
        // to the tracer mass fraction.
        phi_presc_ptr =
                data.calc_bc_mass_fraction_of_tracer_in_gas_field(
                    vol_frac_bound_ptr[data.continuous_gas_field_id],
                    // List of params that can be
                    // retrieved by get_simulation_array()
                    );
    }
    return OK;
}

Warning

The plugin developer must NOT change vol_frac_bound variable, only the output variable phi_presc.

Dig deeper into specific topics:

Simulator WorkFlow

Here are shown some graphs of the ALFAsim simulator workflow. In those graphs, it is possible to identify when the Solver Hooks are called during the simulation. Some of them, like Hydrodynamic Solver and Tracer Solver, have their graphs expanded to make it possible to see more internal hooks.

Main Overview

digraph { nodesep = 0.6; newrank=true node [fillcolor="#FAAC2C" style="rounded, filled" color="#FAAC2C" fontcolor="#ffffff"] edge [color="#8699A3" fontcolor="#2c3e50"] init [label="Initialize Simulation"] end [label="End of Simulation"] node [shape=point, width=0] invisible_point hook_initialize_point [peripheries="2"] hook_finalize_point [peripheries="2"] time [fixedsize=true, label="Time Step", width="1.0", shape="circle"]; decision [label="Final \n Time?", shape="diamond", fixedsize=true, width=2.0, height=1.0, labelcolor="#8699A3", style="filled"] node[shape="rectangular", target="_top"] config [label="Solver Configuration"] hyd_solver [label="Hydrodynamic Solver", URL="../07_workflow.html#hydrodynamic-solver"] tracer_solver [label="Tracer Solver" URL="../07_workflow.html#tracer-solver"] output [label="Output Variables"] node[peripheries="0" shape="cds", color="#DA5961", fontcolor="#DA5961", style=""] hook_initialize [ label="HOOK_INITIALIZE", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.initialize"] hook_finalize [label="HOOK_FINALIZE", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.finalize"] {rank = same; hook_initialize_point; hook_initialize} {rank = same; hook_finalize_point; hook_finalize; } {rank=same; time;tracer_solver} {rank=same; invisible_point;hyd_solver} init -> config; config -> hook_initialize_point [arrowhead= none]; hook_initialize_point -> invisible_point [arrowhead=none]; hook_initialize_point -> hook_initialize [style=dotted, color="#DA5961"]; subgraph cluster_a{ label="Transient Solver" style="dashed, rounded" shape="reactangular" color="#8699A3" fontcolor="#2c3e50" labeljust="l" invisible_point -> time; time:ne -> hyd_solver:w [style=dashed]; hyd_solver -> tracer_solver [weight=1000]; tracer_solver -> output [weight=1000]; output:nw -> time:se [style=dashed]; time:s -> decision:n [weight=10]; decision:w -> time:sw [label="No"]; } decision -> hook_finalize_point [arrowhead= none, label="Yes"]; hook_finalize_point -> hook_finalize [style=dotted, color="#DA5961"]; hook_finalize_point -> end; }

Hydrodynamic Solver

digraph { nodesep = 0.6; newrank=true; node [fillcolor="#FAAC2C", style="rounded, filled", color="#FAAC2C", fontcolor="#ffffff", target="_top"] edge [color="#8699A3", fontcolor="#2c3e50"] hydrodynamic_1 [label="Primary Variables \n (Solver Unknowns)"] hydrodynamic_2 [label="Calculate \n State Variables" URL="../07_workflow.html#state-variable-calculator"] hydrodynamic_3 [label="Calculate \n Secondary Variables"] hydrodynamic_4 [label="Calculate \n Source Terms"] invisible_init [shape=point, style=invis] invisible_end [shape=point, style=invis] hook_update_variables_point [shape = point, width = 0, peripheries="2"] hook_calculate_source_terms_point [shape = point, width = 0, peripheries="2" ] // Align Hooks node[peripheries="0", shape="cds", color="#DA5961", fontcolor="#DA5961", style=""] hook_update_variables [label="HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.update_plugins_secondary_variables"] hook_calculate_mass_source_terms [label="HOOK_CALCULATE_MASS_SOURCE_TERM", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.calculate_mass_source_term"] hook_calculate_momentum_source_terms [label="HOOK_CALCULATE_MOMENTUM_SOURCE_TERM", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.calculate_momentum_source_term"] hook_calculate_energy_source_terms [label="HOOK_CALCULATE_ENERGY_SOURCE_TERM", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.calculate_energy_source_term"] {rank = same; hook_update_variables_point; hook_update_variables } {rank = same; hook_calculate_source_terms_point; hook_calculate_momentum_source_terms; } invisible_init -> hydrodynamic_1 hook_calculate_source_terms_point -> invisible_end ; // Align all hooks hook_calculate_mass_source_terms -> hook_calculate_momentum_source_terms -> hook_calculate_energy_source_terms [constraint=true, style=invis] subgraph cluster1{ labeljust="l" style="rounded, dashed" color="#8699A3" hydrodynamic_1 -> hydrodynamic_2 -> hydrodynamic_3 hydrodynamic_3 -> hook_update_variables_point [arrowhead=none, ltail=cluster1] hook_update_variables_point -> hydrodynamic_4 hydrodynamic_4 -> hook_calculate_source_terms_point [arrowhead=none] } hook_update_variables_point -> hook_update_variables [constraint=false, style=dotted, color="#DA5961"] hook_calculate_source_terms_point -> hook_calculate_mass_source_terms:w [constraint=false, style=dotted, color="#DA5961"] hook_calculate_source_terms_point -> hook_calculate_momentum_source_terms [constraint=false, style=dotted, color="#DA5961"] hook_calculate_source_terms_point -> hook_calculate_energy_source_terms:w [constraint=false, style=dotted, color="#DA5961"] // Align Notes subgraph cluster2{ labeljust="l" style="rounded, dashed" fontcolor="#2c3e50" color="#8699A3" node[shape=box, color="#FAAC2C",fillcolor="#FFFFFF", fontcolor="#FAAC2C", peripheries="1" shape="rectangular"] note_1 [label="α, P, U, T"] note_2 [label="ρ, μ, Cₚ, ... = ƒ(P,T)"] note_3 [label="Mass Flow Rate, Flow Pattern ..."] } {rank=same; hydrodynamic_1; note_1} {rank=same; hydrodynamic_2; note_2} {rank=same; hydrodynamic_3; note_3} note_1->note_2->note_3[ style = invis ] edge[arrowhead=none, style=dashed, constraint=false,] hydrodynamic_1 -> note_1 hydrodynamic_2 -> note_2 hydrodynamic_3 -> note_3 }

State Variable Calculator

digraph { newrank=true nodesep=0.7 node [fillcolor="#FAAC2C" style="rounded, filled" color="#FAAC2C" fontcolor="#ffffff" shape="rectangular"] edge [ color="#8699A3" fontcolor="#2c3e50" ] node_1 [label="Calculate State Variables \n for ALFAsim Phases"] node_2 [label="Setup"] node_3 [label="Calculate State Variables"] node_4 [label="Calculate Phase Pair \n State Variables \n (Surface Tension)"] node_5 [label="Finalize"] loop_1 [fixedsize=true, label="Phases Set \n By Plugins", width="1.2", shape="circle"] node [shape=point style=invis width=0] invisible_init invisible_end invisible_1 invisible_2 invisible_3 node[peripheries="0" shape="cds", color="#DA5961", fontcolor="#DA5961" , style="" target="_top" fontsize=10] hook_initialize_state_variables_calculator [label=" HOOK_INITIALIZE_STATE_VARIABLES_CALCULATOR" URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.initialize_state_variables_calculator"] hook_calculate_state_variable [label=" HOOK_CALCULATE_STATE_VARIABLE", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.calculate_state_variable"] hook_calculate_phase_pair_state_variable [label=" HOOK_CALCULATE_PHASE_PAIR_STATE_VARIABLE", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.calculate_phase_pair_state_variable"] hook_finalize_state_variables_calculator [label=" HOOK_FINALIZE_STATE_VARIABLES_CALCULATOR" URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.finalize_state_variables_calculator"] {rank = same node_2 hook_initialize_state_variables_calculator } {rank = same node_3 hook_calculate_state_variable } {rank = same node_4 hook_calculate_phase_pair_state_variable} {rank = same node_5 hook_finalize_state_variables_calculator } {rank=same loop_1 node_3} invisible_init -> node_1 subgraph cluster1{ label="" labeljust="l" style="rounded, dashed" color="#8699A3" node_2->node_3->node_4->node_5 [weight=9999] loop_1:ne -> node_2:w [style=dashed] node_5:w -> loop_1:se [style=dashed] invisible_1 -> loop_1 [weight=9999] edge[arrowhead=none style=normal] node_1 -> invisible_1 [weight=9999] loop_1 -> invisible_2 invisible_2 -> invisible_3 } invisible_3 -> invisible_end edge[constraint=false, style=dotted, color="#DA5961"] node_2 -> hook_initialize_state_variables_calculator node_3 -> hook_calculate_state_variable node_4 -> hook_calculate_phase_pair_state_variable node_5 -> hook_finalize_state_variables_calculator }

Tracer Solver

digraph { nodesep = 0.7 newrank=true node [fillcolor="#FAAC2C" style="rounded, filled" color="#FAAC2C" fontcolor="#ffffff" shape="rectangular"] edge [ color="#8699A3" fontcolor="#2c3e50" ] tracer_1 [label="Primary Variables \n (Solver Unknowns, ϕ) "] tracer_2 [label="Calculate \n Secondary Variables"] tracer_3 [label="Calculate \n Source Terms"] invisible_init [shape=point, style=invis] invisible_end [shape=point, style=invis] node[shape = point, width = 0, peripheries="2" ] hook_initialize_user_defined_tracer_point hook_set_bc_user_defined_tracer_point hook_update_variables_point hook_calculate_source_terms_point node[peripheries="0" shape="cds", color="#DA5961", fontcolor="#DA5961" , style="" target="_top" fontsize=10] hook_initialize_user_defined_tracer [label=" HOOK_INITIALIZE_MASS_FRACTION_OF_TRACER" URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.initialize_mass_fraction_of_tracer"] hook_set_bc_user_defined_tracer [label=" HOOK_SET_PRESCRIBED_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.set_prescribed_boundary_condition_of_mass_fraction_of_tracer"] hook_update_variables [label=" HOOK_UPDATE_PLUGINS_SECONDARY_VARIABLES_ON_TRACER_SOLVER", URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.update_plugins_secondary_variables_on_tracer_solver"] hook_calculate_tracer_source_terms [label=" HOOK_CALCULATE_TRACER_SOURCE_TERM" URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.calculate_tracer_source_term"] hook_update_bc_user_defined_tracer [label=" HOOK_UPDATE_BOUNDARY_CONDITION_OF_MASS_FRACTION_OF_TRACER" URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.update_boundary_condition_of_mass_fraction_of_tracer"] hook_calculate_mass_fraction_of_tracer_in_field [label=" HOOK_CALCULATE_MASS_FRACTION_OF_TRACER_IN_FIELD \n HOOK_CALCULATE_MASS_FRACTION_OF_TRACER_IN_PHASE" URL="../06_solver_hooks.html#_alfasim_sdk.hook_specs.calculate_mass_fraction_of_tracer_in_phase" ] {rank = same hook_update_variables_point hook_update_variables} {rank = same hook_calculate_source_terms_point hook_calculate_tracer_source_terms } {rank = same hook_initialize_user_defined_tracer_point hook_initialize_user_defined_tracer } {rank = same hook_set_bc_user_defined_tracer_point hook_set_bc_user_defined_tracer } {rank = same tracer_1 hook_update_bc_user_defined_tracer } {rank = same tracer_2 hook_calculate_mass_fraction_of_tracer_in_field} invisible_init -> hook_initialize_user_defined_tracer_point [arrowhead=none] hook_calculate_source_terms_point -> invisible_end subgraph cluster1{ labeljust="l" style="rounded, dashed" color="#8699A3" hook_initialize_user_defined_tracer_point -> hook_set_bc_user_defined_tracer_point [arrowhead=none] hook_set_bc_user_defined_tracer_point-> tracer_1 tracer_1 -> tracer_2 tracer_2 -> hook_update_variables_point [arrowhead=none] hook_update_variables_point -> tracer_3 tracer_3 -> hook_calculate_source_terms_point [arrowhead=none] } edge[constraint=false, style=dotted, color="#DA5961"] subgraph cluster2{ label="Hooks for User Defined Tracers" labeljust="l" fontcolor="#2c3e50" style="rounded, dashed" color="#8699A3" hook_initialize_user_defined_tracer_point -> hook_initialize_user_defined_tracer hook_set_bc_user_defined_tracer_point -> hook_set_bc_user_defined_tracer tracer_1 -> hook_update_bc_user_defined_tracer tracer_2 -> hook_calculate_mass_fraction_of_tracer_in_field } hook_calculate_source_terms_point -> hook_calculate_tracer_source_terms hook_update_variables_point -> hook_update_variables }

Full API Reference

This page contains the full reference to ALFAsim-SDK API.

C/C++ API

Here is listed the completed API available to implement the Solver Hooks.

Enums
enum error_code

It holds the possible returning error code from ALFAsim-SDK-API functions.

Values:

enumerator REFERENCE_NOT_SET

Some reference from input data wasn’t set.

enumerator UNKNOWN_REFERENCE_TYPE

Reference type is unknown.

enumerator OUT_OF_BOUNDS

Index out of array bounds.

enumerator UNKNOWN_CONTEXT

The context is unknown.

enumerator NOT_AVAILABLE_DATA

Data from ALFAsim is not available.

enumerator BUFFER_SIZE_INSUFFICIENT

Buffer size is insufficient.

enumerator UNDEFINED_DATA

Plugin internal data is undefined.

enumerator NOT_IMPLEMENTED

A feature is not implemented in an API function.

enumerator OK

Everything was fine.

enum GridScope

It holds the variable scope in the grid to retrieve a simulation array.

Values:

enumerator CENTER

Variable located in the control volume center

enumerator FACE

Variable located in the control volume face

enum MultiFieldDescriptionScope

It holds the variable scope in the Multifield description (phases/fields/layers) to retrieve a simulation array.

Values:

enumerator MIXTURE

Variable associated to the mixture

enumerator GLOBAL

Global variable

enumerator FIELD

Variable associated to the field

enumerator LAYER

Variable associated to the layer

enumerator PHASE

Variable associated to the phase

enum TimestepScope

It holds the variable scope in the time level to retrieve a simulation array.

Values:

enumerator CURRENT

Variable in the current time step

enumerator PREVIOUS

Variable in the previous (old) time step

enum StateVariable

It holds the possible state variables that can be computed to a phase inside the plugin. See solver hooks calculate_state_variable and calculate_phase_pair_state_variable

Values:

enumerator RHO

Density

enumerator MU

Viscosity

enumerator CP

Heat Capacity

enumerator DRHO_DP

Partial derivative of density in relation to pressure

enumerator DRHO_DT

Partial derivative of density in relation to temperature

enumerator H

Enthalpy

enumerator K

Thermal Conductivity

enumerator SIGMA

Interfacial tension

enum WallLayerProperty

It holds the possible wall layer property that can be obtained from ALFAsim’s solver. This Enum is used by The #set_wall_layer_property API function.

Values:

enumerator THICKNESS

Wall layer tickness

enumerator DENSITY

Wall layer material density

enumerator THERMAL_CONDUCTIVITY

Wall layer material thermal conductivity

enumerator HEAT_CAPACITY

Wall layer material specifc heat capacity

enumerator INNER_EMISSIVITY

Wall layer material inner emissivity

enumerator OUTER_EMISSIVITY

Wall layer material outer emissivity

enumerator EXPANSION

Wall layer material thermal expansion coefficient

enumerator VISCOSITY

Wall layer material viscosity (if it is a deposit layer)

enum sdk_load_error_code

It holds the possible returning error code when trying to open ALFAsim-SDK API.

Values:

enumerator SDK_DLL_PATH_TOO_LONG

Path to SDK dll too long (Windows limitation).

enumerator SDK_ALREADY_OPEN_ERROR

SDK dll already Opened.

enumerator SDK_OK

Everything was fine.

Structs
struct VariableScope

It holds all variable scopes (grid, multifield and timestep)

Public Members

enum GridScope grid_scope

Which grid scope of the variable

enum MultiFieldDescriptionScope mfd_scope

Which multifield scope of the variable

enum TimestepScope ts_scope

Which timestep scope of the variable

Functions
ALFAsim-SDK API Loading

Note

The ALFAsim-SDK API must be loaded with alfasim_sdk_open() inside HOOK_INITIALIZE of any plugin, otherwise the plugin will not be able to use any function available in the API. In addition, to avoid memory leak it is important to unload the ALFAsim-SDK API in the last called hook, HOOK_FINALIZE, using the alfasim_sdk_close() function.

int alfasim_sdk_open(ALFAsimSDK_API *api)
void alfasim_sdk_close(ALFAsimSDK_API *api)
Plugin Input Data (From user interface)

Note

All API functions on this section has the parameter var_name. This parameter must be filled following the rules exposed in Variable Name Parsing section.

int get_plugin_input_data_boolean(void *ctx, bool *out, const char *plugin_id, const char *var_name)

Gets the data provided from the user on a Boolean input field. For more detail about the Boolean input field check alfasim_sdk.types.Boolean

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Retrieved variable value.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

int get_plugin_input_data_enum(void *ctx, int *out, const char *plugin_id, const char *var_name)

Gets the data provided from the user on a Enum input field. For more detail about the Enum input field check alfasim_sdk.types.Enum.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Retrieved variable value.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

int get_plugin_input_data_quantity(void *ctx, double *out, const char *plugin_id, const char *var_name)

Gets the data provided from the user on a Quantity input field. For more detail about the quantity input field check alfasim_sdk.types.Quantity.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Retrieved variable value.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

int get_plugin_input_data_string(void *ctx, char *out, const char *plugin_id, const char *var_name, int size)

Gets the data provided from the user on a String input field. For more detail about the string input field check alfasim_sdk.types.String.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Retrieved variable value.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

  • [in] size: Size of output string (param out).

int get_plugin_input_data_string_size(void *ctx, int *out, const char *plugin_id, const char *var_name)

Gets the size of the data provided from the user on a String input field.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: String size of a variable in which its name is informed by var_name.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

int get_plugin_input_data_file_content(void *ctx, char *out, const char *plugin_id, const char *var_name, int size)

Gets the data provided from the user on a FileContent input field. For more detail about the FileContent input field check alfasim_sdk.types.FileContent

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Retrieved variable value.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

  • [in] size: Size of output string (param out).

int get_plugin_input_data_file_content_size(void *ctx, int *out, const char *plugin_id, const char *var_name)

Gets the size of the data provided from the user on a FileContent input field.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: File content size of a variable in which its name is informed by var_name.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

int get_plugin_input_data_table_quantity(void *ctx, double **out, int *size, const char *column_id, const char *plugin_id, const char *var_name)

Gets the values from a column of an input table. column_id is the string defined in the plugin’s configuration file. If the var_name or the column_id are invalid, UNDEFINED_DATA is returned.

Example of usage:

int size = -1;
double* values = NULL;
int errcode = get_plugin_input_data_table_quantity(
    ctx,
    &values,
    &size,
    "temperature",
    get_plugin_id(),
    "Model.some_table"
);
for (int i = 0; i < size; ++i) {
    some_plugin_data = 1.1 * values[i];
}

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Variable values array.

  • [out] size: Size of variable values array.

  • [in] column_id: Table column ID which values are retrieved.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrieved.

int get_plugin_input_data_reference(void *ctx, void **out, const char *plugin_id, const char *var_name)

Gets an ALFAsim input data internal Reference. Note that a Reference is a specific concept of ALFAsim-SDK and plugins - It is a way to retrieve data from an input outside of the current model. See the ALFAsim’s SDK python configuration file for more information.

Example of usage:

void* tracer_ref = nullptr;
errcode = get_plugin_input_data_reference(
    ctx, &tracer_ref, get_plugin_id(), "Model.tracer_reference");

int tracer_id = -1;
errcode = get_tracer_id(ctx, &tracer_id, tracer_ref);

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: ALFAsim data reference.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable to be retrived.

int get_plugin_input_data_multiplereference_selected_size(void *ctx, int *indexes_size, const char *plugin_id, const char *var_name)

Get the number of selected references in a multiple-reference selection. User should be able to iterate over the selections to get information.

Example of usage:

int errcode = -1;
int indexes_size = -1;
errcode = get_plugin_input_data_multiplereference_selected_size(
    ctx, &indexes_size, get_plugin_id(), "Model.internal_multiple_reference");

for (int i = 0; i < indexes_size; ++i) {
    auto value = -1.0;
    auto reference_str = std::string(
        "Model.internal_multiple_reference[" + std::to_string(i) + "]->quantity");

    errcode = get_plugin_input_data_quantity(
        ctx, &value, get_plugin_id(), reference_str.c_str());
    }
}

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] indexes_size: Number of selected references in a multiple reference input data.

  • [in] plugin_id: Plugin ID.

  • [in] var_name: Name of the variable.

Plugin Internal Data
int set_plugin_data(void *ctx, const char *plugin_id, void *data, int thread_id)

Set the data provided from the plugin developer.

When a plugin has internal data and it has to be accessed by all C/C++ Hooks during the simulation this function allows the plugin to ask the ALFAsim’s solver to hold its internal data.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [in] plugin_id: Plugin ID.

  • [in] data: Plugin internal data.

  • [in] thread_id: Thread ID, see get_thread_id for more information.

int get_plugin_data(void *ctx, void **out, const char *plugin_id, int thread_id)

Gets the data provided from the plugin developer.

Once the plugin set an internal data, it can be accessed from any C/C++ Hook during the simulation using this function.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Plugin internal data.

  • [in] plugin_id: Plugin ID.

  • [in] thread_id: Thread ID, see get_thread_id for more information.

int get_number_of_threads(void *ctx, int *n_threads)

Gives the number of running threads on the solver

ALFAsim’s Solver runs in multiple threads. To avoid data access concurrency problems the plugin developer must set one internal data to each running thread during the initialization. Then, with number of threads, the developer can do it properly.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] n_threads: Number of threads.

int get_thread_id(void *ctx, int *thread_id)

Gives the current running thread id (in the solver process)

Once the plugin sets one internal data to each running thread, to access this data properly it has to know which thread is trying to access this data. For that, this function retrieves this information from solver.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] thread_id: Thread ID.

ALFAsim’s Solver Data
int get_plugin_variable(void *ctx, void **out, const char *variable_name, int line_index, enum TimestepScope ts_scope, int *size)

Gets the contents of a plugin-registered secondary variable (Given by name).

It is allowed to the plugins to add new secondary variables via python config file. ALFAsim’s solver registers/holds these variables and make them available in the solver hooks by this function.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Plugin-registered secondary variable values array.

  • [in] variable_name: Name of the secondary variable.

  • [in] line_index: It can represent Layer/Field/Phase ID, since the secondary variables can be associated to different MultiFieldDescriptionScope.

  • [in] ts_scope: A TimestepScope value.

  • [out] size: Size of out array of values. It can be the number of volumes or number of faces depending in which GridScope the secondary variable was registered.

int get_field_id(void *ctx, int *out, const char *name)

Gets the field ID of the given name. Althought this depends on the hydrodynamic model being solved, common values include “gas”, “oil”, “droplet” and “bubble”. This functions supports retrieve ID of field added by plugin.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Field ID.

  • [in] name: Name of the field to retrieve the ID.

int get_primary_field_id_of_phase(void *ctx, int *out, const char *name)

Gets the primary field ID of the phase with given name. For example, the “oil” phase has primary field “oil”. Different phases may have different primary fields. Use this function when you need a variable from a field, but you aren’t sure about the field name, but you know the phase name.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Field ID.

  • [in] name: Name of the phase to retrieve the primary field ID.

int get_phase_id(void *ctx, int *out, const char *name)

Gets the phase ID of the given name. Althought this depends on the hydrodynamic model being solved, common values include “gas”, “oil” and “water”. This functions supports retrieve ID of phase added by plugin.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Phase ID.

  • [in] name: Name of the phase to retrieve the ID.

int get_layer_id(void *ctx, int *out, const char *name)

Gets the layer ID of the given name. Althought this depends on the hydrodynamic model being solved, common values include “gas”, “oil” and “water”. This functions supports retrieve ID of layer added by plugin.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Layer ID.

  • [in] name: Name of the layer to retrieve the ID.

int get_state_variable_array(void *ctx, double **out, enum StateVariable state_var, int field_index, int *size)

Gets the current contents of a given state variable (For an array data pointer). A state variable is any variable calculated from pressure and temperature, as any thermodynamic variable.

Example of usage:

errcode = get_state_variable_array(
    ctx, enthalpy, StateVariable::H, FIELD_GAS, size);

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: State Variable values array.

  • [in] state_var: A StateVariable value. It indicates which variable to be retrieved.

  • [in] field_index: Index of the field in which the state variable is retrieved.

  • [out] size: Size of the out array of values.

Warning

Changing the contents retrieved by this function (out array) has UNDEFINED BEHAVIOR. The plugin must NEVER change the contents returned by this function.

int get_simulation_array(void *ctx, double **out, const char *variable_name, struct VariableScope var_scope, int line_index, int *size)

Gets the current contents of a given secondary variable (For an array data pointer). A secondary variable is any variable calculated in the solver iterative procedure. Note that not all variables are available at any time. If a given variable is not available in one of the chosen scopes, a NOT_AVAILABLE_DATA error is returned.

List of variable_name values:

  • "rho": Density [kg/m3]

  • "mu": Viscosity [Pa.s]

  • "alpha": Volume Fraction [m3 of field|layer|phase /m3 of mixture]

  • "mass_concentration": Mass Concentration [kg of field|layer|phase /m3 of mixture]

  • "P": Pressure [Pa]

  • "T": Temperature [K]

  • "h": Specific Enthalpy [J/kg]

  • "cp": Specific Heat Capacity [J/kg.K]

  • "k": Thermal Conductivity [W/m.K]

  • "eta_inner": Heat Transfer Coefficient between inner pipe wall and the fluid layers [W/m2.K]

  • "U": Velocity [m/s]

  • "U_superficial": Superficial Velocity [m/s]

  • "RS": Gas mass fraction in gas/oil mixture [kg/kg]

  • "RSW": Water vapour mass fraction in gas phase [kg/kg]

  • "ff_S_wall": Wall friction factor times wall perimeter [-]

  • "ff_S_interface": Interface Friction factor times interface perimeter [-]

  • "D": Pipe Inner Diameter [m]

  • "A": Cross-sectional Area in each control volume [m2]

  • "theta": Inclination of each control volume [rad]

  • "dx": Control Volume Length along the Pipe Axis [m]

  • "dv": Volume of the control volume [m3]

  • "D_eff": Effective Pipe Inner Diameter, considering the internal deposit layers [m]

  • "A_eff": Cross-sectional Area Effective in each control volume, considering the internal deposit layers [m2]

  • "dv_eff": Effective Volume of the control volume, considering the internal deposit layers [m3]

It is important to know that the listed variable_names are no available in all MultiFieldDescriptionScope and GridScope. Because of that, the error_code must be checked.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Variable values array.

  • [in] variable_name: String with the variable name. See the list of possible values above.

  • [in] var_scope: It must be configured to determine all scopes in which the variable will be retrieved. See VariableScope for more information.

  • [in] line_index: It can represent Layer/Field/Phase ID, since the secondary variables can be associated to different MultiFieldDescriptionScope. When it is a GLOBAL variable line_index must be 0.

  • [out] size: Size of the out array of values.

Warning

Changing the contents retrieved by this function (out array) has UNDEFINED BEHAVIOR. The plugin must NEVER change the contents returned by this function.

int get_simulation_tracer_array(void *ctx, double **out, const char *variable_name_c, struct VariableScope var_scope, int tracer_index, int line_index, int *size)

Gets the current contents of a given tracer mass fraction (For an array data pointer). A tracer mass fraction is calculated in the extra solver iterative procedure. Note that not all tracer mass fraction are available at any time. If a given tracer mass fraction (in an inexistent field) is not available, a NOT_AVAILABLE_DATA error is returned.

List of variable_name_c values:

  • "phi": Mass Fraction [kg of tracer (in field|phase) / kg of mixture]

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Variable values array.

  • [in] variable_name_c: String with the variable name. See the list of possible values above.

  • [in] var_scope: It must be configured to determine all scopes in which the variable will be retrieved. See VariableScope for more information.

  • [in] tracer_index: Tracer ID, it can be retrieved by get_tracer_id.

  • [in] line_index: It can represent Field or Phase ID, since the tracer masss fraction can be calculated related to Field or Phase. When it is the mass fraction on mixture the line_index must be 0.

  • [out] size: Size of the out array of values.

Warning

Changing the contents retrieved by this function (out array) has UNDEFINED BEHAVIOR. The plugin must NEVER change the contents returned by this function.

int get_simulation_quantity(void *ctx, double *out, enum TimestepScope ts_scope, const char *variable_name_c)

Gets the current contents of a given secondary variable (For a single quantity). A secondary variable is any variable calculated in the solver iterative procedure. Note that not all variables are available at any time. If a given variable is not available, a NOT_AVAILABLE_DATA error is returned.

List of variable_name_c values:

  • "dt": Time Step [s]

  • "time": Current time [s]

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Variable value.

  • [in] ts_scope: TimestepScope value.

  • [in] variable_name_c: String with the variable name. See the list of possible values above.

int get_tracer_id(void *ctx, int *tracer_id, void *reference)

Retrieves the tracer ID given a tracer reference. A tracer reference may be obtained from the user input data (See get_plugin_input_data_reference API function for an example).

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] tracer_id: Tracer ID.

  • [in] reference: Tracer reference.

int get_tracer_name_size(void *ctx, int *tracer_name_size, void *reference)

Retrieves the size of the tracer name, given a tracer reference. A tracer reference may be obtained from the user input data (See get_plugin_input_data_reference API function for an example).

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] tracer_name_size: Size of tracer name string.

  • [in] reference: Tracer reference.

int get_tracer_name(void *ctx, char *out, void *reference, int size)

Retrieves the tracer name, given a tracer reference. The tracer_name parameter must be a valid and pre-allocated memory region where the name string will be copied to. A tracer reference may be obtained from the user input data (See get_plugin_input_data_reference API function for an example).

Example of usage:

int tracer_name_size = -1;
errcode = get_tracer_name_size(ctx, &tracer_name_size, tracer_ref);

char* tracer_name = (char*)malloc(sizeof(char) * tracer_name_size);
errcode = get_tracer_name(
    ctx, tracer_name, tracer_ref, tracer_name_size);
std::cout << "TRACER NAME: " << tracer_name << std::endl;
free(tracer_name);

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: String with tracer name.

  • [in] reference: Tracer reference.

  • [in] size: Size of out string.

int get_tracer_ref_by_name(void *ctx, void **reference, const char *tracer_name, const char *plugin_id)

Gets the tracer reference for a given tracer name. This function is important to obtain the tracer reference of a user defined tracer added by the plugin.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] reference: Tracer reference.

  • [in] tracer_name: Tracer name.

  • [in] plugin_id: Plugin ID.

int get_tracer_partition_coefficient(void *ctx, double *out, void *reference, int phase_id)

Gets the partition coefficient input data for a given tracer reference. The phase_id must also be given (See get_phase_id API function). A tracer reference may be obtained from the user input data (See get_plugin_input_data_reference API function for an example).

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Partition coefficient value related to the specified phase.

  • [in] reference: Tracer reference.

  • [in] phase_id: Phase ID.

int get_wall_interfaces_temperature(void *ctx, double **out, int control_volume, enum TimestepScope ts_scope, int *size)

Gets the wall interface temperature for a given control volume. Each control volume has an array of temperatures, one for each wall layer. The temperatures are given in the wall interfaces.

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Wall interfaces temperature values array.

  • [in] control_volume: Control Volume ID.

  • [in] ts_scope: TimestepScope value.

  • [in] size: Size of out array of values.

int get_flow_pattern(void *ctx, int **out, enum GridScope grid_scope, enum TimestepScope ts_scope, int *size)

Gets the flow pattern for each control volume.

List of possible values of Flow Pattern is:

  • 0 - Unknown

  • 1 - Stratified

  • 2 - Dispersed Bubble

  • 3 - Bubble

  • 4 - Slug

  • 5 - Annular Mist

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Flow Pattern values array. See list of possible values above.

  • [in] grid_scope: A GridScope value.

  • [in] ts_scope: A TimestepScope value.

  • [in] size: Size of out array of values.

Unit Cell Model (UCM) helpers
int get_ucm_friction_factor_input_variable(void *ctx, double *out, const char *var_name, int phase_id)

Gets the current UCM (unit cell model) input data for friction factor calculation. Any available variable by this function is considered for a unit cell, which means that there are variables with one value and there are variables with two values related to the two phase system (GAS and LIQUID). If a given variable name is not available, a NOT_AVAILABLE_DATA error is returned.

List of variable_name with two values (Two phase):

  • "alpha": Volume Fraction [m3 of phase /m3 of mixture]

  • "rho": Density [kg/m3]

  • "mu": Viscosity [Pa.s]

  • "U": Velocity [m/s]

It is important to know that the listed variable_names are not available in any phase, only for two phase systems, in which Gas id is 0 (zero) and Liquid id (sum of all liquid phases) is 1 (One). Because of that, the error_code must be checked.

List of variable_name with one value:

  • "D": Unit Cell Inner Diameter [m]

  • "ks": Roughness [m]

  • "theta": Inclination of the Unit Cell [rad]

  • "sigma": Gas-liquid Surface Tension [N/m]

Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] out: Variable value.

  • [in] var_name: String with the variable name. See the list of possible values above.

  • [in] phase_id: A TwoPhaseSystem value. When the requested variable is not associated to a phase any value can be passed.

int get_ucm_fluid_geometrical_properties(void *ctx, double *S_w, double *S_i, double *H, double alpha_G, double D)

Gets the current UCM (unit cell model) fluid geometrical properties for friction factor calculation.

During the implementation of any HOOK related to the UCM friction factor, this function provides the following fluid geometrical properties:

  • "S_w": Wetted perimeters of phases [m].

  • "S_i": Interface perimeter [m].

  • "H": Phase height [m].

It is important to know that

S_w and H must be pointers to an array of size two (GAS and LIQUID).
Return

An error_code value.

Parameters
  • [in] ctx: ALFAsim’s plugins context.

  • [out] S_w: Wetted Perimeters [m].

  • [out] S_i: Interface Perimeter [m].

  • [out] H: Phase height [m]. For annular flow, H[GAS] is the core diameter and H[LIQUID] is the total liquid film height.

  • [in] alpha_G: Unit Cell Gas Volume Fraction [m3 of gas phase /m3 of mixture].

  • [in] D: Unit Cell Inner Diameter [m].

Variable Name Parsing

To retrieve input data from the plugin’s GUI, the plugin must pass a var_name in a specific format. API functions that use this kind of variable described on Plugin Input Data (From user interface) section.

All variables must begin with the model name described on the plugin model, followed by . (For nested objects) or -> (For references). Lists must be accessed with the list index directly, for example, Model.lst[0] will be the first element of the list “lst”, inside the plugin model named “Model”. References can be internal (Reference to a plugin model) or external (Reference to an ALFAsim model).

Basic example

Imagine you have the following simple GUI model defined as

@data_model(icon='', caption='Plugin Model')
class Model:
    boolean_data = Boolean(value=True, caption="BOOLEAN CAPTION")

To extract the plugin input data content on C++, the plugin must use the proper API function call:

int errcode = 0;
bool test_api_boolean = false;
errcode = alfasim_sdk_api.get_plugin_input_data_boolean(
    ctx, &test_api_boolean, get_plugin_id(), "Model.boolean_data");
std::cout << " BOOLEAN:" << test_api_boolean
          << " ERROR CODE:" << errcode
          << std::endl;

See get_plugin_input_data_boolean() for details.

List Model Example

For the cases were the model is a container, it is possible to retrieve the information for each element individually.

@data_model(icon='', caption='Plugin Model 2')
class Model:
    name = String(value='default', caption='Name')
    boolean = Boolean(value=True, caption="Boolean")
    quantity = Quantity(value=1, unit='m', caption='Quantity')


@container_model(icon='', caption='Plugin Container', model=Model)
class ModelContainer:
    pass

To extract the plugin input data content on C++, the plugin must use the proper API function call:

int errcode = 0;
double test_api_quantity = 0.;
errcode = alfasim_sdk_api.get_plugin_input_data_quantity(
   ctx, &test_api_quantity, get_plugin_id(), "ModelContainer[0].quantity");
std::cout << " Quantity from container[0]:" << test_api_quantity
          << " ERROR CODE:" << errcode
          << std::endl;

See get_plugin_input_data_quantity() for details.

Internal Reference Example

Internal references are references to models defined in the plugin itself. They are useful when you have a list of models, for example, but need to let the user decide from one specific model from the list. Assuming the model container defined in the previous, example, an internal reference for an element inside that container can be programmed as follows. The plugin must use -> to access referenced data, instead of . as in other examples.

@data_model(icon='', caption='Plugin Model')
class OtherModel:
    internal_reference = Reference(
        container_type='ModelContainer',
        ref_type=Model,
        caption="Internal Reference"
    )

Data from the referenced model can then be extracted on C++ code as follows. Note that the developer will extract the values directly, not the model itself, that is, in the example below, there is never an object of type Model. Raw data values such as boolean, strings or floats are directly retrieved instead.

int errcode = 0;
double test_api_quantity = 0.;
errcode = alfasim_sdk_api.get_plugin_input_data_quantity(
    ctx, &test_api_quantity, get_plugin_id(), "OtherModel.internal_reference->quantity");
std::cout << " Quantity from internal reference:" << test_api_quantity
          << " ERROR CODE:" << errcode
          << std::endl;
External Reference Example

External references gives the user a way to interact with references to specific ALFAsim’s GUI object configurations. Those types of references work a bit different, because ALFAsim developers must provide an API for each specific entity. As of today, the only exposed ALFAsim model is the Tracer model. See the tracer-related functions to have an overview about the available data that can be used:

The example below extracts the tracer Id configured in the plugin.

@data_model(icon='', caption='Plugin Model')
class OtherModel:
    tracer_reference = Reference(
        ref_type=TracerType,
        caption="Tracer Reference",
    )

To extract the plugin input data content on C++, the plugin must use the proper API function call:

int errcode = 0;
void* tracer_ref = nullptr;
errcode = get_plugin_input_data_reference(
    ctx, &tracer_ref, get_plugin_id(), "OtherModel.tracer_reference");

int tracer_id = -1;
errcode = get_tracer_id(ctx, &tracer_id, tracer_ref);
std::cout << "TRACER ID: " << tracer_id << std::endl;

See get_plugin_input_data_reference() for details.

Multiple Reference

The plugin developer may need to let the user select not one, but several references (This is valid for both internal and external references). To tackle this problem, ALFAsim developers created the notion of Multiple References. It is basically a container of referenced objects, and the usage is simply a mix of the container with the reference syntax.

Example of a GUI model in which has both types of multiple references:

@data_model(icon='', caption='Plugin Model')
class OtherModel:
    multiple_reference = MultipleReference(
        ref_type=TracerType,
        caption='Multiple Reference'
    )

    internal_multiple_reference = MultipleReference(
        ref_type=Model,
        container_type='ModelContainer',
        caption='Internal Multiple Reference'
    )

Example of accessing the external multiple references:

int errcode = -1;
int indexes_size = -1;
errcode = get_plugin_input_data_multiplereference_selected_size(
    ctx, &indexes_size, get_plugin_id(), "OtherModel.multiple_reference");

void* tracer_ref = nullptr;
for (int i = 0; i < indexes_size; ++i) {
    auto reference_str = std::string(
        "OtherModel.multiple_reference[" + std::to_string(i) + "]");
    errcode = get_plugin_input_data_reference(
        ctx, &tracer_ref, get_plugin_id(), reference_str.c_str());

    int tracer_id = -1;
    errcode = get_tracer_id(ctx, &tracer_id, tracer_ref);
    std::cout << "TRACER ID: " << tracer_id << std::endl;
}

Example of accessing the internal multiple references:

int errcode = -1;
 int indexes_size = -1;
 errcode = get_plugin_input_data_multiplereference_selected_size(
     ctx,
     &indexes_size,
     get_plugin_id(),
     "OtherModel.internal_multiple_reference");

 for (int i = 0; i < indexes_size; ++i) {
     auto test_api_bool = false;
     auto reference_str = std::string(
         "OtherModel.internal_multiple_reference[" + std::to_string(i) + "]->boolean");
     errcode = get_plugin_input_data_boolean(
         ctx,
         &test_api_bool,
         get_plugin_id(),
         reference_str.c_str());
     std::cout << " Bool from referenced container[" << i << "]:" << (test_api_bool ? "true" : "false")
               << " ERROR CODE:" << errcode
               << std::endl;
 }

see get_plugin_input_data_multiplereference_selected_size() for details.

Application API

Here is listed the completed API available to implement the Application Hooks.

Models
data_model(*, caption, icon=None)

`data_model` is an object that keeps together many different properties defined by the plugin and allows developers to build user interfaces in a declarative way.

Application Required:

The following options are required when declaring a data_model and are used into the user interface

caption

A text to be displayed over the Tree.

icon

Name of the icon to be used over the Tree.

Note

Even though the icon parameter is required, it’s not currently being used.

Plugin Defined:

Visual elements that allow the user to input information into the application, or to arrange better the user interface.

Input Fields

Visual elements that allow the user to provide input information into the application.

Layout

Elements that assist the developer to arrange input fields in a meaningful way.

Check the section visual elements to see all inputs available, and layout elements to see all layouts available.

Example:

@data_model(icon='', caption='My Plugin')
class MyModel:
        distance = Quantity(value=1, unit='m', caption='Distance')


@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
        return [MyModel]
_images/data_model_example_1_1.png _images/data_model_example_1_2.png
container_model(*, model, caption, icon)

container_model is an object that keeps together many different properties defined by the plugin and allows developers to build user interfaces in a declarative way similar to data_model().

container_model() can also hold a reference to a data_model() declared from the plugin, making this object a parent for all new data_model() created.

Application Required:

The following options are required when declaring a container_model().

Caption

A text to be displayed over the Tree.

Icon

Name of the icon to be used over the Tree.

Model

A reference to a class decorated with data_model().

Note

Even though the icon parameter is required, it’s not currently being used.

Plugin defined:

Visual elements that allow the user to input information into the application, or to arrange better the user interface.

Input Fields

Visual elements that allow the user to provide input information into the application.

Layout

Elements that assist the developer to arrange input fields in meaningfully way.

Check the section visual elements to see all inputs available, and layout elements to see all layouts available.

Example myplugin.py

@data_model(icon="", caption="My Child")
class ChildModel:
    distance = Quantity(value=1, unit="m", caption="Distance")


@container_model(icon='', caption='My Container', model=ChildModel)
class MyModelContainer:
    my_string = String(value='Initial Value', caption='My String')


@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModelContainer]
_images/container_model_example_1_1.png _images/container_model_example_1_2.png _images/container_model_example_1_3.png

Container data also includes automatically two actions for the model:

Action: Create new Model

An action that creates a new model inside the container selected, you can activate this action by right-clicking in the container over the Tree, or by clicking on the “Plus” icon available at the Model Explorer.

_images/container_model_new_model_1.png _images/container_model_new_model_2.png

Action: Remove

An action that remove the selected model, only available for models inside a container, you can activate this action by right-clicking the model over the Tree, or by clicking on the “Trash” icon available at the Model Explorer.

_images/container_model_remove_1.png _images/container_model_remove_2.png
Types

The types module supplies UI elements for creating user interfaces with the classic desktop-style, each type has a related model.

Models are the primary elements to create user interfaces on ALFAsim, models can display data, receive user input, and provide a container for other fields that should be grouped together.

class BaseField

A base field for all types available at ALFAsim.

Parameters
  • caption – Label to be displayed on the right side of the component.

  • tooltip – Shows a tip, a short piece of text.

  • enable_expr (Callable) – Function to evaluate if the component will be enabled or not.

  • visible_expr (Callable) – Function to inform if the component will be visible or not.

Caption and Tooltip:

Caption is the most basic information that all fields must inform, it will display Label over the right side of the component on the Model Explorer window.

Tooltips are short pieces of text to reminder/inform the user about some specificity about the property when they keep the mouse over the field. Tooltips must be a string and can have HTML tags and Unicode characters as well.

Raises

TypeError – if the tooltip informed is not a string.

Example myplugin.py

@data_model(icon='', caption='My Plugin')
class MyModel:
    my_string_1= String(
        value='String 1',
        caption='My String 1',
        tooltip="Some Text <br> <b> More Information</b>",
    )
    my_string_2 = String(
        value='String 2',
        caption='My String 2',
        tooltip="∩ ∪ ∫ ∬ ∮",
    )

@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModel]

The images below shows the output from the example above.

_images/base_field_caption.png _images/base_field_tootip_1.png _images/base_field_tootip_2.png

Enable Expression:

Accepts a python function that controls either the component will be enabled, or disabled. The python function will receive two arguments, an instance of itself (to check local values) and an instance of alfasim_sdk.context.Context() to retrieve information about the application.

This function must return a boolean, informing True (for enabled) or False (for disabled).

enabled: The component will handle keyboard and mouse events.

disabled: The component will not handle events and it will be grayed out.

Example myplugin.py

def my_check(self, ctx):
    return self.bool_value

@data_model(icon="", caption="My Plugin")
class MyModel:
    bool_value = Boolean(value=True, caption="Enabled")
    N_ions = Quantity(
        caption='Number of Ions',
        value=1,
        unit='-',
        enable_expr=my_check,
    )

@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModel]

The image below shows the N_ions property disabled, when the property bool_value is disabled (False)

_images/base_field_enable_expr_1.png _images/base_field_enable_expr_2.png

Visible Expression:

Accepts a python function that controls either the component will be visible, or not. The python function will receive two arguments, an instance of itself (to check local values) and an instance of alfasim_sdk.context.Context() to retrieve information about the application.

This function must return a boolean, informing True (for visible) or False (for invisible).

Example myplugin.py

def my_check(self, ctx):
    return self.bool_value


@data_model(icon="", caption="My Plugin")
class MyModel:
    bool_value = Boolean(value=True, caption="Enabled")
    N_ions = Quantity(
        caption="Number of Ions",
        value=1,
        unit="-",
        visible_expr=my_check,
    )


@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModel]

The image below shows the N_ions property visible, when the property bool_value is enabled (True)

_images/base_field_visible_expr_1.png _images/base_field_visible_expr_2.png
class String

The String field represents an input that allows the user to enter and edit a single line of plain text.

The String field have all options available from BaseField(), plus the following ones

Parameters

value (str) – property to hold the value informed by the user.

Example myplugin.py

@data_model(icon="", caption="My Plugin")
class MyModel:
    string_field = String(
        value="Default Value",
        caption="String Field",
    )
_images/string_field_example.png

Accessing String Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++ you need to use get_plugin_input_data_string_size() together with get_plugin_input_data_string_size()

Accessing String Field from Context:

When accessed from the Context(), the String field will return the currently text as str.

>>> ctx.get_model("MyModel").string_field
'Default Value'

>>> type(ctx.get_model("MyModel").string_field)
<class 'str'>
class Enum

The Enum field provides list of options to the user, showing only the select item but providing a way to display a list of all options through a combo-box.

The Enum field have all options available from BaseField(), besides the listed the ones listed above:

Parameters
  • values – A list of strings with the available options.

  • initial – Indicates which one of the options should be selected per default. If not given, the first item in values will be used as default.

Example myplugin.py

@data_model(icon="", caption="My Plugin")
class MyModel:
    enum_field = Enum(
        values=["Option 1, Option 2"],
        initial="Option 1",
        caption="Enum Field",
    )
_images/enum_field_example.png

Accessing Enum Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++, you need to use get_plugin_input_data_enum()

Accessing Enum Field from Context:

When accessed from the Context(), the Enum field will return the currently selected option as str.

@data_model(icon="", caption="My Plugin")
class MyModel:
    enum_field = Enum(
        values=["Option 1", "Option 2"],
        initial="Option 1",
        caption="Enum Field",
    )
# From Terminal
>>> ctx.get_model("MyModel").enum_field
'Option 1'

>>> type(ctx.get_model("MyModel").enum_field)
<class 'str'>
class Reference

The Reference field provides a list of options to the user and displays the current item selected.

There are two types of models supported by this field.

ALFAsimTypes

models from ALFAsim, for example, Tracers.

Custom Data

a model defined within the plugin.

Note

In order to reference custom data, the model must be inside a container.

Parameters
  • caption (str) – Property used as a label for the field.

  • ref_type – Property that indicates which type of data the Reference will hold.

  • container_type – The name of the class that holds the ref_type, this property must be used when the ref_type references model from the plugin.

Example using ALFAsimTypes on myplugin.py

@data_model(icon="", caption="My Plugin")
class MyModel:
    tracer_ref = Reference(
        ref_type=TracerType,
        caption="Tracer Type",
    )
_images/reference_field_example_1.png

Example using Custom Data on myplugin.py

@data_model(caption="My Model")
class MyModel:
    field_1 = String(value="Value 1", caption="String 1")


@container_model(caption="My Container", model=MyModel, icon="")
class MyContainer:
    internal_ref = Reference(
        ref_type=MyModel,
        container_type="MyContainer",
        caption="Internal Reference",
    )
_images/reference_field_example_2.png

Accessing Reference Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++, you need to use get_plugin_input_data_reference()

Accessing Reference Field from Context:

When accessed from the Context(), the Reference field will return the currently selected option object instance.

With the instance, you can access all attributes from the object normally. Check the example below.

@data_model(caption="My Model")
class MyModel:
    field_1 = String(value="Value 1", caption="String 1")

@container_model(caption="My Container", model=MyModel, icon="")
class MyContainer:
    tracer_ref = Reference(
        ref_type=TracerType,
        caption="Tracer Type",
    )
    internal_ref = Reference(
        ref_type=MyModel,
        container_type="MyContainer",
        caption="Internal Reference",
    )

# Example with Tracer
>>> ctx.get_model("MyContainer").tracer_ref
TracerModel(gas_partition_coefficient=[...])

>>> ctx.get_model("MyContainer").tracer_ref.gas_partition_coefficient
Scalar(0.0, 'kg/kg', 'mass fraction')

# Example with Custom Data
>>> ctx.get_model("MyContainer").internal_ref
MyModel(field_1='Value 1', name='My Model 1')

>>> ctx.get_model("MyContainer").internal_ref.field_1
'Value 1'
class MultipleReference

The MultipleReference field works similar to Reference(), providing a list of options to the user, but allowing multiple values, of the same type, to be chosen.

There are two types of models supported by this field. :ALFAsimTypes: models from ALFAsim, for example, Tracers. :Custom Data: a model defined within the plugin.

Note

In order to reference a custom data the model must be inside a container.

Variables
  • caption (str) – Property used as a label for the field.

  • ref_type – Property that indicates which type of data the Reference will hold.

  • container_type – The name of the class that holds the ref_type, this property must be used when the ref_type references model from the plugin.

Example using ALFAsimTypes on myplugin.py

@data_model(icon="", caption="My Plugin")
class MyModel:
    tracer_ref = MultipleReference(
        ref_type=TracerType, caption="Tracer Type"
    )
_images/multiplereference_field_example_1.png

Example using Custom Data on myplugin.py

@data_model(caption="My Model")
class MyModel:
    field_1 = String(value="Value 1", caption="String 1")


@container_model(caption="My Container", model=MyModel, icon="")
class MyContainer:
    internal_ref = MultipleReference(
        ref_type=MyModel,
        container_type="MyContainer",
        caption="Internal Reference",
    )
_images/multiplereference_field_example_2.png

Accessing MultipleReference Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++, you need to use get_plugin_input_data_multiplereference_selected_size()

Accessing MultipleReference Field from Context:

When accessed from the Context(), the MultipleReference field will return a list with the currently selected option objects instances.

With the instance, you can access all attributes from the object. Check the example below.

@data_model(caption="My Model")
class MyModel:
    field_1 = String(value="Value 1", caption="String 1")


@container_model(caption="My Container", model=MyModel, icon="")
class MyContainer:
    internal_ref = MultipleReference(
        ref_type=MyModel,
        container_type="MyContainer",
        caption="Internal Reference",
    )


# Example
>>> ctx.get_model("MyContainer").internal_ref
[MyModel(field_1='Value 1', name='My Model 1'),
MyModel(field_1='Value 1', name='My Model 4')]

>>> type(ctx.get_model("MyContainer").internal_ref)
<class 'list'>

>>> ctx.get_model("MyContainer").internal_ref[0]
MyModel(field_1='Value 1', name='My Model 1')
class Quantity

The Quantity field provides a way to the user provide a scalar value into the application.

The Quantity field have all options available from BaseField(), besides the listed the ones listed above: :param values: A number value. :param unit: Unit for the given scalar.

All scalar values are created using the Barril library

Checkout the Barril documentation, to see all available units

Note

If you want to check the input value, is recommended to include a status monitor in your plugin to make sure that the provided value is valid.

For more details about status monitor check alfasim_get_status()

Example myplugin.py

@data_model(icon="", caption="My Plugin")
class MyModel:
    quantity_field = Quantity(
        value=1, unit="degC", caption="Quantity Field"
    )
_images/quantity_field_example.png

Accessing Quantity Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++, you need to use get_plugin_input_data_quantity()

Accessing Quantity Field from Context:

When accessed from the Context(), the Quantity field will return a Scalar object, with the current value and unit. Check out the Scalar documentation from Barril for more details about the usage.

@data_model(icon="", caption="My Plugin")
class MyModel:
    quantity_field = Enum(
        values=["Option 1", "Option 2"],
        initial="Option 1",
        caption="Enum Field",
    )

# From Terminal
>>> ctx.get_model("MyModel").quantity_field
Scalar(1.0, 'degC', 'temperature')

>>> ctx.get_model("MyModel").quantity_field.value
1.0

>>> ctx.get_model("MyModel").quantity_field.unit
'degC'

>>> ctx.get_model("MyModel").quantity_field.GetValue('K')
274.15
class Table

The Table component provides a table to the user to be able input values manually or by importing it from a file.

Example myplugin.py

@data_model(icon="", caption="My Model")
class MyModel:
    Table(
        rows=[
            TableColumn(
                id="temperature",
                value=Quantity(
                    value=1,
                    unit="K",
                    caption="Temperature Column Caption",
                ),
            ),
            TableColumn(
                id="pressure",
                value=Quantity(
                    value=2,
                    unit="bar",
                    caption="Pressure Column Caption",
                ),
            ),
        ],
        caption="Table Field",
    )

The image above illustrates the output from the example above.

_images/table_field_example_1.png

With this component, the user can easily import the content from a file by clicking on the last icon from the toolbar menu.

_images/table_field_example_2.png

The wizard assistance supports multiple types of file, the user just needs to inform which kind of configuration the file has.

_images/table_field_example_3.png

By the end, it’s possible for the user select to which unit the values must be converted and which columns.

Accessing Table Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++, you need to use get_plugin_input_data_table_quantity()

Accessing Table Field from Context:

When accessed from the Context(), the Table field will return a model, with information about all columns.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@data_model(icon="", caption="My Model")
class MyModel:
    Table(
        rows=[
            TableColumn(
                id='temperature',
                value=Quantity(value=1, unit='K', caption='Temperature Column Caption'),
            ),
            TableColumn(
                id='pressure',
                value=Quantity(value=2, unit='bar', caption='Pressure Column Caption'),
            ),
        ],
        caption="Table Field"
    )

# From Terminal
>>> ctx.get_model("MyModel").table_field
TableContainer([...])

>>> len(ctx.get_model("MyModel").table_field)
6

>>> len(ctx.get_model("MyModel").table_field)
TableRow(temperature=Scalar(1.0, 'K', 'temperature'), pressure=Scalar(2.0, 'bar', 'pressure'))

>>> ctx.get_model("MyModel").table_field[0].pressure
Scalar(2.0, 'bar', 'pressure')
class TableColumn

The TableColumn component provides columns for a Table() field. Currently only columns with a Quantity() fields are available.

Check out the documentation from Table() to see more details about the usage and how to retrieve values.

class Boolean

The Boolean field provides a checkbox to select/deselect a property.

The Boolean fields have all options available from BaseField(), besides the listed the ones listed above: :param value: A boolean informing the initial state from the Field

Example myplugin.py

@data_model(icon="", caption="My Plugin")
class MyModel:
    boolean_field = Boolean(
        value=False,
        caption="Boolean Field",
    )
_images/boolean_field_example_1.png

Accessing Boolean Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++, you need to use get_plugin_input_data_boolean()

Accessing Quantity Field from Context:

When accessed from the Context(), the Boolean field will return a boolean value

@data_model(icon="", caption="My Plugin")
class MyModel:
    quantity_field = Boolean(
        value=False,
        caption="Boolean Field",
    )

# From Terminal
>>> ctx.get_model("MyModel").boolean_field
False
class FileContent

The FileContent component provides a platform-native file dialog to the user to be able to select a file. The name of the selected file will be available over the GUI.

Note

If you want to make the file mandatory it is recommended to include a status monitor in your plugin to make sure that a file is selected.

For more details about status monitor check alfasim_get_status()

Parameters

caption – Label to be displayed on the right side of the component.

Example myplugin.py

@data_model(icon="", caption="My Plugin")
class MyModel:
    file_content_field = FileContent(caption="FileContent Field")
_images/file_content_field_example_1.png

Accessing FileContent Field from Plugin:

In order to access this field from inside the plugin implementation, in C/C++, you need to use get_plugin_input_data_file_content() together with get_plugin_input_data_file_content_size()

Accessing Quantity Field from Context:

When accessed from the Context(), the FileContent field will return a FileContent object, a Model that represent a file from the filesystem.

Class FileContent

Path

Return a Path object of the file.

Content

The content from the file in binary format.

Size

The size of the file in bytes.

Modified_data

Return a Datetime object, with the last time the file was modified

>>> ctx.get_model("MyModel").file_content_field.path
WindowsPath('C:/ol-wax-1.wax')
>>> ctx.get_model("MyModel").file_content_field.content
b"!Name of Table  [...] "
>>> ctx.get_model("MyModel").file_content_field.size
90379
>>> ctx.get_model("MyModel").file_content_field.modified_data
datetime.datetime(2019, 5, 10, 14, 22, 11, 50795)
Layout
group()

The group layout is a container to organize ALFAsim types, only fields that derives from BaseField can be defined inside a group.

Example.:

@data_model(icon="", caption="My Model")
class MyModel:
    string_field_1 = String(caption="Outside", value="Default")

    @group(caption="Group Container")
    class GroupMain:
        string_field_2 = String(value="Group 1", caption="Inside")
        bool_field = Boolean(value=True, caption="Boolean Field")

The image below shows the output from the example above.

_images/group_layout_example.png

Note

group is a layout component, and will not have an attribute to be accessed through context or API.

tabs()

Create a tab bar layout, to group multiples :func:”~alfasim_sdk.layout.tab” instances.

With the tabs, you can split up complex dialog into “pages” using a :func:”~alfasim_sdk.layout.tab” instance.

Notice that only classes decorated with :func:”~alfasim_sdk.layout.tab” can be placed inside a tab bar.

Example of usage:

@data_model(icon="", caption="My Model")
class MyModel:
    field = String(caption="String outside tabs", value="Default")

    @tabs()
    class MainPage:

        @tab(caption="Fist Tab")
        class Tab1:
            field_1 = String(caption="First Tab", value="Default")

        @tab(caption="Second Tab")
        class Tab2:
            field_2 = String(caption="Second Tab", value="Default")

The image below shows the output from the command above.

_images/tabs_layout_example_1.png _images/tabs_layout_example_2.png

Note

tabs is a layout component, and will not have an attribute to be accessed through context or API.

tab()

The tab represents a single entry, on the tabs() layout.

Notice that only components available at the types modules can be placed inside a tab.

Status
class ErrorMessage

ErrorMessage allows the plugin to display a message over the status monitor, and signalize to the application to block the simulation until the issue is fixed.

Parameters
  • model_name – Name of the model that issues the error.

  • message – Message that will be displayed over the status monitor.

Checkout the alfasim_get_status() for some examples of ErrorMessage() in action.

class WarningMessage

WarningMessage allows the plugin to display a message to the user over the status monitor, and signalizes a minor issue that needs to be fixed but doesn’t block the simulation.

Parameters
  • model_name – Name of the model that issues the warning.

  • message – Message that will be displayed over the status monitor.

Checkout the alfasim_get_status() for some examples of WarningMessage() in action.

Context
class Context

The context class provides information about the current state of the application and the models implemented by the user.

The following methods provide an instance of Context() to inform the current state of the application:

get_edges()

Return a list of all Edges available on ALFAsim. Each Edge is represented by an instance of EdgeInfo().

Example of GetEdges

_images/context_access_network.png

The image above has two Edges configured, in order to access the available Edges, it’s possible to use the method GetEdges as demonstrated below.

Accessing GetEdges from the context

>>> ctx.get_edges()[0]
EdgeInfo(name='Pipe 1', number_of_phases_from_associated_pvt=2)

>>> ctx.get_pipelines()[0].number_of_phases_from_associated_pvt
'Pipe 1'

Checkout the EdgeInfo() section to know more about the properties available.

get_model(model_name)

Returns an instance of the given model_name.

The parameter model_name must be the name of a model defined within the plugin.

In the example below, the Context is used to access a property from the model MyModel

ctx.GetModel("Acme") as exemplified in the code below.

Setting up the model

@data_model(caption="MyPlugin", icon="")
class MyModel:
    name = String(value="ALFAsim", caption="Field")
    scalar = Quantity(value=1, unit="degC", caption="Field")

@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModel]

Accessing the context

>>> ctx.get_model('MyModel')
MyModel(name='ALFAsim', scalar=Scalar(1.0, 'degC', 'temperature'))

>>> ctx.get_model('MyModel').name
'ALFAsim'

At runtime, you can also verify the names of the models defined by a given plugin. For this, you need to For more information check GetPluginInfoById()

Raises
  • TypeError – When the given model_name does not exist.

  • FrozenInstanceError – When trying to modify a value

get_nodes()

Return a list of all Nodes available on ALFAsim. Each Node is represented by an instance of alfasim_sdk.context.NodeInfo().

Usage Example of GetNodes

_images/context_access_network.png

The image above has three nodes configured, you can access this information by using the method GetNodes as demonstrated below.

>>> ctx.get_nodes[0]
NodeInfo(name='Node 1', number_of_phases_from_associated_pvt=2)

>>> ctx.get_nodes[0].name
'Node 1'

Note

The values from NodeInfo are read-only, they cannot be modified.

Checkout the NodeInfo() section to know more about the properties available.

get_physics_options()

Return the physics options from the current project from ALFAsim.

Example of GetPhysicsOptions

The image below shows a configuration from a given project.

_images/context_get_advanced_options_example_2.png _images/context_get_advanced_options_example_1.png

It’s possible to access this information from inside the plugin, by using context api as demonstrate below.

Accessing GetPhysicsOptions from the context

>>> ctx.get_physics_options()
PhysicsOptionsInfo( [...] )

>>> ctx.get_physics_options().emulsion_model.value
'EmulsionModelType.brinkman1952'

>>> ctx.get_physics_options().hydrodynamic_model
HydrodynamicModelInfo( [ ... ] )

>>> ctx.get_physics_options().hydrodynamic_model.fields
['gas', 'oil', 'droplet', 'bubble']

>>> ctx.get_physics_options().hydrodynamic_model.layers
['gas', 'oil']

>>> ctx.get_physics_options().hydrodynamic_model.phases
['gas', 'oil']

Checkout the PhysicsOptionsInfo() section to know more about the properties available.

get_pipelines()

Return a list with all Pipes available on the Network from the Project. Each Pipe is represented by an instance of PipelineInfo().

Usage Example of GetPipelines

_images/context_access_network.png

The image above has two Pipelines configured, you can access this information by using the method GetPipelines as demonstrated below.

>>> ctx.get_pipelines()[0]
PipelineInfo(name='Pipe 1 > Pipeline', [ ... ])

>>> ctx.get_pipelines()[0].edge_name
'Pipe 1'

>>> ctx.get_pipelines()[0].total_length
Scalar(1000.0, 'm', 'length')

>>> len(ctx.get_pipelines()[0].segments)
1

Note

The values from PipelineInfo are read-only, they cannot be modified.

Checkout the PipelineInfo() section to know more about the properties available.

get_plugin_info_by_id(plugin_id)

Similar to GetPluginsInfos() but returns a single instance of PluginInfo() from the given plugin_id parameter.

Checkout the PluginInfo() section to know more about the properties available.

Raises

ValueError – When the plugin informed by plugin_id it’s not available.

get_plugins_infos()

Return a list of all plugins available on ALFAsim. Each plugin is represented by an instance of PluginInfo().

Usage Example of GetPluginsInfos

The example demonstrated how you can access information about the plugin from using the GetPluginsInfos() method.

Setting up the model

@data_model(caption="MyPlugin", icon="")
class MyModel:
    name = String(value="ALFAsim", caption="Field")
    scalar = Quantity(value=1, unit="degC", caption="Field")

@alfasim_sdk.hookimpl
def alfasim_get_data_model_type():
    return [MyModel]

Accessing the context

>>> ctx.get_plugins_infos()
[PluginInfo(caption='myplugin', name='myplugin', enabled=True, models=['MyModel'])]

>>> ctx.get_plugins_infos()[0].enabled
True

>>> ctx.get_plugins_infos()[0].models
['MyModel']

Checkout the PluginInfo() section to know more about the properties available.

class EdgeInfo(name, number_of_phases_from_associated_pvt)

The EdgeInfo provides information about a Edge from ALFAsim, it provides the name of the Node and the number of phases that the associate pvt model has.

class HydrodynamicModelInfo(selected_base_type, phases, fields, layers, has_water_phase)

HydrodynamicModelInfo provides information about which layer, fields, and phases the currently Hydrodynamic model is using.

class NodeInfo(name, number_of_phases_from_associated_pvt)

The NodeInfo provides information about a Node from ALFAsim, it provides the name of the Node and the number of phases that the associate PVT model has.

class PhysicsOptionsInfo(emulsion_model, solids_model, hydrodynamic_model)

PhysicsOptionsInfo provides information about the Physics Options available at ALFAsim.

The following option can be accessed:

Emulsion Model: Informs which emulsion model the application is currently using. For more information about all options available check alfasim_sdk.context.EmulsionModelType

Solids Model: Informs the current solid model being used by the application For more information about all options available check alfasim_sdk.context.SolidsModelType

Hydrodynamic Model: Provides a alfasim_sdk.context.HydrodynamicModelInfo informing which layers, fields and phases the application is currently using. For more information about all options available check alfasim_sdk.context.HydrodynamicModelInfo

class PipelineInfo(name, edge_name, segments, total_length)

The PipelineInfo provides information about the geometry of a pipeline.

PipelineSegmentInfo provides the following attributes:

name: Name associated with this Pipeline on ALFAsim

edge_name: Name of the edge that this Pipeline is associated with.

segments: List of segments associates with this Pipeline For more information check alfasim_sdk.context.PipelineSegmentInfo

total_length: Total length of the pipeline.

class PipelineSegmentInfo(inner_diameter, start_position, is_custom, roughness)

The PipelineSegmentInfo provides information about segments associated with a pipeline.

PipelineSegmentInfo provides the following attributes:

edge_name: name of the edge that the segment is associated with

start_position: Defines point where this segment starts in MD (measured depth).

inner_diameter: Inner diameter of pipe annulus.

roughness: Absolute roughness of the wall of this segment.

When `is_custom` is true, the reported roughness is customized for this segment, otherwise, the reported roughness is the original reported by the wall.

is_custom: Informs either the roughness value is custom or original from the wall

class PluginInfo(caption, name, enabled, models)

PluginInfo provides information about the plugin name, its current state (either enabled or not) and all models defined from this plugin.

Configuration API

Here is listed the completed API available to implement the Solver Configuration Hooks.

Hydrodynamic Model
class AddField

Allows the plugin to add new fields to Hydrodynamic model.

An added field must be associated to a phase (Using AddPhase or UpdatePhase) and added to a layer (Using AddLayer or UpdateLayer)

Parameters

name – Name of the new field.

Note

This type is supposed to be used in the alfasim_configure_fields() hook.

class AddPhase

Allows the plugin to add new phases to Hydrodynamic model.

Parameters
  • name – Name of the new phase.

  • fields – List of fields names associated to the added phase. It is important to know how to calculate the state variables of fields.

  • primary_field – Reference field when a phase property calculation is performed through the fields of the phase.

  • is_solid – A boolean variable to identify if the added phase is solid.

Note

This type is supposed to be used in the alfasim_configure_phases() hook.

class UpdatePhase

Allows the plugin update existing phases of the Hydrodynamic model.

List of possible phase names (see Constants for details):
  • GAS_PHASE

  • OIL_PHASE

  • WATER_PHASE (If a three phase hydrodynamic model is used)

Parameters
  • name – Name of the new phase.

  • additional_fields – List of additional fields names to be appended in the fields list of the phase.

Note

This type is supposed to be used in the alfasim_configure_phases() hook.

class AddLayer

Allows the plugin to add new layers to Hydrodynamic model.

Parameters
  • name – Name of the new layer.

  • fields – List of fields names contained in the added layer.

  • continuous_field – Name of the continuous field of the added layer (must be in the fields list).

Note

This type is supposed to be used in the alfasim_configure_layers() hook.

class UpdateLayer

Allows the plugin to update existing layer of the Hydrodynamic model.

List of possible layers names (see Constants for details):
  • GAS_LAYER

  • OIL_LAYER

  • WATER_LAYER (If a three phase hydrodynamic model is used)

Parameters
  • name – Name of the updated layer.

  • additional_fields – List of additional fields names to be appended in the fields list of the layer.

Note

This type is supposed to be used in the alfasim_configure_layers() hook.

Secondary Variables
class SecondaryVariable

Secondary variables are those variables that are not unknowns from the nonlinear system. That is, they are not directly solved in the nonlinear system, but they are calculated based on the nonlinear system results.

Parameters
  • name – Plugin secondary variable name. This name will be used to access it in the Solver Hooks.

  • caption – Caption to be shown in the GUI (For output purpose).

  • type – a Type value.

  • unit – A string with the unit of the variable.

  • visibility – a Visibility value.

  • location – a Location value.

  • multifield_scope – a Scope.

  • default_value – Default value to be set.

  • checked_on_gui_default – If the added variable has Visibility equal to Output, it indicates that this variable will be exported as output by default.

The unit param accepts all units available on Barril Unit Manager, for more information read its documentation.

Note

This type is supposed to be used in the alfasim_get_additional_variables() hook.

class Type
Indicates the type of the variable.
  • Double: Double precision floating point data type.

  • Int: Integral data type.

class Visibility
Controls the visibility of the variable.
  • Internal: The variable should only be used by the plugin, but not available to the end-user.

  • Output: The variable should be available to the end user, as a Property on Plot Window

class Location
Controls the Location of the variable in the pipe discretization.
  • Center: Center of the control volumes.

  • Face: Faces of control volumes.

class Scope
Controls the Scope of the variable.
  • Energy: One value for each energy equation (One for GLOBAL model and number of layers for LAYER model).

  • Global: One global value (or related to the mixture).

  • Field: One value for each field of the hydrodynamic model.

  • Layer: One value for each layer of the hydrodynamic model.

  • Phase: One value for each phase of the hydrodynamic model.

Constants
GAS_PHASE = 'gas'

str(object=’‘) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

OIL_PHASE = 'oil'

str(object=’‘) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

WATER_PHASE = 'water'

str(object=’‘) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

GAS_LAYER = 'gas'

str(object=’‘) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

OIL_LAYER = 'oil'

str(object=’‘) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

WATER_LAYER = 'water'

str(object=’‘) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

ALFAcase

Full API Reference

This page contains the full reference to ALFAsim-SDK API.

Case

class CaseDescription

Definitions

class CaseDescription
    name: Optional[str]
    physics: PhysicsDescription⠀
    time_options: TimeOptionsDescription⠀
    numerical_options: NumericalOptionsDescription⠀
    ipr_models: IPRModelsDescription⠀
    pvt_models: PvtModelsDescription⠀
    tracers: TracersDescription⠀
    outputs: CaseOutputDescription⠀
    pipes: List[PipeDescription]
    nodes: List[NodeDescription]
    wells: List[WellDescription]
    materials: List[MaterialDescription]
    walls: List[WallDescription]

Options

class PhysicsDescription

Definitions

class PhysicsDescription
    hydrodynamic_model: HydrodynamicModelType⠀
    simulation_regime: SimulationRegimeType⠀
    energy_model: EnergyModel⠀
    solids_model: SolidsModelType⠀
    initial_condition_strategy: InitialConditionStrategyType⠀
    restart_filepath: Optional[Path]
    keep_former_results: bool
    keep_former_results: bool
    emulsion_model: EmulsionModelType⠀
    flash_model: FlashModel⠀
    correlations_package: CorrelationPackageType
hydrodynamic_model: HydrodynamicModelType⠀
simulation_regime: SimulationRegimeType⠀
energy_model: EnergyModel⠀
solids_model: SolidsModelType⠀
initial_condition_strategy: InitialConditionStrategyType⠀
restart_filepath: string    # optional
keep_former_results: boolean
keep_former_results: number
emulsion_model: EmulsionModelType⠀
flash_model: FlashModel⠀
correlations_package: CorrelationPackageType
class TimeOptionsDescription

Definitions

class TimeOptionsDescription
    stop_on_steady_state: bool
    stop_on_steady_state: bool
    initial_time: Scalar⠀
    final_time: Scalar⠀
    initial_timestep: Scalar⠀
    minimum_timestep: Scalar⠀
    maximum_timestep: Scalar⠀
    restart_autosave_frequency: Scalar⠀
    minimum_time_for_steady_state_stop: Scalar
stop_on_steady_state: boolean
stop_on_steady_state: number
initial_time:
    value: number
    unit: string
final_time:
    value: number
    unit: string
initial_timestep:
    value: number
    unit: string
minimum_timestep:
    value: number
    unit: string
maximum_timestep:
    value: number
    unit: string
restart_autosave_frequency:
    value: number
    unit: string
minimum_time_for_steady_state_stop:
    value: number
    unit: string
class NumericalOptionsDescription

Definitions

class NumericalOptionsDescription
    nonlinear_solver_type: NonlinearSolverType⠀
    tolerance: float
    maximum_iterations: int
    maximum_timestep_change_factor: float
    maximum_cfl_value: float
    relaxed_tolerance: float
    divergence_tolerance: float
    friction_factor_evaluation_strategy: EvaluationStrategyType⠀
    simulation_mode: SimulationModeType⠀
    enable_solver_caching: bool
    enable_solver_caching: bool
    caching_rtol: float
    caching_atol: float
    always_repeat_timestep: bool
    always_repeat_timestep: bool
nonlinear_solver_type: NonlinearSolverType⠀
tolerance: number
maximum_iterations: number
maximum_timestep_change_factor: number
maximum_cfl_value: number
relaxed_tolerance: number
divergence_tolerance: number
friction_factor_evaluation_strategy: EvaluationStrategyType⠀
simulation_mode: SimulationModeType⠀
enable_solver_caching: boolean
enable_solver_caching: number
caching_rtol: number
caching_atol: number
always_repeat_timestep: boolean
always_repeat_timestep: number

Outputs

class CaseOutputDescription

Definitions

class CaseOutputDescription
    trends: List[TrendOutputDescription]
    trend_frequency: Scalar⠀
    profiles: List[ProfileOutputDescription]
    profile_frequency: Scalar
trends:
    - trend_output_description_schema⠀
trend_frequency:
    value: number
    unit: string
profiles:
    - profile_output_description_schema⠀
profile_frequency:
    value: number
    unit: string
class ProfileOutputDescription

Definitions

class ProfileOutputDescription
    curve_names: List[str]
    element_name: str
    location: OutputAttachmentLocation
curve_names:
    - str
element_name: string
location: OutputAttachmentLocation
class TrendOutputDescription

Definitions

class TrendOutputDescription
    curve_names: List[str]
    element_name: str
    position: Scalar⠀
    location: OutputAttachmentLocation
curve_names:
    - str
element_name: string
position:
    value: number
    unit: string
location: OutputAttachmentLocation

PVTs

class PvtModelsDescription

Holds a PVT which is used by the simulator to obtain fluid characteristics, such as density and viscosity, given a certain pressure and temperature.

This class is a holder for the different ways the user can enter PVT information in the application.

Parameters
  • PvtModelCorrelationDescription] correlations (Dict[str,) – Standard black-oil correlations found in the literature. The user can tune the parameters used by the correlations.

  • compositions (Dict[str, PvtModelCompositionalDescription]) – Molar fluid compositions with molecular weights and densities for each component. It be light components and/or heavy fractions to be lumped into pseudo-components.

  • tables (Dict[str, Union[str, Path]]) –

    Load a complete PVT table obtained (usually) from lab results and generated by various software. Currently the user can import the table directly from a .tab file or a .alfatable file.

    The table parameter must be filled with a dictionary where the keys informs the name of the PVT and the values informs Path to a file with the Pvt model.

    • The value which holds the Path can be either relative or absolute.

    • The name of the pvt model from the Path can contains a ‘pipe’ character in order to select one of the multiples PVT tables in the same .tab file.

    Example

    Absolute Path, using MyPvtModel

    >>> Path("/home/user/my_file.tab|MyPvtModel")
    

    Relative Path, using MyPvtModel

    >>> Path("./my_file.tab|MyPvtModel")
    

  • table_parameters (Dict[str, PvtModelTableParametersDescription]) –

    INTERNAL USE ONLY

    This attribute is populated when exporting a Study to a CaseDescription, and it holds a model representation of a PVT originated from a (.tab / .alfatable) file.

    Their usage is directly related to the export of a CaseDescription to a .alfacase/.alfatable file, where the original PVT file cannot be guaranteed to exist therefore the only reproducible way to recreate the PVT is trough the PvtModelTableParametersDescription.

Definitions

class PvtModelsDescription
    default_model: Optional[str]
    tables: Dict[str, Union[str, pathlib.Path]]
    correlations: Dict[str, PvtModelCorrelationDescription]
    compositions: Dict[str, PvtModelCompositionalDescription]
default_model: string    # optional
tables:
    string: string | Path
correlations:
    string: pvt_model_correlation_description_schema⠀
compositions:
    string: pvt_model_compositional_description_schema

Examples

PvtModelsDescription(
    default_model="PVT1",
    tables={
        'PVT1': Path('./my_tab_file.tab')
    },
)
pvt_models:
    default_model: PVT1
    tables:
        PVT1: ./my_tab_file.tab
class PvtModelCorrelationDescription
oil_density_std :

default: Scalar(850.0, “kg/m3”)

gas_density_std:

default: Scalar(0.9, “kg/m3”)

rs_sat:

default: Scalar(150.0, “sm3/sm3”)

pvt_correlation_package:

default: CorrelationPackage.Standing

Definitions

class PvtModelCorrelationDescription
    oil_density_std: Scalar⠀
    gas_density_std: Scalar⠀
    rs_sat: Scalar⠀
    pvt_correlation_package: CorrelationPackage
oil_density_std:
    value: number
    unit: string
gas_density_std:
    value: number
    unit: string
rs_sat:
    value: number
    unit: string
pvt_correlation_package: CorrelationPackage

Examples

PvtModelCorrelationDescription(
    default_model="PVT1",
)
some_value:
    some_other_value: fooo
class PvtModelTableParametersDescription
Variables
  • pressure_values (ndarray(shape=(M,1))) – Array like of sorted pressure values (m number of entries). [Pa]

  • temperature_values (ndarray(shape=(N,1))) – Array like of sorted temperature values (n number of entries). [K]

  • table_variables (List[ndarray(shape=(MxN,1))]) – List of array like values for each property such as densities, specific heats, enthalpies, etc.

  • variable_names (List[str]) – List of property names

PVT Compositional

class PvtModelCompositionalDescription
Variables
  • equation_of_state_type (Scalar) – default: Scalar(850.0, “kg/m3”)

  • surface_tension_model_type (Scalar) – default: Scalar(0.9, “kg/m3”)

  • viscosity_model (Scalar) – default: Scalar(150.0, “sm3/sm3”)

  • heavy_components (List[HeavyComponentDescription]) – default: []

  • light_components (List[LightComponentDescription]) – default: []

  • FluidDescription] fluids (Dict[str,) – default: {}

Definitions

class PvtModelCompositionalDescription
    equation_of_state_type: EquationOfStateType⠀
    surface_tension_model_type: SurfaceTensionType⠀
    viscosity_model: PVTCompositionalViscosityModel⠀
    heavy_components: List[HeavyComponentDescription]
    light_components: List[LightComponentDescription]
    fluids: Dict[str, FluidDescription]
equation_of_state_type: EquationOfStateType⠀
surface_tension_model_type: SurfaceTensionType⠀
viscosity_model: PVTCompositionalViscosityModel⠀
heavy_components:
    - heavy_component_description_schema⠀
light_components:
    - light_component_description_schema⠀
fluids:
    string: fluid_description_schema
class HeavyComponentDescription

Definitions

class HeavyComponentDescription
    name: str
    scn: int
    MW: Scalar⠀
    rho: Scalar
name: string
scn: number
MW:
    value: number
    unit: string
rho:
    value: number
    unit: string
class LightComponentDescription

Definitions

class LightComponentDescription
    name: str
    Pc: Scalar⠀
    Tc: Scalar⠀
    Vc: Scalar⠀
    omega: Scalar⠀
    MW: Scalar⠀
    Tb: Scalar⠀
    Parachor: Scalar⠀
    B_parameter: Scalar⠀
    Cp_0: Scalar⠀
    Cp_1: Scalar⠀
    Cp_2: Scalar⠀
    Cp_3: Scalar⠀
    Cp_4: Scalar
name: string
Pc:
    value: number
    unit: string
Tc:
    value: number
    unit: string
Vc:
    value: number
    unit: string
omega:
    value: number
    unit: string
MW:
    value: number
    unit: string
Tb:
    value: number
    unit: string
Parachor:
    value: number
    unit: string
B_parameter:
    value: number
    unit: string
Cp_0:
    value: number
    unit: string
Cp_1:
    value: number
    unit: string
Cp_2:
    value: number
    unit: string
Cp_3:
    value: number
    unit: string
Cp_4:
    value: number
    unit: string
class FluidDescription

Definitions

class FluidDescription
    composition: List[CompositionDescription]
    fraction_pairs: List[BipDescription]
composition:
    - composition_description_schema⠀
fraction_pairs:
    - bip_description_schema
class CompositionDescription
Variables

Component (str) –

Name of the component available created on:

PvtModelCompositionalDescription.light_components PvtModelCompositionalDescription.heavy_components

..note:: CompositionDescription can only refer to components created from the same PvtModelCompositionalDescription

Definitions

class CompositionDescription
    component: str
    molar_fraction: Scalar⠀
    reference_enthalpy: Scalar
component: string
molar_fraction:
    value: number
    unit: string
reference_enthalpy:
    value: number
    unit: string
class BipDescription

Definitions

class BipDescription
    component_1: str
    component_2: str
    value: float
component_1: string
component_2: string
value: number

IPR

class IPRModelsDescription
Variables

Union[str, IPRDescription]] tables (Dict[str,) – A dictionary with the name of the IPR and the instance of the IPR Model.

Definitions

class IPRModelsDescription
    linear_models: Dict[str, LinearIPRDescription]
    table_models: Dict[str, TableIPRDescription]
linear_models:
    string: linear_ipr_description_schema⠀
table_models:
    string: table_ipr_description_schema
class LinearIPRDescription

Definitions

class LinearIPRDescription
    well_index_phase: WellIndexPhaseType⠀
    min_pressure_difference: Scalar⠀
    well_index: Scalar
well_index_phase: WellIndexPhaseType⠀
min_pressure_difference:
    value: number
    unit: string
well_index:
    value: number
    unit: string
class TableIPRDescription

Definitions

class TableIPRDescription
    well_index_phase: WellIndexPhaseType⠀
    table: IPRCurveDescription
well_index_phase: WellIndexPhaseType⠀
table: ipr_curve_description_schema
class IPRCurveDescription

Definitions

class IPRCurveDescription
    pressure_difference: Array⠀
    flow_rate: Array
pressure_difference:
    values: [number]
    unit: string
flow_rate:
    values: [number]
    unit: string

Tracer

class TracersDescription

Definitions

class TracersDescription
    constant_coefficients: Dict[str, TracerModelConstantCoefficientsDescription]
constant_coefficients:
    string: tracer_model_constant_coefficients_description_schema
class TracerModelConstantCoefficientsDescription

Definitions

class TracerModelConstantCoefficientsDescription
    partition_coefficients: Dict[str, Scalar]
partition_coefficients:
    string:
        value: number
        unit: string

Initial Conditions

class InitialConditionsDescription

Definitions

class InitialConditionsDescription
    pressures: InitialPressuresDescription⠀
    volume_fractions: InitialVolumeFractionsDescription⠀
    tracers_mass_fractions: InitialTracersMassFractionsDescription⠀
    velocities: InitialVelocitiesDescription⠀
    temperatures: InitialTemperaturesDescription⠀
    fluid: Optional[str]
class InitialPressuresDescription

Definitions

class InitialPressuresDescription
    position_input_type: TableInputType⠀
    table_x: ReferencedPressureContainerDescription⠀
    table_y: ReferencedPressureContainerDescription⠀
    table_length: PressureContainerDescription
class ReferencedPressureContainerDescription

Definitions

class ReferencedPressureContainerDescription
    reference_coordinate: Scalar⠀
    positions: Array⠀
    pressures: Array
reference_coordinate:
    value: number
    unit: string
positions:
    values: [number]
    unit: string
pressures:
    values: [number]
    unit: string
class PressureContainerDescription

Definitions

class PressureContainerDescription
    positions: Array⠀
    pressures: Array
positions:
    values: [number]
    unit: string
pressures:
    values: [number]
    unit: string
class InitialVolumeFractionsDescription

Definitions

class ReferencedVolumeFractionsContainerDescription

Definitions

class ReferencedVolumeFractionsContainerDescription
    reference_coordinate: Scalar⠀
    positions: Array⠀
    fractions: Dict[str, Array]
reference_coordinate:
    value: number
    unit: string
positions:
    values: [number]
    unit: string
fractions:
    string:
        values: [number]
        unit: string
class VolumeFractionsContainerDescription

Definitions

class VolumeFractionsContainerDescription
    positions: Array⠀
    fractions: Dict[str, Array]
positions:
    values: [number]
    unit: string
fractions:
    string:
        values: [number]
        unit: string
class InitialTracersMassFractionsDescription

Definitions

class ReferencedTracersMassFractionsContainerDescription

Definitions

class ReferencedTracersMassFractionsContainerDescription
    reference_coordinate: Scalar⠀
    positions: Array⠀
    tracers_mass_fractions: List[Array]
reference_coordinate:
    value: number
    unit: string
positions:
    values: [number]
    unit: string
tracers_mass_fractions:
    - Array
class TracersMassFractionsContainerDescription

Definitions

class TracersMassFractionsContainerDescription
    positions: Array⠀
    tracers_mass_fractions: List[Array]
positions:
    values: [number]
    unit: string
tracers_mass_fractions:
    - Array
class InitialVelocitiesDescription

Definitions

class InitialVelocitiesDescription
    position_input_type: TableInputType⠀
    table_x: ReferencedVelocitiesContainerDescription⠀
    table_y: ReferencedVelocitiesContainerDescription⠀
    table_length: VelocitiesContainerDescription
class ReferencedVelocitiesContainerDescription

Definitions

class ReferencedVelocitiesContainerDescription
    reference_coordinate: Scalar⠀
    positions: Array⠀
    velocities: Dict[str, Array]
reference_coordinate:
    value: number
    unit: string
positions:
    values: [number]
    unit: string
velocities:
    string:
        values: [number]
        unit: string
class VelocitiesContainerDescription

Definitions

class VelocitiesContainerDescription
    positions: Array⠀
    velocities: Dict[str, Array]
positions:
    values: [number]
    unit: string
velocities:
    string:
        values: [number]
        unit: string
class InitialTemperaturesDescription

Definitions

class InitialTemperaturesDescription
    position_input_type: TableInputType⠀
    table_x: ReferencedTemperaturesContainerDescription⠀
    table_y: ReferencedTemperaturesContainerDescription⠀
    table_length: TemperaturesContainerDescription
class ReferencedTemperaturesContainerDescription

Definitions

class ReferencedTemperaturesContainerDescription
    reference_coordinate: Scalar⠀
    positions: Array⠀
    temperatures: Array
reference_coordinate:
    value: number
    unit: string
positions:
    values: [number]
    unit: string
temperatures:
    values: [number]
    unit: string
class TemperaturesContainerDescription

Definitions

class TemperaturesContainerDescription
    positions: Array⠀
    temperatures: Array
positions:
    values: [number]
    unit: string
temperatures:
    values: [number]
    unit: string

Pipe

class PipeDescription

Definitions

class PipeDescription
    name: str
    source: str
    target: str
    source_port: Optional[WellConnectionPort⠀]
    target_port: Optional[WellConnectionPort⠀]
    pvt_model: Optional[str]
    profile: ProfileDescription⠀
    equipment: EquipmentDescription⠀
    environment: EnvironmentDescription⠀
    segments: PipeSegmentsDescription⠀
    initial_conditions: InitialConditionsDescription
name: string
source: string
target: string
source_port: well_connection_port_schema⠀  # optional
target_port: well_connection_port_schema⠀  # optional
pvt_model: string    # optional
profile: profile_description_schema⠀
equipment: equipment_description_schema⠀
environment: environment_description_schema⠀
segments: pipe_segments_description_schema⠀
initial_conditions: initial_conditions_description_schema
class PipeSegmentsDescription

Definitions

class PipeSegmentsDescription
    start_positions: Array⠀
    diameters: Array⠀
    roughnesses: Array⠀
    wall_names: Optional[List[str]]
start_positions:
    values: [number]
    unit: string
diameters:
    values: [number]
    unit: string
roughnesses:
    values: [number]
    unit: string
wall_names:     # optional
    - str

Node

class NodeDescription

Definitions

class NodeDescription
    name: str
    node_type: NodeCellType⠀
    pvt_model: Optional[str]
    pressure_properties: PressureNodePropertiesDescription⠀
    mass_source_properties: MassSourceNodePropertiesDescription⠀
    internal_properties: InternalNodePropertiesDescription⠀
    separator_properties: SeparatorNodePropertiesDescription
name: string
node_type: NodeCellType⠀
pvt_model: string    # optional
pressure_properties: pressure_node_properties_description_schema⠀
mass_source_properties: mass_source_node_properties_description_schema⠀
internal_properties: internal_node_properties_description_schema⠀
separator_properties: separator_node_properties_description_schema
class PressureNodePropertiesDescription

Definitions

class PressureNodePropertiesDescription
    pressure: Scalar⠀
    temperature: Scalar⠀
    fluid: Optional[str]
    tracer_mass_fraction: Array⠀
    split_type: MassInflowSplitType⠀
    mass_fractions: Dict[str, Scalar]
    volume_fractions: Dict[str, Scalar]
    gas_liquid_ratio: Scalar⠀
    gas_oil_ratio: Scalar⠀
    water_cut: Scalar
pressure:
    value: number
    unit: string
temperature:
    value: number
    unit: string
fluid: string    # optional
tracer_mass_fraction:
    values: [number]
    unit: string
split_type: MassInflowSplitType⠀
mass_fractions:
    string:
        value: number
        unit: string
volume_fractions:
    string:
        value: number
        unit: string
gas_liquid_ratio:
    value: number
    unit: string
gas_oil_ratio:
    value: number
    unit: string
water_cut:
    value: number
    unit: string
class MassSourceNodePropertiesDescription

Definitions

class MassSourceNodePropertiesDescription
    fluid: Optional[str]
    tracer_mass_fraction: Array⠀
    temperature: Scalar⠀
    source_type: MassSourceType⠀
    volumetric_flow_rates_std: Dict[str, Scalar]
    mass_flow_rates: Dict[str, Scalar]
    total_mass_flow_rate: Scalar⠀
    water_cut: Scalar⠀
    gas_oil_ratio: Scalar
fluid: string    # optional
tracer_mass_fraction:
    values: [number]
    unit: string
temperature:
    value: number
    unit: string
source_type: MassSourceType⠀
volumetric_flow_rates_std:
    string:
        value: number
        unit: string
mass_flow_rates:
    string:
        value: number
        unit: string
total_mass_flow_rate:
    value: number
    unit: string
water_cut:
    value: number
    unit: string
gas_oil_ratio:
    value: number
    unit: string
class InternalNodePropertiesDescription

Definitions

class InternalNodePropertiesDescription
    fluid: Optional[str]
fluid: string    # optional
class SeparatorNodePropertiesDescription
Variables

overall_heat_transfer_coefficient

η such that the overall heat transferred to the separator is

Q = η A (T_amb - T_sep)

Definitions

class SeparatorNodePropertiesDescription
    environment_temperature: Scalar⠀
    geometry: SeparatorGeometryType⠀
    length: Scalar⠀
    overall_heat_transfer_coefficient: Scalar⠀
    radius: Scalar⠀
    nozzles: Dict[str, Scalar]
    initial_phase_volume_fractions: Dict[str, Scalar]
environment_temperature:
    value: number
    unit: string
geometry: SeparatorGeometryType⠀
length:
    value: number
    unit: string
overall_heat_transfer_coefficient:
    value: number
    unit: string
radius:
    value: number
    unit: string
nozzles:
    string:
        value: number
        unit: string
initial_phase_volume_fractions:
    string:
        value: number
        unit: string

Well

class WellDescription

Definitions

class WellDescription
    name: str
    pvt_model: Optional[str]
    stagnant_fluid: Optional[str]
    profile: ProfileDescription⠀
    casing: CasingDescription⠀
    annulus: AnnulusDescription⠀
    formation: FormationDescription⠀
    top_node: str
    bottom_node: str
    environment: EnvironmentDescription⠀
    initial_conditions: InitialConditionsDescription⠀
    equipment: EquipmentDescription
name: string
pvt_model: string    # optional
stagnant_fluid: string    # optional
profile: profile_description_schema⠀
casing: casing_description_schema⠀
annulus: annulus_description_schema⠀
formation: formation_description_schema⠀
top_node: string
bottom_node: string
environment: environment_description_schema⠀
initial_conditions: initial_conditions_description_schema⠀
equipment: equipment_description_schema
class CasingDescription

Definitions

class CasingDescription
    casing_sections: List[CasingSectionDescription]
    tubings: List[TubingDescription]
    packers: List[PackerDescription]
    open_holes: List[OpenHoleDescription]
class CasingSectionDescription

Definitions

class CasingSectionDescription
    name: str
    hanger_depth: Scalar⠀
    settings_depth: Scalar⠀
    hole_diameter: Scalar⠀
    outer_diameter: Scalar⠀
    inner_diameter: Scalar⠀
    inner_roughness: Scalar⠀
    material: Optional[str]
    top_of_filler: Scalar⠀
    filler_material: Optional[str]
    material_above_filler: Optional[str]
name: string
hanger_depth:
    value: number
    unit: string
settings_depth:
    value: number
    unit: string
hole_diameter:
    value: number
    unit: string
outer_diameter:
    value: number
    unit: string
inner_diameter:
    value: number
    unit: string
inner_roughness:
    value: number
    unit: string
material: string    # optional
top_of_filler:
    value: number
    unit: string
filler_material: string    # optional
material_above_filler: string    # optional
class TubingDescription

Definitions

class TubingDescription
    name: str
    length: Scalar⠀
    outer_diameter: Scalar⠀
    inner_diameter: Scalar⠀
    inner_roughness: Scalar⠀
    material: Optional[str]
name: string
length:
    value: number
    unit: string
outer_diameter:
    value: number
    unit: string
inner_diameter:
    value: number
    unit: string
inner_roughness:
    value: number
    unit: string
material: string    # optional
class PackerDescription

Definitions

class PackerDescription
    name: str
    position: Scalar⠀
    material_above: Optional[str]
name: string
position:
    value: number
    unit: string
material_above: string    # optional
class OpenHoleDescription

Definitions

class OpenHoleDescription
    name: str
    length: Scalar⠀
    diameter: Scalar⠀
    inner_roughness: Scalar
name: string
length:
    value: number
    unit: string
diameter:
    value: number
    unit: string
inner_roughness:
    value: number
    unit: string
class AnnulusDescription

Definitions

class AnnulusDescription
    has_annulus_flow: bool
    has_annulus_flow: bool
    pvt_model: Optional[str]
    initial_conditions: InitialConditionsDescription⠀
    gas_lift_valve_equipment: Dict[str, GasLiftValveEquipmentDescription]
    top_node: str
has_annulus_flow: boolean
has_annulus_flow: number
pvt_model: string    # optional
initial_conditions: initial_conditions_description_schema⠀
gas_lift_valve_equipment:
    string: gas_lift_valve_equipment_description_schema⠀
top_node: string
class GasLiftValveEquipmentDescription

Definitions

class GasLiftValveEquipmentDescription
    position: Scalar⠀
    diameter: Scalar⠀
    valve_type: ValveType⠀
    delta_p_min: Scalar⠀
    discharge_coeff: Scalar
position:
    value: number
    unit: string
diameter:
    value: number
    unit: string
valve_type: ValveType⠀
delta_p_min:
    value: number
    unit: string
discharge_coeff:
    value: number
    unit: string
class FormationDescription

Definitions

class FormationDescription
    reference_y_coordinate: Scalar⠀
    layers: List[FormationLayerDescription]
reference_y_coordinate:
    value: number
    unit: string
layers:
    - formation_layer_description_schema
class FormationLayerDescription

Definitions

class FormationLayerDescription
    name: str
    start: Scalar⠀
    material: Optional[str]
name: string
start:
    value: number
    unit: string
material: string    # optional

Material

class MaterialDescription

Definitions

class MaterialDescription
    name: str
    material_type: MaterialType⠀
    density: Scalar⠀
    thermal_conductivity: Scalar⠀
    heat_capacity: Scalar⠀
    inner_emissivity: Scalar⠀
    outer_emissivity: Scalar⠀
    expansion: Scalar⠀
    viscosity: Scalar
name: string
material_type: MaterialType⠀
density:
    value: number
    unit: string
thermal_conductivity:
    value: number
    unit: string
heat_capacity:
    value: number
    unit: string
inner_emissivity:
    value: number
    unit: string
outer_emissivity:
    value: number
    unit: string
expansion:
    value: number
    unit: string
viscosity:
    value: number
    unit: string

Wall

class WallDescription

Definitions

class WallDescription
    name: str
    inner_roughness: Scalar⠀
    wall_layer_container: List[WallLayerDescription]
name: string
inner_roughness:
    value: number
    unit: string
wall_layer_container:
    - wall_layer_description_schema
class WallLayerDescription

Used for defining the default walls.

Variables
  • thickness (Scalar) –

  • material_name (str) –

  • has_annulus_flow (bool) –

Definitions

class WallLayerDescription
    thickness: Scalar⠀
    material_name: str
    has_annulus_flow: bool
    has_annulus_flow: bool
thickness:
    value: number
    unit: string
material_name: string
has_annulus_flow: boolean
has_annulus_flow: number

Profile

class ProfileDescription

Describe a pipe by either length and inclination or by X and Y coordinates.

Variables
  • LengthAndElevation (Optional[XAndYDescription]) – A list of points with the length and elevation. The first item MUST always be (0, 0), otherwise a ValueError is raised.

  • XAndY (Optional[LengthAndElevationDescription]) – A list of points (X, Y), describing the coordinates.

Note

x_and_y and length_and_elevation are mutually exclusive.

Definitions

class ProfileDescription
    x_and_y: Optional[XAndYDescription]
    length_and_elevation: Optional[LengthAndElevationDescription]
x_and_y: x_and_y_description_schema⠀  # optional
length_and_elevation: length_and_elevation_description_schema⠀  # optional
class XAndYDescription

Describe a pipe with a sequence of coordinates.

Definitions

class XAndYDescription
    x: Optional[Array]
    y: Optional[Array]
x:     # optional
    values: [number]
    unit: string
y:     # optional
    values: [number]
    unit: string
class LengthAndElevationDescription

Describe a pipe with length and elevation.

Definitions

class LengthAndElevationDescription
    length: Optional[Array]
    elevation: Optional[Array]
length:     # optional
    values: [number]
    unit: string
elevation:     # optional
    values: [number]
    unit: string

Environment

class EnvironmentDescription

Definitions

class EnvironmentDescription
    thermal_model: PipeThermalModelType⠀
    position_input_mode: PipeThermalPositionInput⠀
    reference_y_coordinate: Scalar⠀
    md_properties_table: List[EnvironmentPropertyDescription]
    tvd_properties_table: List[EnvironmentPropertyDescription]
thermal_model: PipeThermalModelType⠀
position_input_mode: PipeThermalPositionInput⠀
reference_y_coordinate:
    value: number
    unit: string
md_properties_table:
    - environment_property_description_schema⠀
tvd_properties_table:
    - environment_property_description_schema
class EnvironmentPropertyDescription

Definitions

class EnvironmentPropertyDescription
    position: Scalar⠀
    temperature: Scalar⠀
    type: PipeEnvironmentHeatTransferCoefficientModelType⠀
    heat_transfer_coefficient: Scalar⠀
    overall_heat_transfer_coefficient: Scalar⠀
    fluid_velocity: Scalar
position:
    value: number
    unit: string
temperature:
    value: number
    unit: string
type: PipeEnvironmentHeatTransferCoefficientModelType⠀
heat_transfer_coefficient:
    value: number
    unit: string
overall_heat_transfer_coefficient:
    value: number
    unit: string
fluid_velocity:
    value: number
    unit: string

Equipments

class EquipmentDescription

Definitions

class EquipmentDescription
    mass_sources: Dict[str, MassSourceEquipmentDescription]
    pumps: Dict[str, PumpEquipmentDescription]
    valves: Dict[str, ValveEquipmentDescription]
    reservoir_inflows: Dict[str, ReservoirInflowEquipmentDescription]
    heat_sources: Dict[str, HeatSourceEquipmentDescription]
    compressors: Dict[str, CompressorEquipmentDescription]
class MassSourceEquipmentDescription

Definitions

class MassSourceEquipmentDescription
    fluid: Optional[str]
    tracer_mass_fraction: Array⠀
    temperature: Scalar⠀
    source_type: MassSourceType⠀
    volumetric_flow_rates_std: Dict[str, Scalar]
    mass_flow_rates: Dict[str, Scalar]
    total_mass_flow_rate: Scalar⠀
    water_cut: Scalar⠀
    gas_oil_ratio: Scalar⠀
    position: Scalar
fluid: string    # optional
tracer_mass_fraction:
    values: [number]
    unit: string
temperature:
    value: number
    unit: string
source_type: MassSourceType⠀
volumetric_flow_rates_std:
    string:
        value: number
        unit: string
mass_flow_rates:
    string:
        value: number
        unit: string
total_mass_flow_rate:
    value: number
    unit: string
water_cut:
    value: number
    unit: string
gas_oil_ratio:
    value: number
    unit: string
position:
    value: number
    unit: string
class PumpEquipmentDescription

Definitions

class PumpEquipmentDescription
    position: Scalar⠀
    type: PumpType⠀
    pressure_boost: Scalar⠀
    thermal_efficiency: Scalar⠀
    table: TablePumpDescription⠀
    speed_curve: SpeedCurveDescription⠀
    speed_curve_interpolation_type: InterpolationType⠀
    flow_direction: FlowDirection
position:
    value: number
    unit: string
type: PumpType⠀
pressure_boost:
    value: number
    unit: string
thermal_efficiency:
    value: number
    unit: string
table: table_pump_description_schema⠀
speed_curve: speed_curve_description_schema⠀
speed_curve_interpolation_type: InterpolationType⠀
flow_direction: FlowDirection
class ValveEquipmentDescription

Definitions

class ValveEquipmentDescription
    position: Scalar⠀
    type: ValveType⠀
    diameter: Scalar⠀
    flow_direction: FlowDirection⠀
    opening_type: ValveOpeningType⠀
    opening: Scalar⠀
    opening_curve_interpolation_type: InterpolationType⠀
    opening_curve: OpeningCurveDescription⠀
    cv_table: CvTableDescription
position:
    value: number
    unit: string
type: ValveType⠀
diameter:
    value: number
    unit: string
flow_direction: FlowDirection⠀
opening_type: ValveOpeningType⠀
opening:
    value: number
    unit: string
opening_curve_interpolation_type: InterpolationType⠀
opening_curve: opening_curve_description_schema⠀
cv_table: cv_table_description_schema
class ReservoirInflowEquipmentDescription

Definitions

class ReservoirInflowEquipmentDescription
    pressure: Scalar⠀
    temperature: Scalar⠀
    fluid: Optional[str]
    tracer_mass_fraction: Array⠀
    split_type: MassInflowSplitType⠀
    mass_fractions: Dict[str, Scalar]
    volume_fractions: Dict[str, Scalar]
    gas_liquid_ratio: Scalar⠀
    gas_oil_ratio: Scalar⠀
    water_cut: Scalar⠀
    start: Scalar⠀
    length: Scalar⠀
    productivity_ipr: Optional[str]
    injectivity_ipr: Optional[str]
pressure:
    value: number
    unit: string
temperature:
    value: number
    unit: string
fluid: string    # optional
tracer_mass_fraction:
    values: [number]
    unit: string
split_type: MassInflowSplitType⠀
mass_fractions:
    string:
        value: number
        unit: string
volume_fractions:
    string:
        value: number
        unit: string
gas_liquid_ratio:
    value: number
    unit: string
gas_oil_ratio:
    value: number
    unit: string
water_cut:
    value: number
    unit: string
start:
    value: number
    unit: string
length:
    value: number
    unit: string
productivity_ipr: string    # optional
injectivity_ipr: string    # optional
class HeatSourceEquipmentDescription

Definitions

class HeatSourceEquipmentDescription
    start: Scalar⠀
    length: Scalar⠀
    power: Scalar
start:
    value: number
    unit: string
length:
    value: number
    unit: string
power:
    value: number
    unit: string
class CompressorEquipmentDescription

Definitions

class CompressorEquipmentDescription
    position: Scalar⠀
    speed_curve: SpeedCurveDescription⠀
    reference_pressure: Scalar⠀
    reference_temperature: Scalar⠀
    constant_speed: Scalar⠀
    compressor_type: CompressorSpeedType⠀
    speed_curve_interpolation_type: InterpolationType⠀
    flow_direction: FlowDirection⠀
    table: CompressorPressureTableDescription
position:
    value: number
    unit: string
speed_curve: speed_curve_description_schema⠀
reference_pressure:
    value: number
    unit: string
reference_temperature:
    value: number
    unit: string
constant_speed:
    value: number
    unit: string
compressor_type: CompressorSpeedType⠀
speed_curve_interpolation_type: InterpolationType⠀
flow_direction: FlowDirection⠀
table: compressor_pressure_table_description_schema
class SpeedCurveDescription

Definitions

class SpeedCurveDescription
    time: Array⠀
    speed: Array
time:
    values: [number]
    unit: string
speed:
    values: [number]
    unit: string
class CompressorPressureTableDescription
Variables

corrected_mass_flow_rate_entries – Equivalent to m * (T/T_ref)**0.5 / (P/P_ref)

Definitions

class CompressorPressureTableDescription
    speed_entries: Array⠀
    corrected_mass_flow_rate_entries: Array⠀
    pressure_ratio_table: Array⠀
    isentropic_efficiency_table: Array
speed_entries:
    values: [number]
    unit: string
corrected_mass_flow_rate_entries:
    values: [number]
    unit: string
pressure_ratio_table:
    values: [number]
    unit: string
isentropic_efficiency_table:
    values: [number]
    unit: string

Tables

class TablePumpDescription

Definitions

class TablePumpDescription
    speeds: Array⠀
    void_fractions: Array⠀
    flow_rates: Array⠀
    pressure_boosts: Array
speeds:
    values: [number]
    unit: string
void_fractions:
    values: [number]
    unit: string
flow_rates:
    values: [number]
    unit: string
pressure_boosts:
    values: [number]
    unit: string
class CvTableDescription

Definitions

class CvTableDescription
    opening: Array⠀
    flow_coefficient: Array
opening:
    values: [number]
    unit: string
flow_coefficient:
    values: [number]
    unit: string
class OpeningCurveDescription

Definitions

class OpeningCurveDescription
    time: Array⠀
    opening: Array
time:
    values: [number]
    unit: string
opening:
    values: [number]
    unit: string

Constants

This page contains the full reference to constants available for ALFAsim-SDK API.

class CompressorSpeedType(value)

An enumeration.

ConstantSpeed = 'constant_speed'
SpeedCurve = 'speed_curve'
class CorrelationPackage(value)

An enumeration.

Glaso = 'pvt_correlation_package_glaso'
Lasater = 'pvt_correlation_package_lasater'
Standing = 'pvt_correlation_package_standing'
VazquezBeggs = 'pvt_correlation_package_vazquez_beggs'
class CorrelationPackageType(value)

An enumeration.

Alfasim = 'correlation_package_alfasim'
Classical = 'correlation_package_classical'
ISDBTests = 'correlation_package_isdb_tests'
class EmulsionModelType(value)

Options for emulsion properties calculation.

Boxall2012 = 'boxall2012'
Brauner2001 = 'brauner2001'
Brinkman1952 = 'brinkman1952'
Brinkman1952AndYeh1964 = 'brinkman1952_and_yeh1964'
Hinze1955 = 'hinze1955'
ModelDefault = 'model_default'
Mooney1951a = 'mooney1951a'
Mooney1951b = 'mooney1951b'
NoModel = 'no_model'
Sleicher1962 = 'sleicher1962'
Taylor1932 = 'taylor1932'
class EnergyModel(value)

Do not rely on the value of this enum, it is used exclusively for backward compatibility

GlobalModel = 'global_model'
LayersModel = 'layers_model'
NoModel = 'no_model'
class EnergyModelPrimaryVariable(value)

Do not rely on the value of this enum, it is used exclusively for backward compatibility

Enthalpy = 'enthalpy'
Temperature = 'temperature'
class EquationOfStateType(value)

An enumeration.

PengRobinson = 'pvt_compositional_peng_robinson'
SoaveRedlichKwong = 'pvt_compositional_soave_redlich_kwong'
class EvaluationStrategyType(value)

An enumeration.

Implicit = 'implicit'
NewtonExplicit = 'newton_explicit'
TimeExplicit = 'time_explicit'
class FlashModel(value)

Do not rely on the value of this enum, it is used exclusively for backward compatibility

HydrocarbonAndWater = 'hydrocarbon_and_water'
HydrocarbonOnly = 'hydrocarbon_only'
class FlowDirection(value)

An enumeration.

Backward = 'backward'
Forward = 'forward'
class HydrodynamicModelType(value)

Informs which base Hydrodynamic model is being used, without any modification from plugins:

TwoFields is valid only for the slug/regime capturing

  • TwoFields - ‘Two-fluid, Regime Capturing (gas-oil)’:

    Two phase (gas and oil) with two fields (continuous gas and continuous oil) using Regime Capturing strategy.

  • FourFields - ‘Multi-field, Unit Cell (gas-oil)’:

    Two phase (gas and oil) with four fields (continuous gas, continuous oil, dispersed gas bubble, and dispersed oil droplet).

  • ThreeLayersGasOilWater - ‘Multi-field, Unit Cell (gas-oil-water), free water’:

    Three phase (gas, oil, and water) with five fields (continuous gas, continuous oil, continuous water, dispersed gas bubble, and dispersed liquid droplet). Water does not disperse in any other phase

  • ThreeLayersSevenFieldsGasOilWater - ‘Multi-field, Unit Cell (gas-oil-water), no liquid-liquid dispersion’:

    Three phase (gas, oil, and water) with seven fields (continuous gas, continuous oil, continuous water, gas in oil, gas in water, oil in gas, and water in gas. There is no dispersion of oil in water and water in oil.

  • ThreeLayersNineFieldsGasOilWater - ‘Multi-field, Unit Cell (gas-oil-water)’:

    Full three phase gas oil water model. Three continuous fields and six dispersed fields.

FiveFieldsCO2 = 'hydrodynamic_model_5_fields_co2'
FiveFieldsSolid = 'hydrodynamic_model_5_fields_solid'
FiveFieldsWater = 'hydrodynamic_model_5_fields_water'
FourFields = 'hydrodynamic_model_4_fields'
ThreeLayersGasOilWater = 'hydrodynamic_model_3_layers_gas_oil_water'
ThreeLayersNineFieldsGasOilWater = 'hydrodynamic_model_3_layers_9_fields_gas_oil_water'
ThreeLayersNoBubbleGasOilWater = 'hydrodynamic_model_3_layers_no_bubble_gas_oil_water'
ThreeLayersSevenFieldsGasOilWater = 'hydrodynamic_model_3_layers_7_fields_gas_oil_water'
ThreeLayersWaterWithCO2 = 'hydrodynamic_model_3_layers_water_with_co2'
TwoFields = 'hydrodynamic_model_2_fields'
class InitialConditionStrategyType(value)

An enumeration.

Constant = 'constant'
Restart = 'restart'
SteadyState = 'steady_state'
class InterpolationType(value)

An enumeration.

Constant = 'constant'
Linear = 'linear'
Quadratic = 'quadratic'
class MassInflowSplitType(value)

PvtUserGorWc is currently only used for GenKey

ConstantMassFraction = 'mass_inflow_split_type_constant_mass_fraction'
ConstantVolumeFraction = 'mass_inflow_split_type_constant_volume_fraction'
Pvt = 'mass_inflow_split_type_pvt'
PvtUserGlrWc = 'mass_inflow_split_type_pvt_user_glr_wc'
PvtUserGorWc = 'mass_inflow_split_type_pvt_user_gor_wc'
class MassSourceType(value)

An enumeration.

AllVolumetricFlowRates = 'mass_source_type_all_volumetric_flow_rates'
FlowRateGasGorWc = 'mass_source_type_flow_rate_gas_gor_wc'
FlowRateOilGorWc = 'mass_source_type_flow_rate_oil_gor_wc'
FlowRateWaterGorWc = 'mass_source_type_flow_rate_water_gor_wc'
MassFlowRates = 'mass_source_type_mass_flow_rates'
TotalMassFlowRatePvtSplit = 'mass_source_type_total_mass_flow_rate_pvt_split'
class MaterialType(value)

An enumeration.

Fluid = 'fluid'
Solid = 'solid'
class NodeCellType(value)

An enumeration.

Internal = 'internal_node'
MassSource = 'mass_source_boundary'
Pressure = 'pressure_boundary'
Separator = 'separator_node'
class NonlinearSolverType(value)

An enumeration.

AlfasimQuasiNewton = 'nonlinear_solver_alfasim_quasi_newton'
NewtonBacktracking = 'nonlinear_solver_newton_backtracking'
NewtonBasic = 'nonlinear_solver_newton_basic'
class OutputAttachmentLocation(value)

Output Attachment Location will tell the location in which this attachment’s data should be retrieved from.

Annulus = 'annulus'
Main = 'main'
class PVTCompositionalViscosityModel(value)

An enumeration.

CorrespondingStatesPrinciple = 'corresponding_states_principle'
LohrenzBrayClark = 'lohrenz_bray_clark'
class PipeEnvironmentHeatTransferCoefficientModelType(value)

An enumeration.

Overall = 'overall_heat_transfer_coefficient_model'
WallsAndAir = 'walls_and_air_heat_transfer_coefficient_model'
WallsAndEnvironment = 'walls_and_environment_heat_transfer_coefficient'
WallsAndWater = 'walls_and_water_heat_transfer_coefficient_model'
class PipeThermalModelType(value)

An enumeration.

AdiabaticWalls = 'adiabatic_walls'
SteadyState = 'steady_state_heat_transfer'
Transient = 'transient_heat_transfer'
class PipeThermalPositionInput(value)

An enumeration.

Md = 'position_by_md'
Tvd = 'position_by_tvd'
class PumpType(value)

An enumeration.

ConstantPressure = 'constant_pressure'
TableInterpolation = 'table_interpolation'
class SeparatorGeometryType(value)

An enumeration.

HorizontalCylinder = 'horizontal_cylinder'
Sphere = 'sphere'
VerticalCylinder = 'vertical_cylinder'
class SimulationModeType(value)

An enumeration.

Default = 'default'
Robust = 'robust'
class SimulationRegimeType(value)

An enumeration.

SteadyState = 'simulation_regime_steady_state'
Transient = 'simulation_regime_transient'
class SolidsModelType(value)

Informs which solid model should be used:

  • NoModel - None:RR

    Without slip velocity and slurry viscosity

  • Mills1985Equilibrium - Mills (1985):

    Employs the equilibrium slip velocity model and the Mills (1985) effective dynamic viscosity expression.

  • Santamaria2010Equilibrium - Santamaría-Holek (2010):

    This model is more appropriate to use when the solid phase has properties similar to or equal to hydrate. It was fitted by Qin et al. (2018) for hydrates.

  • Thomas1965Equilibrium - Thomas (1965):

    Employs the equilibrium slip velocity model and the Thomas (1965) effective dynamic viscosity expression.

Mills1985Equilibrium = 'mills1985_equilibrium'
NoModel = 'no_model'
Santamaria2010Equilibrium = 'santamaria2010_equilibrium'
Thomas1965Equilibrium = 'thomas1965_equilibrium'
class SurfaceTensionType(value)

An enumeration.

Leechien = 'LeeChien'
Schechterguo = 'SchechterGuo'
Weinaugkatz = 'WeinaugKatz'
class TableInputType(value)

Indicates the semantics of a position field

vertical_position: Interpolation will be calculated in relation to the y-axis horizontal_position: Interpolation will be calculated in relation to the x-axis length: Interpolation will be calculated in relation to the pipeline trajectory

horizontal_position = 'horizontal_position'
length = 'length'
vertical_position = 'vertical_position'
class TracerModelType(value)

An enumeration.

Compositional = 'tracer_model_compositional'
Global = 'tracer_model_global'
class ValveOpeningType(value)

An enumeration.

ConstantOpening = 'constant_opening'
TableInterpolation = 'table_interpolation'
class ValveType(value)

An enumeration.

CheckValve = 'check_valve'
ChokeValveWithFlowCoefficient = 'choke_valve_with_flow_coefficient'
PerkinsValve = 'perkins_valve'
class WellConnectionPort(value)

Available ports for connecting to a Well node.

LeftAnnulus = 'left_annulus_port'
RightAnnulus = 'right_annulus_port'
Top = 'port'
class WellIndexPhaseType(value)

An enumeration.

Gas = 'well_index_phase_gas'
Liquid = 'well_index_phase_liquid'
Oil = 'well_index_phase_oil'
Water = 'well_index_phase_water'
EXTRAS_REQUIRED_VERSION_KEY = 'required-alfasim-sdk'

The dict key which identifies the required version of alfasim-sdk for a given plugin

GAS_LAYER = 'gas'

Constant to identify the gas layer

GAS_PHASE = 'gas'

Constant to identify the gas phase

OIL_LAYER = 'oil'

Constant to identify the oil layer

OIL_PHASE = 'oil'

Constant to identify the oil phase

WATER_LAYER = 'water'

Constant to identify the water layer

WATER_PHASE = 'water'

Constant to identify the water phase