Skip to content

Latest commit

 

History

History
132 lines (95 loc) · 5.67 KB

README.md

File metadata and controls

132 lines (95 loc) · 5.67 KB

FMM2D.jl

Build Status Coverage

FMM2D.jl is a Julia interface for computing N-body interactions using the Flatiron Institute's FMM2D library.

Currently, the wrapper only wraps the Helmholtz and Laplace functionalities.

Helmholtz FMM

Let $c_s \in \mathbb{C},\ s = 1,\dots,N$ denote a collection of charge strengths, $v_s \in \mathbb{C},\ s = 1,\dots,N$ denote a collection of dipole strengths, and $d_s\in\mathbb{R}^2,\ s = 1,\dots,N$ denote the corresponding dipole orientation vectors. Furthermore, $k \in \mathbb{C}$ denotes the wave number. The Helmholtz potential $u$ caused by the presence of a collection of $M$ sources ($x_s$) at $N$ target positions ($x_t$) is computed as

$$ u\left(x_t\right) = \sum_{s=1}^{M} c_sH_0^{(1)}(k|x_t - x_s|) - v_sd_s\cdot\nabla H_0^{(1)}(k|x_t - x_s|), \quad t = 1,\dots, N $$

where $H_0^{(1)}$ is the Hankel function of the first kind of order 0. When $x = x_j$ the $j$ th term is dropped from the sum. Performing this summation would scale as $O(NM)$, but using the Flatiron Insitutes Fast Multipole Library a linear scaling of $O((N + M)\text{log}(\varepsilon^{-1}))$ can be achieved with $\varepsilon$ being the desired relative precision. Note that the library also includes the option for computing the gradient and Hessian of the potential.

Example

using FMM2D

# Simple example for the FMM2D Library
thresh = 10.0^(-5)          # Tolerance
zk     = rand(ComplexF64)   # Wavenumber

# Source-to-source
n = 200
sources = rand(2,n)
charges = rand(ComplexF64,n)
pg = 3 # Evaluate potential, gradient, and Hessian at the sources
vals = hfmm2d(eps=thresh,zk=zk,sources=sources,charges=charges,pg=pg)
vals.pot
vals.grad
vals.hess

# Source-to-target
m = 200
targets = rand(2,m)
pgt = 3 # Evaluate potential, gradient, and Hessian at the targets
vals = hfmm2d(targets=targets,eps=thresh,zk=zk,sources=sources,charges=charges,pgt=pgt)
vals.pottarg
vals.gradtarg
vals.hesstarg

Laplace

The Laplace problem in 2D have the following form

$$ u(x) = \sum_{j=1}^{N} \left[c_{j} \text{log}\left(|x-x_{j}|\right) - d_{j}v_{j} \cdot \nabla( \text{log}(|x-x_{j}|) )\right], $$

In the case of complex charges and dipole strengths ($c_j, v_j \in \mathbb{C}^n$) the function call lfmm2d has to be used. In the case of real charges and dipole strengths ($c_j, v_j \in \mathbb{R}^n$) the function call rfmm2d has to be used.

Example

using FMM2D

# Simple example for the FMM2D Library
thresh = 10.0^(-5)          # Tolerance

# Source-to-source
n = 200
sources = rand(2,n)
charges = rand(ComplexF64,n)
dipvecs = randn(2,n)
dipstr = rand(ComplexF64,n)
pg = 3 # Evaluate potential, gradient, and Hessian at the sources
vals = lfmm2d(eps=thresh,sources=sources,charges=charges,dipvecs=dipvecs,dipstr=dipstr,pg=pg)
vals.pot
vals.grad
vals.hess

# Source-to-target
m = 100
targets = rand(2,m)
pgt = 3 # Evaluate potential, gradient, and Hessian at the targets
vals = lfmm2d(targets=targets,eps=thresh,sources=sources,charges=charges,dipvecs=dipvecs,dipstr=dipstr,pgt=pgt)
vals.pottarg
vals.gradtarg
vals.hesstarg

Stokes

$$ u(x) = \sum_{j=1}^NG^\text{stok}(x,x_j)c_j + d_j\cdot T^\text{stok}(x,x_j)\cdot v_j $$

$$ p(x) = \sum_{j=1}^NP^\text{stok}(x,x_j)c_j + d_j\cdot \Pi^\text{stok}(x,x_j)\cdot v_j^\top $$

Related Package

FMMLIB2D.jl interfaces the FMMLIB2D library which the FMM2D library improves on.