Table of Contents


potential - format for (flow) potential (and force field) description (functors)


 #include <potential.>h
 #include <potential_float.h>      /* optional */
 typedef struct {
    string name;
    string pars;
    string file;
    struct a_potential *next;
 } a_potential; 
void inipotential (npar, par, name)
int *npar;          /* number of parameters (I) */double par[];       /* list of
parameters (I/O) */char *name;         /* optional (file) name for data (I)
void potential_double (ndim, pos, acc, pot, time)
const int *ndim;         /* number of dimensions (I) */const double pos[];
     /* position (I) */double acc[], *pot;    /* forces and potential (O) */const
double *time;        /* time (I) */
void potential_float (ndim, pos, acc,
pot, time)
const int *ndim;         /* number of dimensions (I) */const float pos[]; 
    /* position (I) */float acc[], *pot;    /* forces and potential (O) */const
float *time;        /* time (I) */
integer function  inipotential (npar,
par, name)
integer npardouble precision par(*)character name*(*)
integer function potential_double
(ndim, pos, acc, pot, time)
integer ndim     double precision pos(*)double precision acc(*) double
precision potdouble precision time
integer function potential_float (ndim,
pos, acc, pot, time)
integer ndim     real pos(*)real acc(*) real potreal time


potential is a convenient data structure to hold an ascii description of a user selected potential, and all it’s descriptors (id-name, parameters, associated strings/file(s)). It is currently also stored in the orbit(5NEMO) data structure.

potential(5NEMO) is a ’filestructure’ which defines a potential (and force/density or velocity field) through a standardized interface routine, as described in potential(3NEMO) .

A potential(5NEMO) datafile must have two (or three) externally accessible routines inipotential and potential_double and/or potential_flot, (old name:potential) with a parameter sequence as described above. The parameters are all called by reference to allow interfaces with some common but more primitive languages. Notably FORTRAN is now supported in the BSD calling convention of parameters (see potentialf.c). The first parameter, par[0] in C, and par(1) in fortran, is reserved for the pattern speed. User written potentials must take this into account. And return the pattern speed (or it’s default) in that location. If another parameter describes the pattern speed (e.g. the lagrangian radius, as in athan92), inipotential must compute the pattern speed and return it in the first parameter.


The following table lists the non-pattern speed parameters for a few example potentials found in $NEMOOBJ/potential. Note: the pattern speed is not listed here

harmonic    wx,wy,wz    1,1,1
plummer    m,a          1,1
log      mc,rc,q      1,1,1
bar83    fm,fx,ca    1.334697416,8.485281374,0.2
hackforce    tol,eps,rsize,fcells    1,0.025,4,0.75
ccd    Iscale,Xcen,Ycen,Dx,Dy    1,0,0,1,1
A full listing, including their mathematical expression can be found in the NEMO manual, see also $NEMO/text/manuals/,, and of course in $NEMO/src/orbit/potential/data.


Since the later introduction of a third character valued parameter in inipotential() a Fortran-to-C interface cannot be used in as portable a way as before. A small Fortran-to-C interface is however available, but is not guaranteed to work on all machines. Also keep in mind if you write your potentials in fortran: common blocks and other used routines get loaded into the executable, with the potential for duplicate symbol names.

Most likely loadobj(3NEMO) will break under such circumstances.

Second: no I/O should be done. In practise this also means that this third parameter, potfile, of inipotential cannot be used, as is mostly serves as a filename. The reason is that we didn’t want the programs to have to link in huge fortran I/O libraries, including various portability problems.

There is one exception: potlist(1NEMO) is allowed to load potential(5NEMO) files with FORTRAN WRITE statements. After you have made sure the function works as you think, these statements must be Commented out and can then be reloaded by most other potential/orbit programs.

Flow Potentials

Experimental changes to the interface were implemented by the flowcode(1NEMO) and vpotcode(1NEMO) code. This requires special versions of potential desriptors, with the same calling convention but different meaning to the arguments:

flowcode uses a potential which returns the (currently 2-dimensional) velocities at the requested input position. These are returned in the acc slot. The pot has no meaning, though is used to represent densities in programs like mkflowdisk(1NEMO) .

vpotcode uses a potential which expects the velocity to be input in the acc slot, but the returned arguments (acc and pot) have the same meaning. This is to emulate (non-coriolis) forces which depend on velocity.

mkflowdisk initializes a 2D disk based on the flow velocities.

Meridional Plane in Axisymmetric Potentials

A well known fact about meridional motion in an axisymmetric system is that their 3D motion is really a 2D motion in the R-z plane with an effective potential
            Phi +    ------
                     2 * R**2
but unlike motion in rotating potential this requires the authors of potentials to modify their code in something like the following: (pos[0] is R, pos[1] is z, pos[2] is not used)
    double tmp = sqr(ang_mom/pos[0]);
    *pot += 0.5*tmp;
    acc[0] += tmp / pos[0];


The environment variable POTPATH can be used to search for potentials in other than the local directory.


Since the old format did not use _float or _double, there will be some potentials with no _float support, since _double is the default if not present in the symbol table. For C/C++ routines authors are recommended to either split their potential() in a potential_double() and potential_float(), or rename potential() to potential_double() and include <potential_float.h> (available for NEMO 3.2.2 and above) to have _float call _double (the penalty for this is about 4%).

See Also

get_potential(3NEMO) , orbit(5NEMO) , acceleration(5NEMO) , manipulator(5NEMO) , flowcode(1NEMO) , mkflowdisk(1NEMO) , vpotcode(1NEMO)


Peter Teuben


~/src/orbit/potential   potential.c, potential.h potentialf.c
~/text/manuals (latex description)

Update History

13-Jul-87    V1.0: Original created    PJT
8-Apr-88    V2.0: added parameter ’name’ for hackforce    PJT
13-Mar-89    V2.1: added ’name_len’ in case fortran interface    PJT
9-feb-90    V3.0: added time parameter to potential()    PJT
24-may-92    V4.0: documented the new potential struct   PJT
11-oct-93    V5.0: formalized get_pattern    PJT
16-apr-96    documented ’flowcode’ and ’vpotcode’ deviations     PJT
19-sep-01    documented _float/_double                            PJT
19-nov-03    more flow documentation, added mkflowdisk    PJT
19-jul-04    promote acceleration(5)      PJT

Table of Contents