Skip to content

mipals/FMM2D.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 wraps the Helmholtz, Laplace and Stokes 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

For a source $y$ and target $x$, let $r_i = x_i - y_i$ and $r = |x-y|$. The Stokeslet $G_{ij}$ and the (Type I) stresslet $T_{ijk}$ (without the $1/2\pi$ scaling) are

$$ G_{ij}(x,y) = \frac{r_i r_j}{2 r^2} - \frac{\delta_{ij}}{2}\log(r), \qquad T_{ijk}(x,y) = -2\frac{r_i r_j r_k}{r^4}. $$

The function stfmm2d computes the velocity $u$ caused by a collection of Stokeslets (strengths $\sigma$) and stresslets (strengths $\mu$, orientations $\nu$)

$$ u_i(x) = \sum_{m} G_{ij}(x,y^{(m)})\sigma^{(m)}_j + \sum_{m} T_{ijk}(x,y^{(m)})\mu^{(m)}_j\nu^{(m)}_k, $$

together with the associated pressure and, optionally, the velocity gradient. When $x = y^{(m)}$ the $m$ th term is dropped from the sum.

Example

using FMM2D

thresh = 1e-8
n = 200
sources = rand(2,n)
stoklet = rand(2,n)            # Stokeslet strengths
strslet = rand(2,n)           # stresslet strengths
strsvec = rand(2,n)           # stresslet orientations

# Source-to-source (velocity, pressure and gradient)
vals = stfmm2d(eps=thresh, sources=sources, stoklet=stoklet,
               strslet=strslet, strsvec=strsvec, ppreg=3)
vals.pot   # velocity
vals.pre   # pressure
vals.grad  # velocity gradient

# Source-to-target
m = 100
targets = rand(2,m)
vals = stfmm2d(eps=thresh, sources=sources, stoklet=stoklet,
               targets=targets, ppregt=1)
vals.pottarg

Related Package

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

About

A Julia interface to the FMM2D library from the Flatiron Institute

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages