User modules

Users may write modules that are found and loaded at run time. One may derive classes from ExternalForce that may be built as dynamic modules that may be loaded and instantiated as needed. Modules are built in the src/user directory. This is accomplished using dynamically loaded (DL) libraries that register themselves on a list of ExternalForce instances that may be instantiated as directed in your configuration file. These new modules have access to the entire phase space for each component. It is the user’s responsibility to not change the phase space in unphysical ways, of course.

We offer two strategies for incorporating your user modules into EXP:

  1. Extend the CMakeLists.txt file in src/user to build and install your source in EXP. You can keep your code private in a local branch or a fork. This is described in Extending below.

  2. Create a private git repository and use the submodule facility in git to build the source and install the source in EXP. This is described in Using a private repo.

Extending src/user

There are only a few steps necessary to put one’s code in the tree:

  1. Write the code (see below for additional details)

  2. Edit CMakeLists.txt. Assume you module is called foo and is implemented in the following source files foo1.cc and foo2.cc. Do the following:

    • Define a new source variable pointing to the source files in the CMakeLists.txt. E.g. set(foo_SRC foo1.cc foo2.cc)

  3. Compile the code

  4. Install the code in the location defined by your configuration

Notes on writing your module

A good place to start is the code already in the src/user directory. The simplest code is UserTest.cc; this does nothing but print messages but illustrates all of the necessary components.

All classes, of course, must derive from ExternalForce. A quick look at src/ExternalForce.H will show that you will need to implement at least the member determine_acceleration_and_potential_thread(). In order to parse command line parameters, you will also need a constructor and initialize() and maybe a destructor.

In addition, there is a mechanism that identifies your new class to EXP. This has two parts. First you must define a C function which constructs an instance of your class and returns a pointer. Using the C calling interface here gets around the problem of name demangling in C++ in using the dynamic linking loader (there may be a more transparent and portable way to do this). You will notice an additional class at the end of the file called proxy. An instance of this simple class is instantiated when the module is loaded (the last line in the file). As a byproduct, a pointer to the function makeTest() is is added to the factory map defined in ExternalForce.H. This function can then be invoked by name in the code to create an instance of your class. Cute trick, eh? You can simply copy this to your own source (changing makerTest to makerFoo or some other unique name).

Using a private repository for your modules

The strategy above describes adding your module directly to the src/user directory. With this workflow, you would keep a personal branch and merge new changes from the main EXP branch as they become available.

We support an additional strategy that allows you to work directly from the main EXP repo without a private local branch or a fork. In this alternative scenario, you would make a private git repository, either on your local machine or git server (e.g. GitHub) and install your repository in the extern/user-modules directory. This steps for this are:

  1. Copy CMakeLists.txt from src/user to your new git repository as a template.

  2. Replace the existing module list and source strings with the source for your new module, just as in the instructions for Step 2 at the top of this section.

  3. git clone your repository into the extern/user-modules directory with your new CMakeLists.txt in the top level of the cloned repository. You may include any number user module code directories into extern/user-modules. Just remember to use unique names for each.

  4. Now, when you build EXP, your private modules will be automatically built for each directory and installed.