# tree_d_3d.kernels.fmm_traverse.fmm_traverse_pyccel

*module*

The Pyccel version (CPU) of the ``fmm_traverse`` kernel of the Barnes-Hut and FMM solvers.

``fmm_traverse_cuda.cu`` next to this file is the CUDA version (GPU) and ``fmm_traverse_numpy.py`` the
version for machines without Pyccel, all with the same arguments; the folder's
``__init__.py`` declares the kernel (see :mod:`tree_d_3d.kernels`). The flat
quadtree is described in :mod:`tree_d_3d.flat_tree`.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/kernels/fmm_traverse/fmm_traverse_pyccel.py#L1-L1)

## tree_d_3d.kernels.fmm_traverse.fmm_traverse_pyccel.fmm_traverse

*function*

```python
def fmm_traverse(node_center: float[:, :], node_half: float[:], node_start: int64[:], node_end: int64[:], node_child: int64[:], theta: float, frontier: int64[:, :], n_frontier: int, next_frontier: int64[:, :], m2l: int64[:, :], p2p: int64[:, :], counts: int64[:]) -> None
```

One generation of the dual-tree traversal, which fills mutual M2L and P2P lists.

Each node pair of ``frontier[:n_frontier]`` becomes an M2L pair (well
separated: (r_a + r_b) < theta d, with r the half-diagonal and d the centre
distance), a P2P pair (adjacent leaves) or the pairs of its children, appended
to ``next_frontier``. Start from the single pair (0, 0) and repeat with the new
frontier until it is empty. ``counts`` holds the numbers of M2L, P2P and next
frontier pairs, and pairs are appended at those positions; ``counts[3]``
becomes -1 if a buffer is too small (pairs that do not fit are counted, not
written, so the counts are the sizes needed).

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/kernels/fmm_traverse/fmm_traverse_pyccel.py#L15-L106)
