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”.
To add a new potential you have to edit the following two files in the src/ directory:
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!
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:
r
: this is the distance for which the potential functions is evaluated p
: this is the parameter array for the analytic potential. They are passed in the same order as you specify them in your potential file. f
: this is used to return the function value 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); }
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.
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 with adding analytic potentials to potfit, feel free to contact the authors as described here.