Adding new Analytic Potential Functions


This page describes how you can add your own analytic potential function to potfit.

First you should choose a unique name for your potential and use it throughout the program to avoid any naming conflicts. In this case we simply call it “my_function”.

Things you need to adjust

To add a new potential you have to edit the following two files in the src/ directory:

functions.itm

This file is used to declare your new potential function. The only thing you have do is add a new line anywhere which uses the FUNCTION macro. The macro takes two arguments, the first one being the name of your function and the second one being the number of parameters the function requires.

For our example function “my_function”, which takes 3 arguments, we would add this

FUNCTION(my_function, 3);

Please note that there are no quotes around the function name!

functions_impl.c

The actual definition of your potential function goes into this file. Just add it at the very end of the file if you are not sure where you should put it.

The name of the function is the same as from the FUNCTION macro but with “_value” added at the end. For our example function “my_function” it might look like this:

void my_function_value(const double r, const double* p, double* f) {
  *f = r * p[[0]] + p[[1]] * sin(r);
}

The parameters passed to this function are:


Detailed Guide

If you are not too familiar with C programming here are some more details which should help you with the process of adding a new analytic potential to potfit.

Copy the following template to the bottom of the functions_impl.c file:

/****************************************************************
 *
 * my_function potential
 *
 ****************************************************************/
 
void my_function_value(const double r, const double* p, double* f)
{
  *f = r + p[[0]] + p[[1]];
}

Now it's time to implement your potential.

Please only change the lines between { and }. You need to know the following things: *f is the value that is returned in the end. So the line beginning with *f = should be your last line of the function. There are two variables passed to your function, the distance r and the parameter array p. You can access them by simply using r for the distance and p[x] for the parameters, where x is a number (starting with 0). The order in which the parameters are passed to this function is the same that you specify them in your potential file.

Assume you would have the following potential:

 type example
 cutoff 4.000000
 alpha 2 0.000000 10.000000
 beta 0.4 0.000000 10.000000
 gamma 7.1 6.000000 8.000000

Then you could access the parameter called alpha as p[0], beta as p[1] and gamma as p[2]. Please note that this is a zero-based array (i.e. the first parameter is p[0] and not p[1]).

Now here's a little example: Suppose we have a potential like

$$\phi(r) = \gamma\exp\left(\frac{-r}{\alpha}\right)\cos\left(\beta r\right)$$

Then our potential function could look like this, assuming the potential file from above is used

void example_value(const double r, const double* p, double* f)
{
  *f = p[[2]] * exp(-r / p[[0]]) * cos(p[[1]] * r);
}

Recompiling the program

If you are finished with all of the above it's time to recompile potfit by simply calling './waf' from the root directoy.

If you encounter any errors be sure to check the syntax of the lines you changed. Usually the compiler will give you some hint what is wrong or where you have to look.

Testing the program

In order to test the changes you made, you can set the parameter opt to 0 in your parameter file. Then run potfit once and the potential will only be evaluated and not optimized. After a successful run you can use the plotfile specified in your parameter file to plot your potential and maybe compare it to your references.

If you still need help

If you still need help with adding analytic potentials to potfit, feel free to contact the authors as described here.