C++ interface

The high-level C++ interface is declared in include/pvfmm.hpp. Everything lives in namespace pvfmm and is templated on the floating-point type Real (float or double). The library core is header-only; programs still link -lpvfmm and its numerical dependencies — use the flags exported in MakeVariables (see Installation).

Communicators are passed as sctl::Comm (from the bundled SCTL library), not raw MPI_Comm. Construct one from an MPI communicator or use the predefined world/self communicators:

sctl::Comm comm(MPI_COMM_WORLD);   // wrap an existing MPI communicator
sctl::Comm comm = sctl::Comm::World();
sctl::Comm comm = sctl::Comm::Self();

Usage walk-throughs: Particle FMM in C++ and Volume FMM in C++.

Kernel functions

A kernel is selected by taking a reference to a pvfmm::Kernel<Real> descriptor from one of the kernel-family structs (see Kernel functions for dimensions and formulas):

const pvfmm::Kernel<double>& kernel_fn = pvfmm::LaplaceKernel<double>::potential();

Family

Members

pvfmm::LaplaceKernel<Real>

potential(), gradient()

pvfmm::StokesKernel<Real>

velocity(), pressure(), stress(), vel_grad()

pvfmm::BiotSavartKernel<Real>

potential()

pvfmm::HelmholtzKernel<Real>

potential()

Boundary conditions

Semantics are described in Boundary conditions.

enum pvfmm::BoundaryType

Values:

enumerator FreeSpace
enumerator PX
enumerator PXY
enumerator PXYZ
enumerator Periodic
enumerator BoundaryTypeCount

Volume FMM

Types

template<class Real>
using pvfmm::ChebFMM_Node = FMM_Node<Cheb_Node<Real>>

Octree node class for volume FMM.

See also

pvfmm::FMM_Node, pvfmm::Cheb_Node

template<class Real>
using pvfmm::ChebFMM = FMM_Cheb<ChebFMM_Node<Real>>

Manages all the translation operators for volume FMM.

See also

pvfmm::FMM_Cheb

template<class Real>
using pvfmm::ChebFMM_Tree = FMM_Tree<ChebFMM<Real>>

The octree class for volume FMM.

See also

pvfmm::FMM_Tree

template<class Real>
using pvfmm::ChebFn = typename ChebFMM_Node<Real>::Function_t

Evaluator function class for input volume density.

See also

pvfmm::Cheb_Node::Function_t

Functions

template<class Real>
ChebFMM_Tree<Real> *pvfmm::ChebFMM_CreateTree(int cheb_deg, int data_dim, ChebFn<Real> fn_ptr, const std::vector<Real> &trg_coord, const sctl::Comm &comm, Real tol = 1e-6, int max_pts = 100, BoundaryType bndry = FreeSpace, int init_depth = 0)

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] 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] number of scalar values per point in the evaluation of the input function pointer (fn_ptr).

  • fn_ptr[in] input function pointer.

  • trg_coord[in] target coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first target point.

  • comm[in] MPI communicator.

  • tol[in] tolerance for adaptive refinement.

  • max_pts[in] maximum number of target points per leaf node.

  • bndry[in] type of boundary conditions (FreeSpace or Periodic)

  • init_depth[in] 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:

pointer to the constructed tree. It must be destroyed using delete to free the resources.

template<class Real>
ChebFMM_Tree<Real> *pvfmm::ChebFMM_CreateTree(int cheb_deg, const std::vector<Real> &leaf_coord, const std::vector<Real> &fn_coeff, const std::vector<Real> &trg_coord, const sctl::Comm &comm, BoundaryType 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:
  • cheb_deg[in] degree of the Chebyshev polynomials.

  • leaf_coord[in] vector of points [x1 y1 z1 … xn yn zn] where each point corresponds to a leaf node in the tree.

  • fn_coeff[in] 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] target coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first target point.

  • comm[in] MPI communicator.

  • bndry[in] type of boundary conditions (FreeSpace or Periodic)

Returns:

pointer to the constructed tree. It must be destroyed using delete to free the resources.

template<class Real>
void pvfmm::ChebFMM_Evaluate(std::vector<Real> &trg_value, ChebFMM_Tree<Real> *tree, size_t loc_size = 0)

Run volume FMM and evaluate the result at the target points.

Note

ChebFMM_Tree::SetupFMM(ChebFMM*) must be called before evaluating FMM for the first time with a tree, or when a tree has changed.

Parameters:
  • trg_value[out] computed potential at the target points (in array-of-structure order).

  • tree[inout] pointer to the Chebyshev tree.

  • loc_size[in] local size of the output vector (used to partition it among the MPI ranks).

template<class Real>
void pvfmm::ChebFMM_GetPotentialCoeff(std::vector<Real> &coeff, const ChebFMM_Tree<Real> *tree)

Get the Chebyshev coefficients for the potential.

Parameters:
  • coeff[out] vector 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] pointer to the Chebyshev tree.

template<class Real>
void pvfmm::ChebFMM_GetLeafCoord(std::vector<Real> &leaf_coord, const ChebFMM_Tree<Real> *tree)

Get the leaf node coordinates.

Parameters:
  • leaf_coord[out] vector of points [x1 y1 z1 … xn yn zn] where each point corresponds to a leaf node in the tree.

  • tree[in] pointer to the Chebyshev tree.

template<class Real>
void pvfmm::ChebFMM_Coeff2Nodes(std::vector<Real> &node_val, int ChebDeg, int dof, const std::vector<Real> &coeff)

Evaluate Chebyshev coefficients at tensor product Chebyshev nodes of first kind.

Parameters:
  • node_val[out] node_val function values at tensor product Chebyshev nodes.

  • ChebDeg[in] degree of Chebyshev polynomials.

  • dof[in] number of scalar values at each node point.

  • coeff[in] vector of Chebyshev coefficients.

template<class Real>
void pvfmm::ChebFMM_Nodes2Coeff(std::vector<Real> &coeff, int ChebDeg, int dof, const std::vector<Real> &node_val)

Convert function values on tensor product Chebyshev nodes (first kind nodes) to coefficients.

Parameters:
  • coeff[out] vector of Chebyshev coefficients.

  • ChebDeg[in] degree of Chebyshev polynomials.

  • dof[in] number of scalar values at each node point.

  • node_val[in] function values at tensor product Chebyshev nodes.

Operator class

The ChebFMM<Real> (i.e. pvfmm::FMM_Cheb) object manages the volume-FMM translation operators; construct it once per (kernel, multipole order, Chebyshev degree) combination and pass it to FMM_Tree::SetupFMM.

template<class FMMNode>
class FMM_Cheb : public pvfmm::FMM_Pts<FMMNode>

Public Functions

void Initialize(int mult_order, int cheb_deg, const sctl::Comm &comm, const Kernel<Real_t> *kernel)

Initialize all the translation matrices (or load from file).

Parameters:
  • mult_order[in] Order of multipole expansion.

  • cheb_deg[in] Degree of Chebyshev polynomials.

  • kernel[in] Kernel functions and related data.

Particle FMM

Types

template<class Real>
using pvfmm::PtFMM = FMM_Pts<FMM_Node<MPI_Node<Real>>>

Manages all the precomputed matrices and implements all the translation operations in FMM. An instance of PtFMM must be created and initialized with the kernel function to be used.

template<class Real>
using pvfmm::PtFMM_Tree = FMM_Tree<PtFMM<Real>>

The FMM tree data structure.

See also

pvfmm::FMM_Tree

template<class Real>
using pvfmm::PtFMM_Node = FMM_Node<MPI_Node<Real>>

The node data structure used in the tree.

See also

pvfmm::FMM_Node, pvfmm::MPI_Node

template<class Real>
using pvfmm::PtFMM_Data = typename PtFMM_Node<Real>::NodeData

The data used to initialize the tree.

See also

pvfmm::FMM_Node::NodeData, pvfmm::MPI_Node::NodeData

Functions

template<class Real>
PtFMM_Tree<Real> *pvfmm::PtFMM_CreateTree(const std::vector<Real> &sl_coord, const std::vector<Real> &sl_density, const std::vector<Real> &dl_coord, const std::vector<Real> &dl_density, const std::vector<Real> &trg_coord, const sctl::Comm &comm, int max_pts = 100, BoundaryType bndry = FreeSpace, int init_depth = 0)

Create a new instance of the tree and return a pointer. The tree must eventually be be destroyed by calling delete.

Parameters:
  • sl_coord[in] single-layer source coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first source point. The coordinates must be in [0,1]^3.

  • sl_density[in] single-layer source density vector with values: [u1 v1 w1 … un vn wn] where (u1 v1 w1) is the density vector for the first particle.

  • dl_coord[in] double-layer source coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first source point. The coordinates must be in [0,1]^3.

  • dl_density[in] double-layer source density vector 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.

  • trg_coord[in] target coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first target point.

  • comm[in] MPI communicator.

  • max_pts[in] maximum number of source points per octant.

  • bndry[in] boundary type (FreeSpace or Periodic)

  • init_depth[in] minimum depth for any octant

template<class Real>
PtFMM_Tree<Real> *pvfmm::PtFMM_CreateTree(const std::vector<Real> &sl_coord, const std::vector<Real> &sl_density, const std::vector<Real> &trg_coord, const sctl::Comm &comm, int max_pts = 100, BoundaryType bndry = FreeSpace, int init_depth = 0)

Create a new instance of the tree and return a pointer. The tree must eventually be be destroyed by calling delete.

Parameters:
  • sl_coord[in] single-layer source coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first source point. The coordinates must be in [0,1]^3.

  • sl_density[in] single-layer source density vector with values: [u1 v1 w1 u2 … un vn wn] where (u1 v1 w1) is the density vector for the first particle.

  • trg_coord[in] target coordinate vector with values: [x1 y1 z1 … xn yn zn] where (x1 y1 z1) are the coordinates of the first target point.

  • comm[in] MPI communicator.

  • max_pts[in] maximum number of source points per octant.

  • bndry[in] boundary type (FreeSpace or Periodic)

  • init_depth[in] minimum depth for any octant.

Returns:

pointer to the constructed tree.

template<class Real>
void pvfmm::PtFMM_Evaluate(const PtFMM_Tree<Real> *tree, std::vector<Real> &trg_val, size_t loc_size = 0, const std::vector<Real> *sl_density = NULL, const std::vector<Real> *dl_density = NULL)

Run FMM on the input octree and return the potential at the target points. The setup function PtFMM_Tree::SetupFMM(PtFMM_Tree* fmm_mat) must be called before evaluating FMM for the first time with a tree, or if a tree has changed.

Note

pvfmm::PtFMM_Tree::SetupFMM(PtFMM*) must be called before evaluating FMM for the first time with a tree, or when a tree has changed.

Parameters:
  • tree[in] pointer to the octree.

  • trg_val[out] target potential vector with values: [p1 q1 r1 … pn qn rn] where (p1 q1 r1) is the potential at the first target point.

  • loc_size[in] number of local target points.

  • sl_density[in] new single-layer source density vector.

  • dl_density[in] new double-layer source density vector.

Operator class

template<class FMMNode>
class FMM_Pts

This class manages all the translation operators for particle FMM.

Subclassed by pvfmm::FMM_Cheb< FMMNode >

Public Functions

void Initialize(int mult_order, const sctl::Comm &comm, const Kernel<Real_t> *kernel)

Initialize all the translation matrices (or load from file).

Parameters:
  • mult_order – [in]: the multipole order to be used (even number 2,4,6,8,10,12)

  • comm – [in]: MPI communicator.

  • kernel – [in]: the kernel function pointer to be used.

Tree evaluation

The tree returned by the *_CreateTree functions is a FMM_Tree<FMM_Mat_t>. In the typical workflow only three members are used directly — SetupFMM (once per tree/operator pairing, or after the tree changed), the *_Evaluate free functions (which call RunFMM internally), and ClearFMMData (before re-evaluating with new source densities):

template<class FMM_Mat_t>
class FMM_Tree : public pvfmm::MPI_Tree<FMM_Mat_t::FMMNode_t>

Base class for FMM tree.

Public Functions

void SetupFMM(FMM_Mat_t *fmm_mat_)

Setup FMM.

void RunFMM()

Run FMM.

void ClearFMMData()

Clear FMM data: multipole, local expansions and target potential.