Setting up the Feel++ Environment

1. Introduction

The Feel++ Environment class is the entry point for all Feel++ applications. It handles the initialization and finalization of all required libraries including MPI for parallel computing, PETSc for linear algebra, and logging systems.

The Environment must be created in your main() function and will exist for the entire lifetime of your application.

2. Basic Environment Setup

Let’s start with a minimal example showing how to set up the Feel++ environment:

#include <feel/feel.hpp>

int main( int argc, char* argv[] )
{
    using namespace Feel;

    // Modern Environment initialization with named arguments
    Environment env( _argc=argc, _argv=argv,
                     _about=about( _name="env",
                                   _author="Feel++ Consortium",
                                   _email="feelpp-devel@feelpp.org") );
    
    std::cout << "proc " << Environment::rank()
              << " of " << Environment::numberOfProcessors()
              << std::endl;

    // Print some environment information
    std::cout << "Feel++ version: " << Feel::Info::version() << std::endl;
    std::cout << "Git revision: " << Feel::Info::revision() << std::endl;
    std::cout << "Build id: " << Feel::Info::buildId() << std::endl;
    
    // Display parallel information
    if ( Environment::numberOfProcessors() > 1 )
    {
        std::cout << "Running in parallel with " 
                  << Environment::numberOfProcessors() 
                  << " processes" << std::endl;
    }
    else
    {
        std::cout << "Running in sequential mode" << std::endl;
    }

    // Display repository information
    std::cout << "Repository: " << Environment::repository() << std::endl;
    std::cout << "Config: " << Environment::config() << std::endl;

    return 0;
}

2.1. Key Components

Header Include: Always start by including the main Feel++ header:

#include <feel/feel.hpp>

Environment Creation: The Environment object takes several parameters: - _argc and _argv: Command line arguments - _about: Application metadata including name, author, and contact information

Information Access: The Environment provides access to: - Process rank and total number of processes for MPI parallelism - Feel++ version and build information - Repository paths and configuration details

3. Adding Command Line Options

Feel++ uses the Boost Program Options library to handle command line arguments. Here’s how to add custom options:

po::options_description myoptions( "My application options" );
myoptions.add_options()
    ( "param", po::value<double>()->default_value( 1.0 ), "parameter description" )
    ( "verbose", po::value<bool>()->default_value( false ), "enable verbose output" );

Environment env( _argc=argc, _argv=argv,
                 _desc=myoptions,
                 _about=about( _name="myapp",
                               _author="Your Name",
                               _email="your.email@domain.com") );

Option Access: Use these functions to retrieve option values: - doption("param") for double values - boption("verbose") for boolean values - ioption("count") for integer values - soption("text") for string values

4. Compilation and Execution

4.1. Building Your Application

To compile a Feel++ application, you need to link against the Feel++ libraries. A basic CMake configuration looks like:

cmake_minimum_required(VERSION 3.13)
project(my_feelpp_app)

find_package(feelpp REQUIRED)

add_executable(my_app main.cpp)
target_link_libraries(my_app feelpp)

4.2. Running Your Application

Execute your application with:

./my_app

For parallel execution with MPI:

mpirun -np 4 ./my_app

5. Configuration Files

Feel++ applications can read configuration from .cfg files. The search order is:

  1. Current directory: ./myapp.cfg or ./feelpp_myapp.cfg

  2. User config: $HOME/feelpp/config/

  3. System config: $INSTALL_PREFIX/share/feelpp/config/

5.1. Configuration File Format

Create a file named myapp.cfg:

# Application parameters
param=2.5
verbose=true

# Mesh parameters
gmsh.filename=square.geo
gmsh.hsize=0.1

# Linear solver parameters
ksp-type=cg
pc-type=gamg

5.2. Multiple Configuration Files

You can specify multiple configuration files:

./myapp --config-files base.cfg override.cfg local.cfg

Files are processed in order, with later files overriding earlier ones.

6. Parallel Computing Setup

Feel++ automatically handles MPI initialization through the Environment. Key parallel computing features:

Process Information:

int rank = Environment::rank();                    // Current process rank
int nprocs = Environment::numberOfProcessors();     // Total number of processes
auto worldComm = Environment::worldCommPtr();       // MPI communicator

Conditional Execution:

if ( Environment::isMasterRank() )
{
    std::cout << "This runs only on the master process" << std::endl;
}

7. Repository and Output Organization

Feel++ organizes output files using environment variables:

FEELPP_REPOSITORY: Root directory for results (default: $HOME/feel) FEELPP_WORKDIR: Alternative name for the same directory

Within the repository, files are organized as:

$FEELPP_REPOSITORY/
├── feel/
│   └── myapp/
│       └── np_1/                 # Results for 1 process
│           ├── logs/             # Log files
│           ├── exports/          # Visualization files
│           └── checkpoints/      # Restart files

8. Modern Best Practices

8.1. Use Named Arguments

Modern Feel++ code uses named arguments for clarity:

Environment env( _argc=argc, _argv=argv,
                 _desc=options,
                 _about=about_data );

8.2. Leverage Auto Type Deduction

Use auto for type deduction with Feel++ objects:

auto mesh = loadMesh(_mesh=new Mesh<Simplex<2>>);
auto Vh = Pch<2>(mesh);

8.3. Structure Your Applications

Organize larger applications with clear separation:

int main( int argc, char** argv )
{
    using namespace Feel;

    Environment env( _argc=argc, _argv=argv, /* ... */ );

    // Problem setup
    auto mesh = loadMesh(/*...*/);
    auto Vh = Pch<2>(mesh);

    // Solve problem
    solve_problem(mesh, Vh);

    return 0;
}

This tutorial provides the foundation for all Feel++ applications. The Environment class ensures proper initialization and cleanup of all required libraries and provides access to parallel computing, configuration management, and output organization.

8.4. Minimal Example

Let’s begin with our first program using the Feel++ framework. To start, you include the Feel++ headers.

We use the C++ namespace to avoid Feel:: prefix before Feel++ objects.

We initialize the environment variables through the Feel++ Environment class, which can be found here.

#include <feel/feel.hpp>

int main( int argc, char* argv[] )
{
    using namespace Feel;

    // Modern Environment initialization with named arguments
    Environment env( _argc=argc, _argv=argv,
                     _about=about( _name="env",
                                   _author="Feel++ Consortium",
                                   _email="feelpp-devel@feelpp.org") );
    
    std::cout << "proc " << Environment::rank()
              << " of " << Environment::numberOfProcessors()
              << std::endl;

    // Print some environment information
    std::cout << "Feel++ version: " << Feel::Info::version() << std::endl;
    std::cout << "Git revision: " << Feel::Info::revision() << std::endl;
    std::cout << "Build id: " << Feel::Info::buildId() << std::endl;
    
    // Display parallel information
    if ( Environment::numberOfProcessors() > 1 )
    {
        std::cout << "Running in parallel with " 
                  << Environment::numberOfProcessors() 
                  << " processes" << std::endl;
    }
    else
    {
        std::cout << "Running in sequential mode" << std::endl;
    }

    // Display repository information
    std::cout << "Repository: " << Environment::repository() << std::endl;
    std::cout << "Config: " << Environment::config() << std::endl;

    return 0;
}

and the config file

myapp-solver-type=cg
# myapp-pc-type=ilu

8.5. Adding options

We pass command line options using the Boost Program Options, library using the prefix po:: which is a Feel++ alias for the Boost::program_options namespace. To add a new Feel++ option, we must create a new Feel++ options_description. You must add the default Feel++ options and the new one that we choose here as a double value. Note that the default value will be assigned if not specified by the user.

8.6. Compilation execution and logs

To compile a tutorial, just use the GNU make command.

make feelpp_tut_<appname>

where <appname> is the name of the application you wish to compile (here, myapp). Go to the execution directory as specified in the program, and execute it.You can list the log files created :

ls /tmp/<your login>/feelpp/feelpp_tut_myapp/

If you open one of these log, you should be able to see your value and the processor number used to compute. You can run your application on several processors using MPI :

mpirun -np 2 feelpp_tut_myapp

Note that there will be one log for each processor in that case.

8.7. Config files

A config file can be parsed to the program to profile your options. The default config paths are,

  • current dir

  • $HOME/Feelpp/config/

  • $INSTALL_PREFIX/share/Feelpp/config/

then you have to write inside one of these folders a file called <app_name>.cfg or feelpp_<app_name>.cfg. For example, our myapp.cfg would look like :

value=0.53

Note that you can specify the config file through the option --config-file=<path>

It’s also possible to give several configuration files with the option --config-files <path1> <path2> <path3>

./feelpp_tut_myapp --config-files ex1.cfg ex2.cfg ex3.cfg

In the case where some options are duplicated in the files, the priority is given at the end :

  • ex3.cfg can overwrite options in ex2.cfg and ex1.cfg

  • ex2.cfg can overwrite options in ex1.cfg

All files in --config-files can overwrite options given by --config-file. And all options in the command line can overwrite all options given in cfg files.

8.8. Initializing PETSc, SLEPc and other third party libraries

PETSc is a suite of data structures and routines for the scalable (parallel) solution of scientific applications modeled by partial differential equations. It employs the MPI standard for parallelism.

Feel++ supports the PETSc framework, the Environment takes care of initializing the associated PETSc environment.