C interface
The C interface is declared in
include/pvfmm.h
and compiled into libpvfmm. Link with -lpvfmm (see
Installation for the recommended compiler/linker flags).
Note
Every function below has a single-precision twin with suffix F in place of
D and float in place of double in its signature (e.g. PVFMMEvalD /
PVFMMEvalF). Only the D variants are documented here.
Note
The C interface builds with or without MPI. When libpvfmm was built without
MPI, MPI_Comm degenerates to int and all communicator arguments are
ignored (single-process operation). MPI initialization is performed on demand
if the application has not done it already.
For a complete usage example see Using the C and Fortran interfaces.
Kernel selection
-
enum PVFMMKernel
Kernel functions.
Values:
-
enumerator PVFMMLaplacePotential
-
enumerator PVFMMLaplaceGradient
-
enumerator PVFMMStokesPressure
-
enumerator PVFMMStokesVelocity
-
enumerator PVFMMStokesVelocityGrad
-
enumerator PVFMMBiotSavartPotential
-
enumerator PVFMMLaplacePotential
The (source density, target value) dimensions per point for each kernel are listed in Kernel functions. The Helmholtz and Stokes stress kernels are not available through the C interface.
Boundary conditions
See Boundary conditions for semantics.
-
enum PVFMMBoundaryType
Boundary conditions. The values PVFMMBoundaryFreeSpace (0) and PVFMMBoundaryPXYZ (1) coincide with the boolean periodic flag accepted by earlier versions of this interface.
Values:
-
enumerator PVFMMBoundaryFreeSpace
free-space (decaying) boundary conditions
-
enumerator PVFMMBoundaryPXYZ
periodic in x, y, z
-
enumerator PVFMMBoundaryPX
periodic in x; free in y, z
-
enumerator PVFMMBoundaryPXY
periodic in x, y; free in z
-
enumerator PVFMMBoundaryPeriodic
alias for PVFMMBoundaryPXYZ
-
enumerator PVFMMBoundaryFreeSpace
Volume FMM
Typical call sequence: PVFMMCreateVolumeFMMD (build/load translation
operators) and PVFMMCreateVolumeTreeD (discretize the source density), then
PVFMMEvaluateVolumeFMMD, and finally destroy both objects. The expensive
operator construction is cached on disk — see
Precomputed operator files.
-
void *PVFMMCreateVolumeFMMD(int m, int q, enum PVFMMKernel kernel, MPI_Comm comm)
Build FMM translation operators.
- Parameters:
m – [in] the multipole order (positive, even integer).
q – [in] the degree of the Chebyshev polynomials.
kernel – [in] the kernel function.
comm – [in] the MPI communicator.
- Returns:
the volume FMM context pointer.
-
void *PVFMMCreateVolumeTreeD(int cheb_deg, int data_dim, void (*fn_ptr)(const double *coord, long n, double *out, const void *ctx), const void *fn_ctx, const double *trg_coord, long n_trg, MPI_Comm comm, double tol, int max_pts, enum PVFMMBoundaryType bndry, int init_depth)
Construct a piecewise Chebyshev volume discretization in [0,1]^3. It first constructs a uniform tree of depth init_depth and then adaptively refines each leaf node until the tails of the Chebyshev coefficients in each leaf node are smaller than tol and the number of target points in each leaf node are less than max_pts. It further refines the tree to satisfy the 2:1 balance constraint.
- Parameters:
cheb_deg – [in] the degree of the Chebyshev polynomials. The number of coefficients in each leaf node is data_dim*(cheb_deg+1)(cheb_deg+2)(cheb_deg+3)/6.
data_dim – [in] the number of scalar values per point in the evaluation of the input function pointer (fn_ptr).
fn_ptr – [in] the input function pointer.
fn_ctx – [in] a context pointer to be passed to fn_ptr.
trg_coord – [in] the target coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first target point.
n_trg – [in] number of target points.
comm – [in] MPI communicator.
tol – [in] the tolerance for adaptive refinement.
max_pts – [in] the maximum number of target points per leaf node.
bndry – [in] the boundary conditions (see PVFMMBoundaryType).
init_depth – [in] the depth of the initial tree before adaptive refinement. If zero then the depth is the minimum depth so that the number of leaf nodes is greater than the size of the MPI communicator.
- Returns:
the pointer to the constructed tree. It must be destroyed using PVFMMDestroyVolumeTreeD to free the resources.
-
void *PVFMMCreateVolumeTreeFromCoeffD(long Nleaf, int cheb_deg, int data_dim, const double *leaf_coord, const double *fn_coeff, const double *trg_coord, long n_trg, MPI_Comm comm, enum PVFMMBoundaryType bndry)
Construct a piecewise Chebyshev volume discretization in [0,1]^3. It first constructs a tree with the given leaf node coordinates and then adds the Chebyshev coefficient to each leaf node.
- Parameters:
Nleaf – [in] the number of leaf nodes.
cheb_deg – [in] the degree of the Chebyshev polynomials. The number of coefficients in each leaf node is data_dim*(cheb_deg+1)(cheb_deg+2)(cheb_deg+3)/6.
data_dim – [in] the number of scalar values per point in the input density.
leaf_coord – [in] A vector of points [x1 y1 z1 … xn yn zn] where each point corresponds to a leaf node in the tree.
fn_coeff – [in] the vector of Chebyshev coefficients of size Nleaf*data_dim*(cheb_deg+1)(cheb_deg+2)(cheb_deg+3)/6, where Nleaf=leaf_coord.size()/3 is the number of leaf nodes.
trg_coord – [in] the target coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first target point.
n_trg – [in] number of target points.
comm – [in] MPI communicator.
bndry – [in] the boundary conditions (see PVFMMBoundaryType).
- Returns:
the pointer to the constructed tree. It must be destroyed using PVFMMDestroyVolumeTreeD to free the resources.
-
void PVFMMEvaluateVolumeFMMD(double *trg_value, void *tree, const void *fmm, long loc_size)
Run volume FMM and evaluate the result at the target points.
- Parameters:
trg_value – [out] the computed potential at the target points (in array-of-structure order).
tree – [inout] the pointer to the Chebyshev tree.
fmm – [in] the volume FMM context pointer.
loc_size – [in] the local size of the output vector (used to partition it among the MPI ranks).
-
void PVFMMDestroyVolumeFMMD(void **ctx)
Destroy the volume FMM context.
- Parameters:
ctx – [inout] a pointer to pointer to the FMM. The pointer value is set to NULL.
-
void PVFMMDestroyVolumeTreeD(void **ctx)
Destroy the volume FMM tree.
- Parameters:
ctx – [inout] a pointer to pointer to the tree. The pointer value is set to NULL.
Tree data access
-
long PVFMMGetLeafCountD(const void *tree)
Get the number leaf nodes.
- Parameters:
tree – [in] the pointer to the Chebyshev tree.
- Returns:
the number of leaf nodes.
-
void PVFMMGetLeafCoordD(double *leaf_coord, const void *tree)
Get the leaf node coordinates.
- Parameters:
leaf_coord – [out] A vector of points [x1 y1 z1 … xn yn zn] where each point corresponds to a leaf node in the tree.
tree – [in] the pointer to the Chebyshev tree.
-
void PVFMMGetPotentialCoeffD(double *coeff, const void *tree)
Get the Chebyshev coefficients for the potential.
- Parameters:
coeff – [out] the array of Chebyshev coefficients for the potential of size Nleaf*data_dim*(cheb_deg+1)(cheb_deg+2)(cheb_deg+3)/6, where Nleaf is the number of leaf nodes.
tree – [in] the pointer to the Chebyshev tree.
Chebyshev utilities
-
void PVFMMCoeff2NodesD(double *node_val, long Nleaf, int ChebDeg, int dof, const double *coeff)
Evaluate Chebyshev coefficients at tensor product Chebyshev nodes of first kind.
- Parameters:
node_val – [out] the function values at tensor product Chebyshev nodes.
Nleaf – [in] the number of leaf nodes.
ChebDeg – [in] the degree of Chebyshev polynomials.
dof – [in] the number of scalar values at each node point.
coeff – [in] the array of Chebyshev coefficients.
-
void PVFMMNodes2CoeffD(double *coeff, long Nleaf, int ChebDeg, int dof, const double *node_val)
Convert function values on tensor product Chebyshev nodes (first kind nodes) to coefficients.
- Parameters:
coeff – [out] the vector of Chebyshev coefficients.
Nleaf – [in] the number of leaf nodes.
ChebDeg – [in] the degree of Chebyshev polynomials.
dof – [in] the number of scalar values at each node point.
node_val – [in] the function values at tensor product Chebyshev nodes.
Particle FMM
Typical call sequence: PVFMMCreateContextD once, then PVFMMEvalD as
many times as needed (pass setup=1 whenever particle positions changed,
setup=0 if only the densities changed), then PVFMMDestroyContextD.
-
void *PVFMMCreateContextD(double box_size, int n, int m, enum PVFMMKernel kernel, enum PVFMMBoundaryType bndry, MPI_Comm comm)
Create particle FMM context.
- Parameters:
box_size – [in] the domain length; particle coordinates must be in [0, box_size)^3 and box_size is the period along the periodic directions. Must be positive unless bndry is PVFMMBoundaryFreeSpace; if it is non-positive, the (free-space) bounding box is determined from the particle positions.
n – [in] maximum number of points per leaf node.
m – [in] the multipole order (positive, even integer).
kernel – [in] the kernel function.
bndry – [in] the boundary conditions (see PVFMMBoundaryType).
comm – [in] the MPI communicator (e.g. MPI_COMM_WORLD). MPI is initialized on demand if the application has not done so. When the library is built without MPI, the argument is ignored.
- Returns:
the particle FMM context pointer.
-
void PVFMMEvalD(const double *src_pos, const double *sl_den, const double *dl_den, long n_src, const double *trg_pos, double *trg_val, long n_trg, const void *ctx, int setup)
Evaluate the potential at the target points.
- Parameters:
src_pos – [in] the array of source particle positions: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first source point.
sl_den – [in] the array of single-layer source densities with values: [u1 v1 w1 … un vn wn] where (u1 v1 w1) is the density vector for the first particle.
dl_den – [in] the array of double-layer source densities with values: [u1 v1 w1 nx1 ny1 nz1 … un vn wn nxn nyn nzn] where (u1 v1 w1) is the density vector for the first particle and (nx1 ny1 nz1) is the normal vector for the first particle.
n_src – [in] the number of source particles.
trg_pos – [in] the array of target positions with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first target point.
trg_val – [out] the target potential array with values: [p1 q1 r1 … pn qn rn] where (p1 q1 r1) is the potential at the first target point.
n_trg – [in] the number of target particles.
ctx – [in] the particle FMM context pointer.
setup – [in] a flag to indicate if the source or target particle positions have changed and therefore additional setup must be performed.
-
void PVFMMDestroyContextD(void **ctx)
Destroy the particle FMM context.
- Parameters:
ctx – [inout] a pointer to pointer to the FMM context. The pointer value is set to NULL.
C and C++ callers pass their own MPI_Comm (e.g. MPI_COMM_WORLD). Language
bindings that do not link MPI can instead obtain the world communicator from
the library as a Fortran integer handle and pass it to the Fortran entry
points:
-
MPI_Fint PVFMMGetCommWorld(void)
Get the world communicator as a Fortran integer handle (MPI_Comm_c2f(MPI_COMM_WORLD)), initializing MPI on demand.
This is a convenience for language bindings that do not link MPI directly: the returned handle can be passed to the Fortran entry points (pvfmmcreatecontextd_/pvfmmcreatecontextf_) without the binding needing to know the platform representation of MPI_Comm. C/C++ callers that already have MPI_COMM_WORLD do not need this. When the library is built without MPI the return value is a placeholder (0) that the library ignores.
- Returns:
the world communicator as an MPI_Fint handle.