Creating an empty simulation function

A simulation function must contain two parts :

These two parts should be developped in the .h and .cpp files. They should be compiled through a makefile.

Note:
An rough simulation function source code can be automatically generated through the OpenFLUID plugin for Eclipse, included in the SDK

Writing the signature

The function signature is a set of information about the content and behaviour of the simulation function. With this information, the OpenFLUID framework can evaluate the simulation function, have information on what it does, and dynamically load it.
The informations included in the signature are :

The signature is declared and implemented in the .h file, and begin with the BEGIN_SIGNATURE_HOOK macro and ends with the END_SIGNATURE_HOOK macro. The minimal signature must include identification information. See part Declaration of the simulation function signature

Writing the derivative class from openfluid::base::PluggableFunction

See Complete example below

Compiling the function

The OpenFLUID simulation functions must be compiled using the gcc C++ compiler (g++) and must be linked to the OpenFLUID libraries.
The "pkg-config openfluid" command gives the correct option to pass to the compiler:

The best way to compile your simulation function is to use the CMake build system, with the CMake configuration files (CMakeLists.txt CMake.in.config) generated by the OpenFLUID plugin for the Eclipse IDE.

Complete example

Example of an empty function (.cpp file and makefile)

.cpp file

#include "openfluid-base.h"
#include "openfluid-core.h"


// =====================================================================
// =====================================================================


DECLARE_PLUGIN_HOOKS;


// =====================================================================
// =====================================================================

BEGIN_SIGNATURE_HOOK
  DECLARE_SIGNATURE_ID("examplefunc");
  DECLARE_SIGNATURE_NAME("Example Function");
  DECLARE_SIGNATURE_DESCRIPTION("");

  DECLARE_SIGNATURE_VERSION("1.0");
  DECLARE_SIGNATURE_SDKVERSION;
  DECLARE_SIGNATURE_STATUS(openfluid::base::EXPERIMENTAL);

  DECLARE_SIGNATURE_DOMAIN("");
  DECLARE_SIGNATURE_PROCESS("");
  DECLARE_SIGNATURE_METHOD("");
  DECLARE_SIGNATURE_AUTHORNAME("");
  DECLARE_SIGNATURE_AUTHOREMAIL("");
END_SIGNATURE_HOOK


// =====================================================================
// =====================================================================


class ExampleFunction : public openfluid::base::PluggableFunction
{
  private:

  public:

    ExampleFunction() : PluggableFunction()
    {
      // here code for constructor
    }

    // =====================================================================

    ~ExampleFunction()
    {
      // here code for destructor
    }

    // =====================================================================
        
    bool initParams(openfluid::core::FuncParamsMap_t Params)
    {
      // here code for function parameters initialization
      return true;
    }

    // =====================================================================
    
    bool prepareData()
    {
      // here code for data preparation befor consistency checking
      return true;
    }
    
    // =====================================================================

    bool checkConsistency()
    {
      // here code for function consistency checking
      return true;
    }

    // =====================================================================

    bool initializeRun(const openfluid::base::SimulationInfo* SimInfo)
    {
      // here code for initialization just before the simulation
      return true;
    }

    // =====================================================================

    bool runStep(const openfluid::base::SimulationStatus* SimStatus)
    {
      // here code for each time step
      return true;
    }

    // =====================================================================    

    bool finalizeRun(const openfluid::base::SimulationInfo* SimInfo)
    {
      // here code for finalization just after the simulation
      return true;
    }

};


// =====================================================================
// =====================================================================


DEFINE_FUNCTION_HOOK(ExampleFunction);

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED (VERSION 2.6)

PROJECT(${FUNC_ID} CXX)

INCLUDE(CMake.in.config)

ENABLE_TESTING()



# =========================================================================
#   checking libraries and tools
# =========================================================================

IF(NOT openfluid_FOUND)
  FIND_PACKAGE(PkgConfig REQUIRED)
  PKG_CHECK_MODULES(openfluid REQUIRED openfluid)
ENDIF(NOT openfluid_FOUND)

IF(NOT NOFUNC2DOC)
  FIND_PACKAGE(LATEX)
ENDIF(NOT NOFUNC2DOC)


# =========================================================================
#   headers dirs for wx and other libraries
# =========================================================================
INCLUDE_DIRECTORIES(${openfluid_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${FUNC_INCLUDE_DIRS})

LINK_DIRECTORIES(${openfluid_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
INCLUDE_DIRECTORIES(${FUNC_LIBRARY_DIRS})


# =========================================================================   
#   process fortran source files if present
# ========================================================================= 

IF(FUNC_FORTRAN)
  ENABLE_LANGUAGE(Fortran)
  SET(CMAKE_Fortran_FLAGS_RELEASE "-funroll-all-loops -fno-f2c -O3")
  SET(FORTRAN_LINK_LIBS "gfortran")
ENDIF(FUNC_FORTRAN)



# =========================================================================
#   function build
# =========================================================================

ADD_LIBRARY(${FUNC_ID} MODULE ${FUNC_CPP} ${FUNC_FORTRAN})
ADD_DEFINITIONS(-DOPENFLUID_VERSION=${openfluid_VERSION})
ADD_DEFINITIONS(${openfluid_CFLAGS})
ADD_DEFINITIONS(${FUNC_DEFINITIONS})
SET_TARGET_PROPERTIES(${FUNC_ID} PROPERTIES PREFIX "" SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}mpi")

IF(MSYS)
  SET_TARGET_PROPERTIES(${FUNC_ID} PROPERTIES LINK_FLAGS "-shared")
ENDIF(MSYS)
  
TARGET_LINK_LIBRARIES(${FUNC_ID} ${openfluid_LIBRARIES} ${Boost_LIBRARIES} ${FORTRAN_LINK_LIBS} ${FUNC_LINK_LIBS})



# =========================================================================
#   function documentation
# =========================================================================

IF(REPOS_NOFUNC2DOC)
 SET(NOFUNC2DOC 1)
ENDIF(REPOS_NOFUNC2DOC)

IF(PDFLATEX_COMPILER AND NOT NOFUNC2DOC)

  LIST(GET FUNC_CPP 0 CPP_FOR_DOC)

  IF(NOT DOCS_OUTPUT_PATH)
    SET(DOCS_OUTPUT_PATH "${PROJECT_BINARY_DIR}")
  ENDIF(NOT DOCS_OUTPUT_PATH)


  IF(NOT FUNC2DOC_TPLFILE)
    SET(FUNC2DOC_TPLFILE "/usr/share/openfluid/func2doc/template/func2doc_tpl.tex")
  ENDIF(NOT FUNC2DOC_TPLFILE)

  # latex command for doc build
  ADD_CUSTOM_COMMAND(
    OUTPUT "${DOCS_OUTPUT_PATH}/${FUNC_ID}.pdf"
    DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${CPP_FOR_DOC}"
    COMMAND "openfluid-engine"
    ARGS "--buddy" "func2doc" "--buddyopts" "inputcpp=${CMAKE_CURRENT_SOURCE_DIR}/${CPP_FOR_DOC},outputdir=${DOCS_OUTPUT_PATH},tplfile=${FUNC2DOC_TPLFILE},pdf=1"     
  )

  ADD_CUSTOM_TARGET(${FUNC_ID}-doc ALL DEPENDS "${DOCS_OUTPUT_PATH}/${FUNC_ID}.pdf")

ENDIF(PDFLATEX_COMPILER AND NOT NOFUNC2DOC)



# =========================================================================
#   function tests
# =========================================================================  

IF(REPOS_BUILD)
  SET(FUNCMPI_DIR ${LIBRARY_OUTPUT_PATH})
  SET(FUNCTEST_OUTPUT_DIR ${REPOS_TESTS_OUTPUTDATA_PATH})
ELSE(REPOS_BUILD)
  SET(FUNCMPI_DIR ${PROJECT_BINARY_DIR})
  SET(FUNCTEST_OUTPUT_DIR ${PROJECT_BINARY_DIR}/tests-output)  
  FILE(MAKE_DIRECTORY "${FUNCTEST_OUTPUT_DIR}")
ENDIF(REPOS_BUILD)

FOREACH(currtest ${TESTS_DATASETS})
  ADD_TEST(${FUNC_ID}-${currtest} "openfluid-engine"
                            "-i" "${CMAKE_CURRENT_SOURCE_DIR}/tests/${currtest}.IN"
                            "-o" "${FUNCTEST_OUTPUT_DIR}/${currtest}.OUT"
                            "-p" "${FUNCMPI_DIR}")
  MESSAGE(STATUS "Added function test ${FUNC_ID}-${currtest}")                            
ENDFOREACH(currtest ${TESTS_DATASETS})



# =========================================================================
#   install directives
# =========================================================================

IF(NOT USER_FUNCTIONS_INSTALL_PATH)
 SET(USER_FUNCTIONS_INSTALL_PATH "$ENV{HOME}/.openfluid/functions")
 IF(WIN32)
   SET(USER_FUNCTIONS_INSTALL_PATH "$ENV{APPDATA}/openfluid/functions") 
 ENDIF(WIN32)
ENDIF(NOT USER_FUNCTIONS_INSTALL_PATH)

IF(REPOS_INSTALL_COMPONENT)
  INSTALL(TARGETS ${FUNC_ID} DESTINATION ${REPOS_FUNCTIONS_INSTALL_PATH} COMPONENT ${REPOS_INSTALL_COMPONENT})
  IF(PDFLATEX_COMPILER AND NOT NOFUNC2DOC)
    INSTALL(FILES "${DOCS_OUTPUT_PATH}/${FUNC_ID}.pdf" DESTINATION ${REPOS_FUNCDOCS_INSTALL_PATH} COMPONENT ${REPOS_INSTALL_COMPONENT})
  ENDIF(PDFLATEX_COMPILER AND NOT NOFUNC2DOC) 
ELSE(REPOS_INSTALL_COMPONENT)
  INSTALL(TARGETS ${FUNC_ID} DESTINATION "${USER_FUNCTIONS_INSTALL_PATH}")
ENDIF(REPOS_INSTALL_COMPONENT) 

CMake.in.config

# function ID
SET(FUNC_ID )

# list of CPP files. the func2doc tag must be contained in the first one
SET(FUNC_CPP )

# list of Fortran files, if any
SET(FUNC_FORTRAN )

# packages to find and/or to check (example below with sqlite3)
#FIND_PACKAGE(PkgConfig REQUIRED)
#PKG_CHECK_MODULES(sqlite3 REQUIRED sqlite3)

# dirs to include for function compilation (example below with sqlite3)
#SET(FUNC_INCLUDE_DIRS ${sqlite3_INCLUDE_DIRS})

# libraries to link for function build (example below with sqlite3)
#SET(FUNC_LINK_LIBS ${sqlite3_LIBRARIES})

# definitions to add at compile time (example below with a test definition)
#SET(FUNC_DEFINITIONS "-Dtestfunc")

# set this if you do not want automatic build of func2doc documentation
#SET(NOFUNC2DOC 1)

# set this if you do want to use a specific func2doc template when using func2doc
#SET(FUNC2DOC_TPLFILE "${CMAKE_CURRENT_SOURCE_DIR}/path/to/template")

# set this if you do want to include tests
#SET(TESTS_DATASETS test01 test02)

Generated using Doxygen 1.6.3
Creative Commons License Creative Commons By-NC-ND license