Professional Documents
Culture Documents
Aboria 0.7
Martin Robinson
Copyright © 2015-2018 Martin Robinson
Table of Contents
Abstract
Introduction
Installation and Getting Started
Getting prerequisites
Compiling a program using Aboria
Compiling with Eigen
Compiling with VTK
Compiling with H2Lib
Compiling with OpenMP
Compiling with CUDA
Putting it all together
Particle Container
Creating Particles
Multidimensional Data Types
Working with particles within the container
Internal Data for Variables
Particle's value_type versus reference
Important differences from STL containers
Conversion to VTK formats
Neighbourhood Searching
Cell Lists
Fast Cell-list Neighbour Search
Kd-Trees
Hyper Oct-Tree
Using the spatial data structures
ID Searching
Parallelism in Aboria
OpenMP
CUDA
Evaluating and Solving Kernel Operators with Eigen
Creating Dense Operators
Creating Sparse Operators
Creating Chebyshev Operators
Creating Fast Multipole Method Operators
Creating Hierarchical Matrix Operators
Block Operators
Iterative Solvers
Symbolic Expressions
Setup
Constant Expressions
Univariate Expressions
Bivariate Expressions
Examples
Container/Iterator API
Symbolic API
Kernel Operator API
Benchmarks
Vector Addition
DAXPY
Dense non-linear operator
Neighbour search non-linear operator
API Overview
libaboria
Abstract
Aboria implements an expressive Domain Specifc Language (DSL) in C++ for specifying expressions over particles and their neighbours in
multidimensional space. The library is header-only and based on expression templates for effcient and natural expression of mathematical
expressions applied over the particles.
The particle data is contained in a C++ Standard Template Library (STL) compatible container. Each particle has a n-dimensional position
and user-defned data-package (for other variables such as velocity, density etc) and is optionally embedded within a hypercube spatial
domain (for neighbourhood searches) that can be periodic or not. Users can implement standard C++ and STL algorithms directly on the
particle data, or use the expression template API to naturally form non-linear operators over the particle set.
The motivation behind Aboria is to provide a useful library for implementing particle-based numerical algorithms, for example Molecular
Dynamics, Radial Basis Functions or Smoothed Particle Hydrodynamics.
Aboria is distributed under a BSD 3-Clause License, see LICENCE for more details. Aboria is supported by Maria Bruna's project
"Sustainable software for reactiondiffusion processes of interacting particles", funded by the John Fell Fund (grant BLD10370) and the St
John’s College Research Centre (grant 21138701).
Introduction
Aboria is a C++ library that supports the implementation of particle-based numerical methods. Here we defne a particle-based method as
consisting of three key properties:
1. There exists a set of $N$ particles that have positions within an hypercube of $n$ dimensions. The boundaries of the hypercube can
optionally be periodic.
2. The numerical method in question can be described in terms of non-linear operators on the $N$ particle positions and/or variables
defned at these positions.
3. These operators are defned solely by the particle positions and variables (e.g. neighbourhood interactions), there are no pre-
defned connections or edges between the particles.
Aboria attempts to provide a general purpose library that can be used to support the implementation of particle-based numerical methods.
The idea is to give the user complete control to defne of operators on the particle set, while implementing effciently the diffcult algorithmic
aspects of particle-based methods, such as neighbourhood searches and fast summation algorithms. However, even at this level it is not a
one-fts-all situation and Aboria is designed to allow users to choose specifc algorithms that are best suited to the particular application. For
example, calculating neighbourhood interactions for a uniform particle distribution is best done using a regular cell-list data structure, while
for a highly non-uniform particle distribution a tree data structure like a kd-tree might be preferable . For neighbourhood interactions that are
zero beyond a certain radius, a radial search is the best algorithm to obtain interacting particle pairs, while for interactions that can be
approximated for well-separated clusters of particles, the fast multipole method is an effcient fast summation algorithm.
Design
The diagram below shows the high-level design of Aboria, which consists of three separate and complimentary abstraction levels.
Aboria Level 1
This implements a particle container class which holds the particle data (positions and other user-defned variables). This class is itself
based on the Standard Template Library (STL) vector class (Level 0 in the fgure above ), which serves as the lowest-level data container.
The user can specify the dimension of the particle's position, as well as the variables defned at each particle (velocity, temperature etc.),
and the Level 1 particle set container will combine multiple Level 0 vectors to form a single data structure.
This Level 1 particle set container generally (but not fully) follows the STL specifcation, with its own iterators and traits. It supports
operations to add particles (i.e. the STL push_back member function), remove particles (i.e. erase), and can return a single particle
given an index $i$ (i.e. operator[]). This index operation returns a lightweight type containing references to the corresponding index in
the set of zipped Level 0 vectors. Individual variables can be obtained from this lightweight type via get functions provided by Aboria.
Aboria Level 1 also includes multiple neighbour search classes, which can be used for fast neighbour searches throughout a hypercube
domain with periodic or non-periodic boundaries. The particle set container interacts with a neighbour searching classes to embed the
particles within the domain ensuring that the two data structures are kept in sync, while still allowing for updates to the particles positions
throughout the domain. The current version of the code has four possible neighbour search classes:
1. Two types of cell lists, one supporting serial insertion and parallel queries, the other supporting parallel insertion and queries.
2. A kd-tree, useful for clustered particle distributions and for using Aboria's fast multipole capabilities
3. A hyper oct-tree
Aboria Level 2
This implements neighbourhood searching and fast summation algorithms useful for particle-based methods, using the particle set and
neighbour search classes in Level 1. Currently this includes:
1. Neighbourhood searches using a $p$-norm distance measure, where $p$ can be any integer greater than 0, as well as $p
\rightarrow \infty$ (chebyshev distance)
2. Approximation of kernel operators using interpolation with chebyshev polynomials, the fast multipole method, or hierarchical H2
matrices.
Note that all these algorithms can work with any neighbour search data structure, and in any number of dimensions.
Aboria Level 3
The highest abstraction level in Aboria implements two higher level APIs, suitable for implementing particle-based methods:
1. kernel operators specifed by C++ lambda functions. These can be wrapped in Eigen matrix replacement classes, so they can be
treated as standard matrices, and used in iterative solvers.
2. a Domain Specifc Language (DSL) for specifying non-linear operators on the set of particles, using the Boost.Proto library. Users
can use standard C++ operators (e.g. *, + or /), and/or a set of supplied functions (e.g. sqrt, pow or norm), to express any non-
linear operator over individual particles or particle pairs.
Getting prerequisites
Compiling a program using Aboria
Compiling with Eigen
Compiling with VTK
Compiling with H2Lib
Compiling with OpenMP
Compiling with CUDA
Putting it all together
Getting prerequisites
This software is tested on Ubuntu 14.04LTS with the GCC compiler (version 5.4.1), and Clang compiler (version 3.8.0). See our Travis CI
page for more details.
You will need to install a C++ compiler with C++14 support, and the CMake build software prior to using Aboria, which you can do on a
Debian-based OS using
The only required dependency is the Boost library. Optional dependencies are The Visualization Toolkit , Eigen (version >= 3.3~beta1),
H2Lib, Trust and OpenMP, all of which add extra functionality. To install all these dependencies in a Debian-based OS you can type
Note
replace libvtk5-dev with libvtk6-dev if necessary
Note
If you wish to use H2Lib you will need to download and compile the source manually
#include <Aboria.h>
If you wish to use any of the optional dependencies you will need to install, include and/or link the required library as normal, and defne
one or more of the following compiler defnitions to "turn on" this functionality within Aboria
VTK HAVE_VTK
Eigen HAVE_EIGEN
H2Lib HAVE_H2LIB
Thrust HAVE_THRUST
If you are familiar with compiling C++ projects, this might be all the information you need to incorporate Aboria into your own build system.
If you wish for more details, the following provides a step-by-step guide on compiling your frst Aboria program, using the popular CMake
build system.
Then copy and paste the code below into a C++ source fle named getting_started.cpp.
#include "Aboria.h"
using namespace Aboria;
int main() {
/*
* Create a 2d particle container type with one
* additional variable "velocity", represented
* by a 2d double vector
*/
ABORIA_VARIABLE(velocity, vdouble2, "velocity")
typedef Particles<std::tuple<velocity>, 2> container_t;
typedef typename container_t::position position;
/*
* create a particle set with size N
*/
const int N = 100;
container_t particles(N);
std::uniform_real_distribution<double> uni(0, 1);
std::default_random_engine gen;
for (int i = 0; i < N; ++i) {
/*
* set a random position, and initialise velocity
*/
get<position>(particles)[i] = vdouble2(uni(gen), uni(gen));
get<velocity>(particles)[i] = vdouble2(0, 0);
}
/*
* write particle container to a vtk
* unstructured grid fle
*/
vtkWriteGrid("aboria", 0, particles.get_grid(true));
}
Now copy and paste the CMake confg fle below into another fle called CMakeLists.txt. Note that this assumes that the Aboria
repository is in your current directory, which it will be if you just cloned the repo using the git command above.
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
# Boost
fnd_package(Boost 1.50.0 REQUIRED serialization)
list(APPEND LIBRARIES ${Boost_LIBRARIES})
list(APPEND INCLUDES ${Boost_INCLUDE_DIRS})
# VTK
fnd_package(VTK REQUIRED)
if (VTK_FOUND)
add_defnitions(-DHAVE_VTK)
endif(VTK_FOUND)
list(APPEND LIBRARIES ${VTK_LIBRARIES})
list(APPEND INCLUDES ${VTK_INCLUDE_DIRS})
# Aboria
set(Aboria_LOG_LEVEL 1 CACHE STRING "Logging level (1 = least, 3 = most)")
add_defnitions(-DABORIA_LOG_LEVEL=${Aboria_LOG_LEVEL})
list(APPEND INCLUDES Aboria/src)
list(APPEND INCLUDES Aboria/third-party)
include_directories(src ${INCLUDES})
set(SOURCE
getting_started.cpp
)
add_executable(getting_started ${SOURCE})
target_link_libraries(getting_started ${LIBRARIES})
If you wish to use The Visualisation Toolkit or Eigen with Aboria then you will need to defne the HAVE_VTK and HAVE_EIGEN compiler
defnitions, as done using the above CMakeLists.txt
$ cmake .
$ make
$ ./getting_started
You now should have a fle aboria00000.vtu in your directory, which you can open and view using any application that supports the
VTK unstructured grid format (such as Paraview)
Assuming you are using CMake as per the instructions above, you can include Eigen in the build process by inserting the following into
your CMakeLists.txt
The frst line sets the CMAKE_MODULE_PATH to search in the Aboria cmake directory for additional .cmake fles. This is only necessary if
you don't already have a FindEigen3.cmake module or confg fle on your system and wish to use the one bundled with Aboria.
The most important line for using the Eigen functionality within Aboria is the add_defnitions instruction, which adds the HAVE_EIGEN
compiler defnition. This defnition is used to "turn on" all Eigen functionality within Aboria.
fnd_package(VTK REQUIRED)
add_defnitions(-DHAVE_VTK)
list(APPEND LIBRARIES ${VTK_LIBRARIES})
list(APPEND INCLUDES ${VTK_INCLUDE_DIRS})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/Aboria/cmake"
${CMAKE_MODULE_PATH})
set(H2Lib_ROOT $ENV{HOME}/git/H2Lib)
fnd_package(H2Lib REQUIRED)
list(APPEND LIBRARIES ${H2Lib_LIBRARIES})
list(APPEND INCLUDES ${H2Lib_INCLUDE_DIRS})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}
${H2Lib_LINKER_FLAGS}") add_defnitions(-DHAVE_H2LIB)
To add OpenMP and Thrust to the build process, add the following to your CMakeLists.txt
# OpenMP
fnd_package(OpenMP REQUIRED)
add_defnitions(-DHAVE_OPENMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
# Thrust
fnd_package(Thrust REQUIRED)
add_defnitions(-DHAVE_THRUST)
Caution
This mode is experimental, and has not been thoroughly tested. It is also quite slow, so any pull requests to fx this
are most welcome!
There are a few restrictions on the code that you can write while using the CUDA backend, and these are detailed in
aboria.parallelism_in_aboria.cuda (basically if you are already familiar with Thrust you should be comfortable using the CUDA backend for
Aboria). For now, just copy the following into a getting_started.cu fle
#include "Aboria.h"
using namespace Aboria;
ABORIA_VARIABLE(cu_velocity, vdouble2, "velocity")
int main() {
typedef Particles<std::tuple<cu_velocity>, 2, thrust::device_vector,
CellListOrdered>
cu_container_t;
typedef typename cu_container_t::position cu_position;
/*
* create a particle set with size N
*/
cu_container_t cu_particles(N);
/*
* set a random position
*/
thrust::tabulate(get<cu_position>(cu_particles).begin(),
get<cu_position>(cu_particles).end(),
[] __device__(const int i) {
thrust::default_random_engine gen;
thrust::uniform_real_distribution<foat> uni(0, 1);
gen.discard(i);
return vdouble2(uni(gen), uni(gen));
});
/*
* init velocity
*/
thrust::fll(get<cu_velocity>(cu_particles).begin(),
get<cu_velocity>(cu_particles).end(), vdouble2(0, 0));
/*
* write particle container to a vtk
* unstructured grid fle
*/
vtkWriteGrid("aboria", 0, particles.get_grid(true));
}
To enable the CUDA backend and compile the above source with the CUDA compiler nvcc, add the following to your CMakeLists.txt
fnd_package(CUDA REQUIRED)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/Aboria/cmake"
${CMAKE_MODULE_PATH})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
# Boost
fnd_package(Boost 1.50.0 REQUIRED serialization)
list(APPEND LIBRARIES ${Boost_LIBRARIES})
list(APPEND INCLUDES ${Boost_INCLUDE_DIRS})
# VTK
fnd_package(VTK REQUIRED)
if (VTK_FOUND)
add_defnitions(-DHAVE_VTK)
endif(VTK_FOUND)
list(APPEND LIBRARIES ${VTK_LIBRARIES})
list(APPEND INCLUDES ${VTK_INCLUDE_DIRS})
# H2Lib
set(H2Lib_ROOT $ENV{HOME}/git/H2Lib)
fnd_package(H2Lib REQUIRED)
list(APPEND LIBRARIES ${H2Lib_LIBRARIES})
list(APPEND INCLUDES ${H2Lib_INCLUDE_DIRS})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}
${H2Lib_LINKER_FLAGS}") add_defnitions(-DHAVE_H2LIB)
# OpenMP
fnd_package(OpenMP REQUIRED)
add_defnitions(-DHAVE_OPENMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
# CUDA
fnd_package(CUDA REQUIRED)
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --expt-relaxed-constexpr
--expt-extended-lambda
-std=c++14")
# Thrust
fnd_package(Thrust REQUIRED)
add_defnitions(-DHAVE_THRUST)
# Aboria
set(Aboria_LOG_LEVEL 1 CACHE STRING "Logging level (1 = least, 3 = most)")
add_defnitions(-DABORIA_LOG_LEVEL=${Aboria_LOG_LEVEL})
list(APPEND INCLUDES Aboria/src)
list(APPEND INCLUDES Aboria/third-party)
include_directories(src ${INCLUDES})
set(SOURCE
getting_started.cpp
)
add_executable(getting_started ${SOURCE})
target_link_libraries(getting_started ${LIBRARIES})
set(SOURCE_CU
getting_started.cu
)
cuda_add_executable(getting_started_cu ${SOURCE_CU})
target_link_libraries(getting_started_cu ${LIBRARIES})
Particle Container
Creating Particles
Multidimensional Data Types
Working with particles within the container
Internal Data for Variables
Particle's value_type versus reference
Important differences from STL containers
Conversion to VTK formats
Creating Particles
The main particles data-structure, or container, is called Aboria::Particles. It is templated using a tuple of variable types, explained
below. For example, the following creates a set of particles which each have (along with the standard variables such as position, id etc) a
data package consisting of one double variable type named scalar.
You can set the dimension of the container by using an optional unsigned integer template argument (defaults to 3). For example, if you
wanted a container of particles in 2D space, you would use
If you wanted each particle to have a potential variable held as a double, as well as a velocity variable held as a Aboria::vdouble3
vector class, then you would write the following
Note that there is a special case for boolean variables, which must be represented by an integer, rather than a boolean. This is due to the
STL specialisation of a boolean STL vector, which conficts with the internal design of Aboria. For example, here we can use an 8-bit
unsigned integer to stand in for the boolean fag variable.
You can give the MyParticles constructor a single int argument to initialise the container with n particles:
To create new particles simply use the value_type of the container type. For example, to create a new particle you could write
MyParticles::value_type p;
Each value_type is a tuple of values, of the types specifed by each variable. You can retrieve or set these value using the
Aboria::get function, which is templated on the variable type. For example, say you wanted to set the scalar variable for particle p:
get<scalar>(p) = 1.0;
You can print the value back out, again using the Aboria::get function
std::cout << "the scalar variable equals " << get<scalar>(p) << std::endl;
The value_type of the Particles container also has, a position, a unique id and a boolean fag indicating if this particle is alive or not.
The position type is dependent on the dimension, so the best way is to get the type from the container type, i.e.
Once you are happy with your particle, you can add it to the container using the Aboria::Particles::push_back member function
particles.push_back(p);
There are a number of predefned double, int, and bool vector types, up to dimension 7, and typedefed by the pattern v<type><dim>.
E.g. Aboria::vdouble3, Aboria::vdouble6, Aboria::vint2, Aboria::vbool5...
Note that the index operator Aboria::Particles::operator[] returns a Aboria::Particles::reference, which is defned as a
tuple containing references to each of the variables. This is different from a reference to Aboria::Particles::value_type.
Or you can use the normal STL Aboria::Particles::begin() and Aboria::Particles::end() functions that return random
access iterators to the beginning and end of the container.
Or
Or you can use the STL algorithm for_each. If you are using a GCC compiler, you can turn on the parallel mode to enable this loop to be
run in parallel
Reading the above paragraph, you will note the fundamental difference from normal STL containers, in that value_type& is not the
same as reference. This can be relevant when writing functors for STL algorithms, where you will need to be sure if you need a
value_type& or a reference.
For example, the std::sort algorithm internally stores a value_type of an element which is used in the comparison, so the functor
needs to be equivalent to the following
Which is more effcient than value_type&, since dereferencing the iterator will result in a reference.
Note
Fortunatelly, c++14 makes all this a lot easier, since you can just use the auto keyword and let the compiler
deduce the correct type!
The main differences between Aboria::Particles and normal STL containers are:
2. Additional member functions are available to suit the specifc purpose of this container, for example the push_back function can take a
vector data-type for the particle position, and the get_query function for neighbour searching.
3. When using the neighbourhood searching capabilities of the container, the order of the particles in the particle container might change
due to internal sorting for neighbourhood searching effciency. So do not assume that the particle ordering is fxed. For example, the
push_back member function can reorder the particles if neighbourhood searching is turned on.
"_".
In order to write out the resultant grid to a fle using the VTK data format, Aboria provides a useful helper function
Aboria::vtkWriteGrid, which can write out the grid along with any constant felds (e.g. a timestamp) that you may need. For example,
the following code writes out the entire contents of the the particle set to the fle doc00001.vtu, along with a constant feld named "time"
containing the value 1.0.
Neighbourhood Searching
Cell Lists
Fast Cell-list Neighbour Search
Kd-Trees
Hyper Oct-Tree
The Aboria::Particles container gives you neighbourhood searching functionality, using a variety of spatial data structures as
described below. All these data structure can be used in any number of dimensions, with arbitrary periodicity. Any neighbour search is
performed within a hypercube domain, with extents specifed by the user.
To start with, we will create a particle set in three dimensions (the default) containing a few randomly placed particles
Before you can use the neighbourhood searching, you need to initialise the domain using the
Aboria::Particles::init_neighbour_search function.
In this case, we will initialise a domain from $(-1,-1,-1)$ to $(1,1,1)$, which is periodic in all directions.
Once this is done you can begin using the neighbourhood search queries using the Aboria::euclidean_search function. This returns
an forward-only iterator providing const access to a sequence of particles that lie within a certain distance of a given point. This iterator can
be compared with a boolean to let you know when you have reached that last particle.
For example, the following counts all the particles within a distance radius of the point $(0,0,0)$.
Note that Aboria::euclidean_search uses the euclidean or 2-norm distance ($\sqrt{\sum_i^d x^2}$), but there are other functions for
other distance norms. Aboria::manhatten_search uses the 1-norm ($\sum_i^d |x|$), Aboria::chebyshev_search uses the inf-
norm ($\max_i^d |x|$), and you can use the generic Aboria::distance_search for the $p$-norm ($(\sum_i^d x^n)^{1/n}$), where $p$
is any integer greater than 0.
When dereferenced, the neighbourhood iterator returns a constant reference to the found particle object, with type
Aboria::Particles::const_reference or Aboria::search_iterator::reference. You can also use the function
Aboria::search_iterator::dx() to access a vector $\mathbf{dx}_{ij}$ pointing to the found point from the query point. I.e. if
$\mathbf{x}_i$ is the query point and $\mathbf{x}_j$ is the found point, then $\mathbf{dx}_{ij} = \mathbf{x}_j - \mathbf{x}_i$.
The dx vector is useful for periodic domains, the returned vector $\mathbf{dx}_{ij}$ takes periodic domains into account and returns the
$\mathbf{dx}_{ij}$ with the smallest length.
For example,
Once you start to alter the positions of the particles, you will need to update the neighbourhood data structure that is used for the search.
This is done using the Aboria::Particles::update_positions function. For example, to move all the particles by a random value
and then update the data structure, you would use the following code:
Note: if you did not call update_positions() after the loop, then subsequent neighbour searches would be incorrect
The function Aboria::Particles::update_positions can also take a pair of iterators corresponding to the range of particle
positions you wish to update. For example, if you wish to only move and update a single particle, you could write
Note that this code is valid only for the default Aboria::CellList neighbour data structure (see below), as this is (currently) the only
data structure that does not depend on the specifc ordering of the particles in the particles vector, and thus the only data structure that
can update a single particle independently to the others. The other data structures will generate a run-time error in this case.
You can also use update_positions to delete particles. Any particles with their alive fag set to false will be deleted by the
update_positions function. For example, if you wish to delete all the particles with an x coordinate less than 0 you could write:
If you wish to delete a single particle using the range version of update_positions, then the second iterator you pass to the function
must be the end() iterator of the particles vector. Recall that particles is a vector, and therefore deleting a particle at a given index
in the vector neccessarily moves all the particles after this index
get<alive>(particles)[5] = false;
particles.update_positions(particles.begin() + 5, particles.end());
Cell Lists
There are two cell list data structures within Aboria. Both divide the domain into a regular grid of hypercubes with side length set so that the
average number of particles within each box is close to a given value. Each particle in the container is assigned to the cell that contains its
position, and neighbourhood queries search within that cell and its neighbours within the given radius.
For example, the following diagram illustrates a cell list data structure in two dimensions, shown as a regular array of grey squares each
containing zero or more particles. The user wishes to fnd all the particles within a given euclidean distance around the red point. To
accomplish this query effciently, Aboria would then search all the red-shaded cells for particles that fall within the red circle.
The frst cell list data structure supports serial insertion of particles, and parallel queries. The relevant classes are Aboria::CellList
and Aboria::CellListQuery. This data structure can be selected on a per-particle-set basis, by setting the fourth template argument
for Aboria::Particles. I.e.
You will notice that we also need to specify the vector data structure that the particle container uses, which in this case is a std::vector.
The alternative is a cell-list data structure that supports parallel insertion of points, and parallel queries. This constantly re-orders the
particles in the particle container so that they are sorted into individual cells, so if particles are changing cells often this can be slower. But
theoretically (this hasn't been tested yet) this should speed up neighbourhood search queries as the particles that are local in memory are
also local in space. The relevant classes are Aboria::CellListOrdered and Aboria::CellListOrderedQuery, and you can use
this data structure like so:
Given this assumption, a fast neighbour search would be to simply look in all the possible pairs of neighbouring cells for possible
neighbouring particle pairs. To enable this, Aboria provides the Aboria::get_neighbouring_buckets function, which returns an
iterator that steps through all possible pairs of neighbouring buckets. The user can then iterate over each bucket pair, looping through all
the particle within in bucket using either the Aboria::CellListQuery::get_bucket_particles or
Aboria::CellListOrderedQuery::get_bucket_particles functions. For example, to count up the number of neighbours within a
distance of radius, you might write:
The above code considers particle pairs within neighbouring buckets, but not those within the same bucket. These pairs can be obtained
by simply looping through all the buckets in the cell-list, using the Aboria::CellListQuery::get_subtree or
Aboria::CellListOrderedQuery::get_subtree functions.
For example:
After the code given above, the variable neighbour_count for each particle will contain the number of neighbouring particles around that
particle. Note that this will only be correct if the width of each cell is greater than radius.
Kd-Trees
A kd-tree builds up a hierarchical tree of cells, with only the leaf cells actually containing particles. It is an effcient data structure to use if
you have a high number of dimensions or if your particles are clustered in certain regions of the domain, and so you wish to adapt the size
of your cells with the local particle density.
Each level of the tree divides the cells in the parent level along a certain dimension (the dimension is chosen based on the distribution of
particles within the cell). Any cells that contain a number of particles that is smaller than a given threshold (set in
Aboria::Particles::init_neighbour_search) are marked as leaf cells, and are not divided on subsequent levels.
There are two possible kd-trees in Aboria. The frst is a custom implementation, the second wraps the popular NanoFLANN library
https://github.com/jlblancoc/nanofann. However, Aboria's native neighbourhood queries are used instead of those provided with
NanoFLANN. The NanoFLANN kd-tree is fastest for running in serial (the construction and updates for this data structure are not done in
parallel), where-as the custom kd-tree is best if you are running in parallel, and is the only option if you are using a GPU.
The relevant classes within Aboria are Aboria::Kdtree and Aboria::KdtreeQuery for the custom implementation, and
Aboria::KdtreeNanofann and Aboria::KdtreeNanofannQuery for the NanoFLANN implementation. You can create a particle set
using a kd-tree by setting the Aboria::Particles template arguments accordingly.
or
Hyper Oct-Tree
A hyper oct-tree is a generalisation of an oct-tree (in 3 dimensions) to $N$ dimensions. Is also builds up a hierarchical tree of cells,
however in this case each level of the tree is split along all dimensions, so that each cell has $2^N$ children. Any cells that contain less
that the given number of particles (set in Aboria::Particles::init_neighbour_search) are marked as leaf cells. Empty cells are
included in the data structure, but are ignored by any queries.
For example, the diagram below shows the leaf cells of a hyper oct-tree in 2 dimensions (this is the same as a quad-tree). If the user
wishes to fnd all the particles within a given euclidean distance of the red particle, then Aboria will search through all the red-shaded cells
for matching particles.
The relevant classes within Aboria are Aboria::octtree and Aboria::HyperOctreeQuery. You can create a particle set using a
hyper oct-tree by setting the Aboria::Particles template arguments accordingly.
Aboria uses iterators to provide a generic way to interact with the spatial data structure, so that the code that you write is independent of
the particlular data structure that you use. An iterator is a generic C++ object that "iterates" through a 1D container. For example, the
classic iterator is the loop index i in the code below.
size_t N = 10;
std::vector<double> v(N);
for (size_t i = 0; i < N; ++i) {
v[i] = i;
}
The STL library abstracts away the particular type of i, and defnes a set of iterators for each container. For example, the std::vector
class has its own iterator, which you can use as follows.
size_t index = 0;
for (std::vector<double>::iterator i = v.begin(); i != v.end(); ++i) {
*i = index++;
}
index = 0;
for (auto i = v.begin(); i != v.end(); ++i) {
*i = index++;
}
The iterators in Aboria are similar to STL iterators in that they can step through a given range of objects using the ++ operator, with some
slight differences that we will describe below.
Before we can start using the data structure iterators in Aboria, we need a particle set. Lets create a random set of points in 2D:
N = 100;
typedef Particles<std::tuple<>, 2> Particles_t;
typedef typename Particles_t::position position;
Particles_t particles(N);
std::uniform_real_distribution<double> uniform(0, 1);
for (size_t i = 0; i < N; ++i) {
auto &gen = get<generator>(particles)[i];
get<position>(particles)[i] = vdouble2(uniform(gen), uniform(gen));
}
particles.init_neighbour_search(vdouble2(0, 0), vdouble2(1, 1),
vdouble2(false, false));
In order to start interacting with the spatial data structures, we need to get its query object from the particle set. A query object is a
lightweight object that has all the information neccessary to access either the particle set itself or the underlying spatial data structures. It
was designed because the Aboria::Particles container and the neighbour search classes (e.g. Aboria::NeighbourQueryBase)
were unsuitable for copying to a gpu in order to perform calculations there, so a simpler class, the query class, was created with the
required functionality.
The base class for all the query objects is Aboria::NeighbourQueryBase, and all the query classes for the individual data structures
are derived from this. Now that we have query, we can create a Aboria::NeighbourQueryBase::child_iterator. This is the
lowest level data structure iterator, and allows you to iterate through a set of child nodes attached to a single parent node within a tree
structure.
Note
All the spatial data structures in Aboria are considered trees. For the HyperOctree and kdtree data structures, this
description is obvious, but the cell list is also treated as a tree, in this case a tree with one root node having N
children, where N is the total number of buckets in the cell list.
Note
Aboria tends to use the terms nodes and buckets fairly interchangably.
You can create a child_iterator by using the Aboria::NeighbourQueryBase::get_children function. This creates a child_iterator
that loops through the children of the root node of the tree. We will use this iterator to loop through all these children and print out the
spatial bounds of each node. In order to determine when we have reached the end of the children, we can compare the iterator to false.
This pattern is widely used in Aboria, rather than specifc end iterators as used in the STL.
Above we use the Aboria::NeighbourQueryBase::get_bounds function to get the bounds of the child iterator. This returns a
Aboria::bbox class that contains the minimum and maximum spatial extents of the node pointed to by i.
Note that here we are using the default spatial data structure, a cell list provided by Aboria::CellList, so the "tree" here will only have
2 levels, and the loop above will loop through the second (i.e. non-root) level. We can also create a proper tree structure using the hyper
oct-tree data structure given by Aboria::HyperOctree, like so:
Now particles_octtree contains a full oct-tree, dividing the spatial domain into a hierarchical set of boxes that make up our tree data
structure. The simplest iteration we might want to do on the tree is a depth-frst iteration, which is easiest achieved by recursion. The
Aboria::NeighbourQueryBase::get_children function can be used to get the children of a
Aboria::NeighbourQueryBase::child_iterator, and using a C++ lambda function to provide the recursion we can implement a
depth-frst iteration like so
This construction might be a bit clumsy to use in practice however, so Aboria provides a special depth-frst iterator
Aboria::NeighbourQueryBase::all_iterator to allow you to write a loop equivalent to the recursive depth-frst code given above.
You might also want to distinguish between leaf nodes (nodes with no children) and non-leaf nodes. You can do this with the
Aboria::NeighbourQueryBase::is_leaf_node function, which takes a reference to a node (rather than an iterator), and can be
used like so
Leaf nodes in the tree are the only nodes that contain particles. You can loop through all the particles in a given leaf node using the
Aboria::NeighbourQueryBase::get_bucket_particles function, which returns an iterator. Note for non-leaf nodes, the
Aboria::NeighbourQueryBase::get_bucket_particles will return an iterator that is immediatelly false, so this loop is safe even
for non-leaf nodes.
Aboria also provides functions to query leaf nodes, or buckets, within a certain distance of a point, and these are used internally for the
neighbour search functionality discussed in earlier sections. You can use the
Aboria::NeighbourQueryBase::get_buckets_near_point function, which returns a
Aboria::NeighbourQueryBase::query_iterator of all the buckets with a given distance of a point. This function also takes a
template argument P, which refers to the p-norm distance that it uses (i.e. P=2 is the standard euclidean distance).
Caution
The distance search provided by Aboria::NeighbourQueryBase::get_buckets_near_point does not
respect the periodicity of the domain, so if you did a search near a lhs edge of a periodic domain, it would not pick
up buckets on the neighbouring periodic rhs edge.
const int P = 2;
const vdouble2 search_point = vdouble2(0.5, 0.5);
const double search_radius = 0.1;
std::cout << "searching within " << search_point << " of point "
<< search_point << std::endl;
for (auto i = query_octtree.get_buckets_near_point<P>(search_point,
search_radius);
i != false; ++i) {
auto ci = i.get_child_iterator();
std::cout << "\t found bucket at " << query_octtree.get_bounds(ci)
<< std::endl;
for (auto j = query_octtree.get_bucket_particles(*ci); j != false; ++j) {
std::cout << "\t\t found particle at " << get<position>(*j)
<< std::endl;
}
}
ID Searching
As well as neighbourhood searching, Aboria has functionality to search by each particle's unique id. First, let's create a set of N particles
and randomly rearrange their position in the vector
This will create a set of particles that each have a unique id between 0 and N-1 (but their positions in the vector particles is
randomised). Now, we are going to turn on the id search capability for particles
particles.init_id_search();
Note that each fnd function (e.g. Aboria::CellListQuery::fnd) returns an iterator to the particle set. If we try and search for an id
which doesn't exist, then this iterator will point to the end of the particle vector
Finally, a note on performance: The id search is done by internally creating vectors of id and indicies ordered by id. Keeping these vectors
ordered at each call to Aboria::Particles::update_positions takes O(Nlog(N)). The call to fnd performs a binary search on the
ordered vectors, with takes O(log(N)) time.
Parallelism in Aboria
OpenMP
CUDA
Aboria can use OpenMP or CUDA to utilise multiple cores or Nvidia GPUs that you might have. In general, Aboria uses the parallel
algorithms and vectors provided with Thrust to do this. From there, you can either use Thrust's OpenMP or CUDA backends to provide the
type of parallelism you wish. However, there are a few parts of Aboria that are OpenMP only (notably the entirety of the symbolic and
kernel APIs).
OpenMP
You don't have to do much to start using OpenMP for the high level symbolic or kernel interfaces, all that is required is that you install
OpenMP and Thrust and add the HAVE_THRUST compiler defnition (see aboria.installation_and_getting_started). For lower-level
programming you will need to add a few pragmas to your code, a few examples of which are discussed below.
Now we will loop through the particles and set their initial positions randomly. In order to use an OpenMP parallel for loop, we will stick to a
simple index-based loop for loop to iterate through the particles, like so
Now we can initialise the neighbourhood search data structure. Note that all creation and updates to the spatial data structures are run in
parallel.
Note
currently the only data structure that is created or updated in serial is Aboria::KdtreeNanofann. All the rest are
done in parallel using either OpenMP or CUDA
particles.init_neighbour_search(
vdouble2::Constant(0), vdouble2::Constant(1), vbool2::Constant(false));
We will use Aboria's range search to look for neighbouring pairs within a cutoff, and once again use OpenMPs parallel loop. All queries to
the spatial data structures are thread-safe and can be used in parallel.
++get<neighbour_count>(particles)[i];
}
}
In general, that is 90% of what you need to know, just add a couple of OpenMP pragmas to your loops and you are ready to go!
CUDA
Caution
CUDA support in Aboria is experimental, and is not tested regularly. We welcome feedback by any CUDA users if
anything doesn't work for you
Writing CUDA compatible code is slightly more involved. Aboria uses the Thrust library for CUDA parallism, and follows similar patterns (i.e.
STL-like).
Most importantly, we need to make sure that all the particle data is contained in vectors that are stored on the GPU. To do this we use a
thrust::device_vector as the base storage vector for our particles class
Note
we want to use the type thrust_neighbour_count within a device function, so we need to defne this type
outside any host functions (including main).
Since all our data is on the device, we cannot use raw for loops to access this data without copying it back to the host, an expensive
operation. Instead, Thrust provides a wide variety of parallel algorithms to manipulate the data. Aboria's Aboria::zip_iterator is
compatible with the Thrust framework, so can be used in a similar fashion to Thrust's own zip_iterator (except, unlike Thrust's
zip_iterator, we can take advantage of Aboria's tagged reference and value_types).
We can use Thrust's tabulate algorithm to loop through the particles and set their initial positions randomly.
thrust::tabulate(get<position>(thrust_particles).begin(),
get<position>(thrust_particles).end(),
[] __device__(const int i) {
thrust::default_random_engine gen;
thrust::uniform_real_distribution<foat> uni(0, 1);
gen.discard(i);
return vdouble2(uni(gen), uni(gen));
});
Now we can initialise the neighbourhood search data structure. Note that we are using Aboria::CellListOrdered data structure,
which is similar to Aboria::CellList but instead relies on reordering the particles to arrange them into cells, which is more amenable to
parallelisation using a GPU.
thrust_particles.init_neighbour_search(
vdouble2::Constant(0), vdouble2::Constant(1), vbool2::Constant(false));
We can use any of Aboria's range searches within a Thrust algorithm. Below we will implement a range search around each particle,
counting all neighbours within range. Note that we need to copy all of the variables from the outer scope to the lambda function, since the
lambda will run on the device, and won't be able to access any host memory.
Note
The Aboria::NeighbourQueryBase class for each spatial data structure is designed to be copyable to the GPU,
but the Aboria::Particles class is not, so while the query variable is copyable to the device, the
thrust_particles variable is not.
Note
The type of variable i in the lambda will be deduced as Aboria::Particles::raw_reference. This is different
to Aboria::Particles::reference when using thrust::device_vector, but acts in a similar fashion
thrust::for_each(
thrust_particles.begin(), thrust_particles.end(),
[radius, query = thrust_particles.get_query()] __device__(auto i) {
get<thrust_neighbour_count>(i) = 0;
for (auto j = euclidean_search(query, get<position>(i), radius);
j != false; ++j) {
++get<thrust_neighbour_count>(i);
}
});
While we have exclusively used thrust::for_each above, the iterators that Aboria provides for the Aboria::Particles container
should work with all of Thrust's algorithms. For example, you might wish to restructure the previous code as a transform:
thrust::transform(
thrust_particles.begin(), thrust_particles.end(),
get<thrust_neighbour_count>(thrust_particles).begin(),
[radius, query = thrust_particles.get_query()] __device__(auto i) {
int sum = 0;
for (auto j = euclidean_search(query, get<position>(i), radius);
j != false; ++j) {
++sum;
}
return sum;
});
}
Given that Aboria can describe non-linear operators, this naturally covers linear operators (i.e. matrices) as well. Consider the summation
operator given by the kernel function $K(x_i,x_j)$, over a set of $N$ particles
This is a common enough operator that can be used in many areas. If $K(x_i,x_j) = 1/(x_j-x_i)$, then the operator might be calculating the
force on a set of charged particles via a Coulomb force. If $K(x_i,x_j) = \sqrt{(x_j-x_i)^2 + c^2}$, then the operator might be used for
function interpolation using the multiquadric basis function.
One way to evaluate this operator is to use a matrix to store the values of $K(x_i,x_j)$ for each particle pair, leading to a matrix
$\mathbf{K}$ with storage size $N^2$. Then the summation operator above is equivalent to the matrix-vector product
However, $\mathbf{K}$ could be too large to ft in memory, or the values of $x_i$ and $x_j$ might change too frequently for this to be
useful. Or you may wish to take advantage of the fact that $K(x_i,x_j)$ is a continuous function and use method such as Chebyshev
interpolation or Fast Multipole methods to effciently calculate the action of the operator on the vector $\mathbf{b}$. For any of these
reasons and many others, Aboria can help you out.
Aboria provides functionality to describe linear operators arising from the evaluation of kernel functions at a set of points (i.e. particles in
Aboria's terminology) in $N$ dimensional space. From now on we will refer to these types of operators as kernel operators. To provide
the concept and API of a matrix or linear operator, we will use the C++ linear algebra library Eigen. Aboria provides functionality to wrap
kernel operators as Aboria::MatrixReplacement, so that Eigen can treat them as normal dense or sparse matrices.
1. calculate the action of a kernel operator on a vector (i.e. a matrix-vector multiplication) # use Eigen's iterative solvers to solve a large
linear system of equations arising from a kernel operator.
First we need a particle set to apply the operator to. We will create a particle set containing $N=100$ particles with a single additional
variable $a$.
For convenience, we will also defne a constant reference type to refer to each particle in the container
auto K = create_dense_operator(
particles, particles,
[epsilon](const_particle_reference i, const_particle_reference j) {
const auto dx = get<position>(j) - get<position>(i);
return (get<a>(i) * get<a>(j)) / (dx.norm() + epsilon);
});
Note that Aboria::create_dense_operator takes three arguments. The frst two are particle containers which give the two particle
sets involved in the operator. The frst container holds the particles indexed by $i$ in the kernel function, and the second holds the
particles indexed by $j$. For a matrix representation, you might say that these refer to the rows and columns of the matrix.
The third argument to Aboria::create_dense_operator can be a function object, or C++ lambda expression. Basically any valid C++
object that can be called with two arguments, the frst of type const_particle_reference (i.e. a constant reference to a particle in the
set indexed by $i$), and the second of type const_particle_reference (i.e. a constant reference to a particle in the set indexed by
$j$). Note that in this case the particle sets indexed by $i$ and $j$ is the same particle set particles. However, in other cases you may
want $i$ and $j$ to index different particle sets, in which case the types for arguments 1 and 2 could be different.
In the code above, we are using a lambda expression as our function object, and create one that returns the particular kernel function
$K(\mathbf{x}_i,a_i,\mathbf{x}_j,a_j)$.
Once we have created the operator K, we can use it within Eigen as if it were a normal matrix. For example, to apply K to a vector b, we
could write the following
Note that rather then storing all the values of K that are needed for this summation, Aboria will instead evaluate these values as they are
needed. Therefore the memory requirements are only $\mathcal{O}(N)$, rather than $\mathcal{O}(N^2)$ for a traditional matrix. However,
this requires evaluating the kernel function for each pair of particles at a cost of $\mathcal{O}(N^2)$. If you wish to calculate this operation
approximately, then Aboria can perform the same operation using the Fast Multipole Method or Hierarchical Matrices, please see
subsequent sections for more details on how to do this.
Caution
the Aboria::MatrixReplacement operator K cannot be used, for example, in multiplications or additions with
other Eigen matrices. Thus far, it has only really been tested with matrix-vector multiplication and Eigen's iterative
solvers
If we wish to perform the same operator, but using a traditional matrix, we can use K's Aboria::MatrixReplacement::assemble
member function to fll in a normal Eigen matrix with the values of the kernel function $K(\mathbf{x}_i,a_i,\mathbf{x}_j,a_j)$. This might be
useful if you wish to perform the same operation repeatedly, or in one of Eigen's direct solvers.
Is is common in particle-based methods that the kernel function $K$ be non-zero only for particle pairs separated by less than a certain
radius. In this case we have a summation operation like so
where $K_s$ is a truncated version of $K$ that is only non-zero for $||\mathbf{dx}_{ij}||<r$, where $\mathbf{dx}_{ij}$ is the shortest vector
between particles $i$ and $j$. Note that for non-periodic systems, this will be $\mathbf{dx}_{ij}=\mathbf{x}_j-\mathbf{x}_i$.
Since the summation is only non-zero for $||\mathbf{dx}_{ij}||<r$, we wish to aim for better than $\mathcal{O}(N^2)$ time and combine the
sum with a spatial search of radius $r$.
We can create the operator K_s in Aboria like so (setting $r=0.1$ in this case)
Sparse operators support periodic domains, and therefore we now need the dx argument in the kernel function object. This is a distance
value that gives the shortest vector from particle i to particle j.
When applied to a vector, this operator will use the neighbour search of the particles container to perform a neighbour search for all
particle pairs where $||\mathbf{dx}_{ij}||<r$.
Before we can use this operator, we need to make sure that the neighbour search for particles is initialised. By default, the particle
container was created using three spatial dimensions, so we need to set up a domain from $(0,0,0)$ to $(1,1,1)$ which is not periodic in all
three directions.
Once this is done, we can then apply the operator to the vector b from before
Once again, we can write out K_s to a traditional matrix. This time, we will write out the values of K_s to a sparse matrix, so we can still
obtain an effcient operator
and that we can approximate $K(\mathbf{x}_i,\mathbf{x}_j)$ using interpolation. That is, if $w_l(x)$ denotes a set of interpolating functions,
then
Using this idea, we can use chebyshev interpolation to interpolate $K(\mathbf{x}_i,\mathbf{x}_j)$ at the chebyshev nodes, leading to an
operator that can be applied to a vector at a reduced cost. How reduced depends on the number of chebyshev nodes that are chosen. A
small number of nodes means that the error in the approximation grows, while a larger number of nodes means increased computational
cost.
Note that this idea has been published in the following paper, which was used as a reference for Aboria's implementation:
Fong, William, and Eric Darve. "The black-box fast multipole method." Journal of Computational Physics 228.23 (2009): 8712-8725.
One restriction on the kernel function in this context is that it must be a smooth function of only position. With this in mind, we will defne the
following kernel function
A kernel operator using this function and chebyshev interpolation can be created in Aboria using the
Aboria::create_chebyshev_operator function
where n sets the number of chebyshev nodes in each dimension. Here the function object given to
Aboria::create_chebyshev_operator must have two arguments representing the positions $\mathbf{x}_i$ and $\mathbf{x}_j$.
Caution
Once K_c is created, it assumes that the positions of the particles in particles do not change. If this is not true,
then you can use the function of the underlying kernel class Aboria::KernelChebyshev to update the positions.
Note
Aboria's neighbourhood searching does not need to be initialized in this case, as no neighbourhood queries are
used.
Another powerful class of methods are based on the Fast Multipole Method, which has been also implemented in Aboria. These are valid
for kernel functions with singularities and which boasts $\mathcal{O}(N)$ complexity.
Once again, we will use chebyshev interpolation, but now will construct a tree data structure using one of Aboria's tree data structures (kd-
tree or oct-tree). When the kernel operator is applied to a vector, the fast multiplole algorithm will be invoked, which leads to traversals up
and down the tree, using chebyshev interpolation to compress the kernel function for clusters of particles that are well separated. The
interaction of particle clusters that are not well separated are calculated directly. The details of this are in the following article, which was
used as a reference for Aboria's implementation:
Fong, William, and Eric Darve. "The black-box fast multipole method." Journal of Computational Physics 228.23 (2009): 8712-8725.
A kernel operator using the fast multipole method can be created in Aboria using the Aboria::create_fmm_operator function
});
where n2 sets the number of chebyshev nodes in each dimension. Note that this is typically much less than what is required by the
chebyshev operator discussed in the previous section. Here we need to pass two function objects to Aboria::create_fmm_operator,
both of which represent the kernel applied in different situations. The frst takes two positions that are guarenteed to be not equal, and
which in FMM terminology are used to create the M2L (multipole to local) operators. The second function object takes two particle
references from the row and column particle sets, and is used to create the P2P (particle to particle) operator. Note that the position of i
and j, and/or the particles themselves, might be identical. Therefore this function object must handle any kernel singularities.
Note
the Aboria::create_fmm_operator function creates a kernel operator in which the fast multipole algorithm is
applied completely "on the fy". The fmm can be signifcantly speeded up for static particle positions by storing a
hierarchical matrix. Please see the next section for more details of how to do this in Aboria.
A kernel operator which does this can be created using the Aboria::create_h2_operator function
Block Operators
It is common that you would like to compose operators in a tiled or block format, and Aboria provides a functionality to do this using the
Aboria::create_block_operator.
Let us assume that we wish to compose the two operators K and K_s from before, and want to perform the following combined operator
$$ \begin{align} e_i &= \sum_j^N d_j K_s(\mathbf{x}_i,a_i,\mathbf{x}_j,a_j) \text{ for } i=1...N \\ e_{i+N} &= \sum_j^N d_{j+N}
K(\mathbf{x}_i,a_i,\mathbf{x}_j,a_j) \text{ for } i=1...N \end{align} $$
where $e_i$ and $d_j$ are elements of vectors $\mathbf{e}$ and $\mathbf{d}$ of size $2N$. Using matrix notation, and using $\mathbf{K}$
and $\mathbf{K}_s$ to represent the operators K and K_s, this is equivalent to
We frst need operators representing the zero matrices in the upper right and lower left corners of the block operator. We create these in
Aboria like so
Finally we can create vectors e and d and apply the block operator
Iterative Solvers
The Aboria::MatrixReplacement class can multiply other Eigen vectors, and can be used in Eigen's iterative solvers. Both
Eigen::IdentityPreconditioner and Eigen::DiagonalPreconditioner preconditioners are supported. Below is an example of
how to use Eigen's GMRES iterative solver to solve the equation
We can simply pass the dense operator K to Eigen's GMRES iterative solver like so
Eigen::GMRES<decltype(K), Eigen::DiagonalPreconditioner<double>>
gmres_matrix_free;
gmres_matrix_free.setMaxIterations(2 * N);
gmres_matrix_free.set_restart(2 * N + 1);
gmres_matrix_free.compute(K);
Eigen::VectorXd h_1 = gmres_matrix_free.solve(c_1);
This will solve the equation in a matrix-free fashion. Alternatively, we can use the normal matrix K_eigen that we assembled previously to
solve the equation
Eigen::GMRES<decltype(K_eigen), Eigen::DiagonalPreconditioner<double>>
gmres_matrix;
gmres_matrix.setMaxIterations(2 * N);
gmres_matrix.set_restart(2 * N + 1);
gmres_matrix.compute(K_eigen);
Eigen::VectorXd h_2 = gmres_matrix.solve(c_1);
Symbolic Expressions
Setup
Constant Expressions
Univariate Expressions
Bivariate Expressions
Setup
To start using symbolic expressions, you frst need to defne a set of symbols to represent your variables, as well as labels to represent
your particle set(s).
Symbol<position> p;
Symbol<alive> _alive;
A label representing the particle set particles with type MyParticles is defned as
The frst template argument is the id of the label, and the second is the type of the particle set label refers to. Note that the type of each
label must be unique, as this type is used to determine which particle you mean when using the label within expressions. You can use the
id template argument to ensure that each label type is unique.
Labels refer to a specifc particle set. For example, given a bivariate neighbour expression involving two particles from particles, the
label a defned above would refer to the frst particle, and b would refer to the second. Note that the result values of a bivariate expression
will form a matrix of values, with particle a corresponding to the row of the matrix, and particle b corresponding to the column.
Constant Expressions
Now we have defned our labels and symbols, we can create a simple expression to set the position of all particles to double3(0,0,1)
p[a] += 1;
A special case involves the alive variable fag. If we use our _alive symbol to set all the alive fag's to false like so
_alive[a] = false;
Then after the expression is complete Aboria will call the delete_particles member function to delete all the particles with
get<alive>(particle) == false (i.e. all of them). After this expression the particle container will be empty.
Univariate Expressions
Single-particle dependent expressions can easily be built by using a single label on the RHS of the expression. For example we can also
add a constant value 1 to each particle position like so
p[a] = p[a] + 1;
Or we can use a fag variable fag, along with its symbol f, so defne two sets of particles within the same container and only change the
particle position if get<fag>(particle) == true. Recall that we can't use boolean fags so we can instead use a uint8_t datatype.
For example
ABORIA_VARIABLE(fag,uint8_t,"my fag");
// create particle container and set fags and positions here
Symbol<fag> f;
p[a] = if_else(f[a], p[a] + 1, p[a]);
We can even selectively delete particle using our f and _alive symbols.
Bivariate Expressions
So far we have used constant or univariate expressions on the RHS of an assignment operator. This makes sense because we can only
assign an expression to a single particle if that expression depends on a constant or that particle's variables. However, we might also want
our expression to depend on the other particles in the container, or another container. In this case we wish to use a bivariate expression.
For example, the following equation defned a sum over all other particles (with label b), using the function w, which depends on the
separation of particle a and b.
Normally for a bivariate expression we wish to accumulate the contribution from other particles in order to arrive at a result. This is most
often done with a summation. In Aboria, we can defne an accumulator object, which takes a single template argument which is the
function or functor to accumulate with. For example, the following defnes a summation accumulator using std::plus
Accumulate<std::plus<vdouble3>> sum;
We might also want to sum the inverse distance between particle pairs, like so
Unfortunately if a and b refer to the same particle container this will result a divide-by-zero at runtime, when a and b are labels for the
same particle. Therefore we can restrict the evaluation of the sum by setting the second argument to ensure that the id of particles a and
b are non-identical. Recall that id is a built-in variable that contains a unique id for each particle in the container.
Symbol<id> _id;
p[a] = sum(b, if_else(_id[a] != _id[b], 1.0, 0.0) / (p[b] - p[a]));
So the frst argument to sum is the label to sum over, the second is the conditional expression that must evaluate to true to be included in
the summation, and the third is an expression that provides the value to be included in the summation.
There is a special case for the conditional expression, when you want to sum over all particles within a certain radius. This can be
expressed using the Aboria::AccumulateWithinDistance summation
AccumulateWithinDistance<std::plus<vdouble3>> sum_within_two(2);
auto dx = create_dx(a, b);
p[a] = sum_within_two(b, dx / pow(norm(dx), 2));
where dx is a Dx symbol representing the shortest vector from b to a. Note that this might be different from p[a]-p[b] for periodic
domains. The symbolic function [functionref Aboria::norm norm] returns the 2-norm, or magnitude, of the vector dx, and the symbolic
function [functionref Aboria::pow pow] returns the frst argument to the power of the second (in much the same way as std::pow, but lazily
evaluated).
In this case Aboria will perform a summation over neighbours closer than a radius of 2, and will use the neighbourhood searching facility
described in aboria.neighbourhood_searching to fnd these neighbouring particles. Note that you need to call
Aboria::Particles::init_neighbour_search before any bivariate expressions using neighbourhood searching.
neighbourhood-searching expressions to count the number of particles within a distance of 2 of each individual particle, storing the result in
a variable called count.
Examples
Container/Iterator API
Symbolic API
Kernel Operator API
Container/Iterator API
This example creates $N$ particles within a two-dimensional square domain, with periodic boundary conditions.
There is a linear spring force $\mathbf{f}_{ij}$ between particles $i$ and $j$ with a rest separation of $r$ (constant for all particles), and a
cutoff at $r$. That is, if $\mathbf{r}_i$ is the position of particle $i$ and $\mathbf{dx}_{ij}=\mathbf{r}_j-\mathbf{r}_j$, then
We wish to use a leap frog integrator to evolve positions $\mathbf{r}_i$ using velocities $\mathbf{v}_i$ and accelerations $\mathbf{a}_i =
\sum_j \mathbf{f}_{ij}$. This gives the following update equations for each timestep $n$
\begin{align*} \mathbf{v}^{n+1}_i &= \mathbf{v}^n_i + \frac{dt}{m_i} \sum_j \mathbf{f}^n_{ij} \\ \mathbf{r}^{n+1}_i &= \mathbf{r}^n_i + dt,
\mathbf{v}^{n+1}_i. \end{align*}
We implement this in Aboria using the code given below. Firstly we create the particle set data structure and add particles, ensuring that
we have an initial condition where all the spring forces are $\mathbf{f}_{ij}=0$. Then we start the timestep loop, using our update equations
given above.
#include <boost/math/constants/constants.hpp>
#include <math.h>
#include <random>
#include "Aboria.h"
using namespace Aboria;
int main() {
const double PI = boost::math::constants::pi<double>();
// Create a 2d particle container with one additional variable
// "velocity", represented by a 2d double vector
ABORIA_VARIABLE(velocity, vdouble2, "velocity")
typedef Particles<std::tuple<velocity>,2> container_type;
typedef typename container_type::position position;
container_type particles;
// set parameters for the MD simulation
const int timesteps = 3000;
const int nout = 200;
const int timesteps_per_out = timesteps / nout;
const double L = 31.0 / 1000.0;
const int N = 30;
const double diameter = 0.0022;
const double k = 1.0e01;
This experiment was the frst to demonstrate the importance of computer simulation in the analysis of non-linear systems, and
demonstrates the paradox that many apparently chaotic systems exhibit periodic behaviour.
We reproduce this experiment using Aboria below. Of course, being a 1D lattice code, Aboria is overkill for this type of simulation, but given
that the frst numerical experiment was a particle simulation I had to include it in the examples.
The equations of motion for each particle in terms of its displacement from a rest confguration are
where $w_1^2 = 4 \sin^2(\pi/2N)$, and $A_1 = \sqrt{2/(N+1)}\sum_{n=1}^N u_n \sin(n\pi/(N+1))$ and set up an initial condition with all the
energy in this lowest mode, then we see that while the energy initially diffuses away to the higher modes, after a long enough time the
energy returns to the lowest modes until the system is in its original state.
If you compile the code below with Cairo enabled, then it will output svg fles showing the image below. The circles are the particles,
coloured red by their displacement $u$, and the line shows the amount of energy in the lowest mode versus time.
#include "Aboria.h"
#include <random>
using namespace Aboria;
#include <boost/math/constants/constants.hpp>
int main() {
const double PI = boost::math::constants::pi<double>();
// setup types
ABORIA_VARIABLE(velocity, vdouble1, "velocity")
ABORIA_VARIABLE(acceleration, vdouble1, "acceleration")
ABORIA_VARIABLE(acceleration0, vdouble1, "old acceleration")
typedef Particles<std::tuple<velocity, acceleration, acceleration0>, 1>
particles_t;
typedef particles_t::position position;
// simulation parameters
const double c = 1.0;
const double alpha = 0.25;
const double h = 1.0;
const double scale = std::pow(c, 2) / std::pow(h, 2);
const int N = 32;
const double w1 = 2.0 * std::sin(PI / (2.0 * N));
const double Tf = 160 * 2 * PI / w1;
const long timesteps = 1000000;
const int nout = 1000;
const int timesteps_per_out = timesteps / nout;
const double dt = static_cast<double>(Tf) / timesteps;
// create particles
particles_t particles(N);
// set intial variables, position here is simply a displacement
// for each particle away from its resting position
for (size_t i = 0; i < N; ++i) {
get<position>(particles)[i][0] = std::sin((i + 1) * PI / (N + 1));
get<acceleration>(particles)[i][0] = 0;
get<velocity>(particles)[i][0] = 0;
}
// time loop
std::vector<double> energy(nout, 0);
for (size_t out = 0; out < nout; ++out) {
for (size_t t = 0; t < timesteps_per_out; ++t) {
// advance position: x1 = x0 + dt*v + 0.5*dt^2*a
for (size_t i = 0; i < N; ++i) {
get<position>(particles)[i] +=
dt * get<velocity>(particles)[i] +
0.5 * std::pow(dt, 2) * get<acceleration>(particles)[i];
}
// calculate acceleration: a1 = f(x1)
for (size_t i = 0; i < N; ++i) {
// get displacements, taking into account boundary conditions
// of x0 = xN = 0
const double &x = get<position>(particles)[i][0];
const double xp1 =
i != N - 1 ? get<position>(particles)[i + 1][0] : 0;
const double xm1 = i != 0 ? get<position>(particles)[i - 1][0] : 0;
get<acceleration0>(particles)[i] = get<acceleration>(particles)[i];
get<acceleration>(particles)[i][0] =
scale * (xp1 + xm1 - 2 * x) +
alpha * (std::pow(xp1 - x, 2) - std::pow(x - xm1, 2));
}
// advance velocity: v1 = v0 + 0.5*dt*(a0 + a1)
for (size_t i = 0; i < N; ++i) {
get<velocity>(particles)[i] += 0.5 * dt *
(get<acceleration0>(particles)[i] +
get<acceleration>(particles)[i]);
}
}
// calculate energy in the lowest mode
// (w1*A1)^2 = potential energy
// (Adot1)^2 = kinetic energy
double A1 = 0;
double Adot1 = 0;
for (size_t i = 0; i < N; ++i) {
const double &u = get<position>(particles)[i][0];
const double &v = get<velocity>(particles)[i][0];
A1 += std::sqrt(2.0 / (N + 1)) * u * std::sin((i + 1) * PI / (N + 1));
Adot1 +=
std::sqrt(2.0 / (N + 1)) * v * std::sin((i + 1) * PI / (N + 1));
}
energy[out] = 0.5 * (std::pow(Adot1, 2) + std::pow(w1 * A1, 2));
// visualise system if compiled with cairo
#ifdef HAVE_CAIRO
// create surface
const int image_size = 512;
const double ratio = 1.0 / 5.0;
cairo_surface_t *surface = cairo_svg_surface_create(
("fput" + std::to_string(out) + ".svg").c_str(), image_size,
image_size * ratio);
cairo_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2);
cairo_t *cr = cairo_create(surface);
// set source
cairo_scale(cr, image_size, image_size);
cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
const double lw = 0.01;
cairo_set_line_width(cr, lw);
// draw particles
for (size_t i = 0; i < N; ++i) {
const double &u = get<position>(particles)[i][0];
const double pos = 0.1 * u + (i + 1) * dx;
cairo_set_source_rgba(cr, std::abs(u), 0, 0, 1.0);
cairo_arc(cr, pos, 0.5 * ratio, lw, 0, 2 * PI);
cairo_fll(cr);
}
// draw energy
cairo_set_source_rgba(cr, 1, 0, 0, 0.8);
cairo_move_to(cr, 0, energy[0] * ratio);
for (size_t i = 1; i < out; ++i) {
cairo_line_to(cr, static_cast<double>(i) / nout,
(1.0 - 10 * energy[i]) * ratio);
}
cairo_stroke(cr);
// clean up
cairo_destroy(cr);
cairo_surface_destroy(surface);
#endif // HAVE_CAIRO
}
}
Symbolic API
This example creates $N$ particles within a two-dimensional square domain, with periodic boundary conditions.
There is a linear spring force $\mathbf{f}_{ij}$ between particles $i$ and $j$ with a rest separation of $r$ (constant for all particles), and a
cutoff at $r$. That is, if $\mathbf{r}_i$ is the position of particle $i$ and $\mathbf{dx}_{ij}=\mathbf{r}_j-\mathbf{r}_j$, then
We wish to use a leap frog integrator to evolve positions $\mathbf{r}_i$ using velocities $\mathbf{v}_i$ and accelerations $\mathbf{a}_i =
\sum_j \mathbf{f}_{ij}$. This gives the following update equations for each timestep $n$
\begin{align*} \mathbf{v}^{n+1}_i &= \mathbf{v}^n_i + \frac{dt}{m_i} \sum_j \mathbf{f}^n_{ij} \\ \mathbf{r}^{n+1}_i &= \mathbf{r}^n_i + dt,
\mathbf{v}^{n+1}_i. \end{align*}
We implement this in Aboria using the code given below. Firstly we create the particle set data structure and add particles, ensuring that
we have an initial condition where all the spring forces are $\mathbf{f}_{ij}=0$. Then we start the timestep loop, using our update equations
given above.
#include <boost/math/constants/constants.hpp>
#include <math.h>
#include <random>
#include "Aboria.h"
using namespace Aboria;
int main() {
const double PI = boost::math::constants::pi<double>();
// Create a 2d particle container with one additional variable
// "velocity", represented by a 2d double vector
ABORIA_VARIABLE(velocity, vdouble2, "velocity")
typedef Particles<std::tuple<velocity>,2> container_type;
typedef typename container_type::position position;
// set parameters for the MD simulation
const int timesteps = 3000;
const int nout = 200;
const int timesteps_per_out = timesteps / nout;
const double L = 31.0 / 1000.0;
const int N = 30;
const double diameter = 0.0022;
const double k = 1.0e01;
const double dens = 1160.0;
const double mass = PI * std::pow(0.5 * diameter, 2) * dens;
const double reduced_mass = 0.5 * mass;
const double dt = (1.0 / 50.0) * PI / std::sqrt(k / reduced_mass);
// create N particles
container_type particles(N);
// create symbols and labels in order to use the expression API
Symbol<position> p;
Symbol<velocity> v;
Symbol<id> id_;
Uniform uniform;
VectorSymbolic<double, 2> vector;
Label<0, container_type> a(particles);
Label<1, container_type> b(particles);
// dx is a symbol representing the difference in positions of
// particle a and b.
auto dx = create_dx(a, b);
// sum is a symbolic function that sums a sequence of 2d vectors
AccumulateWithinDistance<std::plus<vdouble2>> sum(diameter);
// initialise particles to a uniform distribution
p[a] = L * vector(uniform[a], uniform[a]);
// zero initial velocity
v[a] = vector(0, 0);
// initiate neighbour search on a periodic 2d domain of side length
// L set average number of particles per cell to 1
particles.init_neighbour_search(vdouble2(0, 0), vdouble2(L, L),
vbool2(true, true));
// perform MD timestepping
for (int io = 0; io < nout; ++io) {
// on every i/o step write particle container to a vtk
// unstructured grid fle
std::cout << "." << std::fush;
#ifdef HAVE_VTK
vtkWriteGrid("particles", io, particles.get_grid(true));
#endif
for (int i = 0; i < timesteps_per_out; i++) {
// leap frog integrator
v[a] += dt *
// spring force between particles
sum(b, if_else(id_[a] != id_[b],
The point particles diffuse around the three-dimensional, periodic domain, and refect off the spheres whenever they encounter them.
Let indicies $i$ and $j$ refer to a pair of point particles, and $a$ and $b$ refer to a pair of spheres. Let $\mathbf{p}_i$ be the position of
particle $i$, and let $\mathbf{dx}_{ij}$ refer to the shortest difference between the positions of particles $i$ and $j$. Let $r_b$ be the radius
of sphere $b$. Then the update equations used to evolve the system are given by
$$ \mathbf{p}_i = \mathbf{p}_i + \sqrt{2\, D\, dt}\, \mathbf{N} + \sum_b \begin{cases} -2\left(\frac{r_b}{||\mathbf{dx}_{ib}||} - 1\right)
\mathbf{dx}_{ib}, & \text{for } ||\mathbf{dx}_{ib}||<r_b \0 & \text{otherwise}. \end{cases} $$
where $D$ is the diffusion constant, $dt$ is the timestep and $\mathbf{N}$ is a three-dimensional vector containing random samples from a
normal distribution
#include "Aboria.h"
#include <random>
using namespace Aboria;
int main() {
ABORIA_VARIABLE(radius, double, "radius")
typedef Particles<std::tuple<radius>,3,std::vector> spheres_type;
typedef Particles<std::tuple<>,3,std::vector> points_type;
typedef position_d<3> position;
spheres_type spheres;
const double L = 10.0;
const double D = 1.0;
const double dt = 0.01;
const double timesteps = 500;
spheres.push_back(vdouble3(0, 0, 0));
get<radius>(spheres[0]) = 1.0;
spheres.push_back(vdouble3(5, 0, 0));
get<radius>(spheres[1]) = 2.0;
spheres.push_back(vdouble3(0, -5, 0));
get<radius>(spheres[2]) = 1.5;
spheres.push_back(vdouble3(0, 0, 5));
get<radius>(spheres[3]) = 1.0;
points_type points;
std::uniform_real_distribution<double> uni(-L + L / 5, L - L / 5);
std::default_random_engine generator;
for (int i = 0; i < 1000; ++i) {
points.push_back(
vdouble3(uni(generator), uni(generator), uni(generator)));
}
points.init_neighbour_search(vdouble3(-L, -L, -L), vdouble3(L, L, L),
vbool3(true, true, true));
spheres.init_neighbour_search(vdouble3(-L, -L, -L), vdouble3(L, L, L),
vbool3(false, false, false));
Symbol<position> p;
Symbol<radius> r;
Symbol<alive> alive_;
Label<0, spheres_type> a(spheres);
Label<1, spheres_type> b(spheres);
Label<0, points_type> i(points);
Label<1, points_type> j(points);
auto dx = create_dx(i, b);
Normal N;
VectorSymbolic<double, 3> vector;
AccumulateWithinDistance<std::bit_or<bool>> any(4);
AccumulateWithinDistance<std::plus<vdouble3>> sum(4);
int count_before = 0;
for (auto point : points) {
if ((get<position>(point) - get<position>(spheres[0])).norm() <
get<radius>(spheres[0])) {
count_before++;
}
}
/*
* Kill any points within spheres
*/
alive_[i] = !any(b, if_else(norm(dx) < r[b], true, false));
int count_after = 0;
for (auto point : points) {
if ((get<position>(point) - get<position>(spheres[0])).norm() <
get<radius>(spheres[0])) {
count_after++;
}
}
std::cout << " found " << count_before << " before and " << count_after
<< " after" << std::endl;
/*
* Diffusion step for points and refect off spheres
*/
for (int ts = 1; ts < timesteps; ++ts) {
if (ts % 10 == 0) {
#ifdef HAVE_VTK
vtkWriteGrid("bd", ts / 10, points.get_grid(true));
#endif
std::cout << "." << std::fush;
}
p[i] += std::sqrt(2 * D * dt) * vector(N[i], N[i], N[i]);
p[i] += sum(b, if_else(norm(dx) < r[b] && norm(dx) != 0,
-2 * (r[b] / norm(dx) - 1), 0) *
dx);
}
std::cout << std::endl;
}
We wish to describe a set of particles in 3D cuboid, which is periodic in the Cartesian $x$, and $y$ directions. There is a linear spring force
$\mathbf{f}_{ij}$ plus dissipation term between particles $i$ and $j$ with a rest separation at $s_i + s_j$ and a cutoff at $s_i + s_j$. That is,
if $\mathbf{r}_i$ is the position of particle $i$ and $\mathbf{dx}_{ij}=\mathbf{r}_j-\mathbf{r}_j$, then
We wish to use a leap frog integrator to evolve positions $\mathbf{r}_i$ using velocities $\mathbf{v}_i$ and accelerations $\mathbf{a}_i =
\frac{1}{m_i} \sum_j \mathbf{f}_{ij} - \mathbf{g}$. This gives the following update equations for each timestep $n$
\begin{align*} \mathbf{v}^{n+1}_i &= \mathbf{v}^n_i + \frac{dt}{m_i} \sum_j \mathbf{f}^n_{ij} \\ \mathbf{r}^{n+1}_i &= \mathbf{r}^n_i + dt,
\mathbf{v}^{n+1}_i. \end{align*}
This fgure above shows the simulation domain. As well as periodic in $x$, and $y$, we wish to add a soft surface at $z=0$ that also
interacts with the particles using the same linear spring force. The domain is left open at $z=h$. We wish to initialise $N$ particles within
this domain, and ensure that they are non-interacting at $t=0$.
#include <random>
#include "Aboria.h"
Simulation of a water column in hydrostatic equilibrium. SPH discretises the Navier-Stokes equations using radial interpolation kernels
defned over a given particle set. See the following papers for more details than can be described here:
M. Robinson, J. J. Monaghan, Direct numerical simulation of decaying two-dimensional turbulence in a no-slip square box using smoothed
par- ticle hydrodynamics, International Journal for Numerical Methods in Fluids 70 (1) (2012) 37–55
M. Robinson, M. Ramaioli, S. Luding, Fluid-particle fow simulations us- ing two-way-coupled mesoscale SPH-DEM and validation,
International Journal of Multiphase Flow 59 (2014) 121–134.
SPH is based on the idea of kernel interpolation. A fuid variable $A(\mathbf{r})$ (such as velocity or density) is interpolated using a kernel
$W$, which depends on the smoothing length variable $h$.
where $m_b$ and $\rho_b$ are the mass and density of particle $b$.
Here we have used the ffth-order Wendland kernel for $W$, which has the form
\begin{eqnarray} W(q) = \frac{\beta}{h^d} \begin{cases} (2-q)^4(1+2q) & \text{for } 0 \leq q \le 2, \ 0 & \text{for } q > 2. \end{cases}
\end{eqnarray}
where $q = ||\mathbf{r}-\mathbf{r'}||/h$.
where $\mathbf{v}_{ab}=\mathbf{v}_a-\mathbf{v}_b$. The correction term $\Omega_a$ due to variable $h$ is given by
\begin{equation} \Omega_a = 1 - \frac{\partial h_a}{\partial \rho_a} \sum_b m_b \frac{\partial W_{ab}(h_a)}{\partial h_a}. \end{equation}
where $\gamma = 7$ is a typical value and $\rho_0$ is a reference density that is normally set to the density of the fuid.
The SPH momentum equation is given as below. Viscosity is included by adding a viscous term $\Pi$
The SPH literature contains many different forms for $\Pi$. We have used the term
where $v_{sig} = 2(c_s + |\mathbf{v}_{ab} \cdot \mathbf{r}_{ab}| / |\mathbf{r}_{ab}| )$ is a signal velocity that represents the speed at which
information propagates between the particles.
The particle's position and velocity were integrated using the Leapfrog second order method, which is also reversible in time in the
absence of viscosity. To preserve the reversibility of the simulation, $d\rho/dt$ was calculated using the particle's position and velocity at
the end of the timestep, rather than the middle as is commonly done. The full integration scheme is given by
\begin{align} \mathbf{r}^{\frac{1}{2}} &= \mathbf{r}^{0} + \frac{\delta t}{2} \mathbf{v}^{0}, \\ \mathbf{v}^{\frac{1}{2}} &= \mathbf{v}^{0} +
\frac{\delta t}{2} F(\mathbf{r}^{-\frac{1}{2}},\mathbf{v}^{-\frac{1}{2}},\rho^{-\frac{1}{2}}), \\ \rho^{\frac{1}{2}} &= \rho^{0} + \frac{\delta t}{2}
D(\mathbf{r}^0,\mathbf{v}^0), \label{Eq:timestepDensity1} \\ \mathbf{v}^{1} &= \mathbf{v}^{0} + \delta t
F(\mathbf{r}^{\frac{1}{2}},\mathbf{v}^{\frac{1}{2}},\rho^{\frac{1}{2}}), \\ \mathbf{r}^{1} &= \mathbf{r}^{\frac{1}{2}} + \frac{\delta t}{2}
\mathbf{v}^{1}, \\ \rho^{1} &= \rho^{\frac{1}{2}} + \frac{\delta t}{2} D(\mathbf{r}^1,\mathbf{v}^1), \label{Eq:timestepDensity2} \end{align}
where $\mathbf{r}^0$, $\mathbf{r}^{1/2}$ and $\mathbf{r}^1$ is $\mathbf{r}$ at the start, mid-point and end of the timestep respectively. The
functions $F$ and $D$ are respectivly the momentum and continuity equations given above. The timestep $\delta t$ is bounded by the
standard Courant condition
\begin{equation} \delta t_1 \le \min_a \left ( 0.8 \frac{h_a}{v_{sig}} \right ), \end{equation}
#include "Aboria.h"
using namespace Aboria;
#include <boost/math/constants/constants.hpp>
const double PI = boost::math::constants::pi<double>();
const double WCON_WENDLAND = 21.0 / (256.0 * PI);
const unsigned int NDIM = 3;
/*
* Note that we are using standard C++ function objects to implement
* the kernel W and its gradient F. We can wrap these as lazy Aboria
* functions that can be used within the symbolic Level 3 API.
*/
struct F_fun {
typedef double result_type;
double operator()(const double r, const double h) const {
if (r == 0)
return 0;
const double q = r / h;
if (q <= 2.0) {
return (1 / std::pow(h, NDIM + 2)) * WCON_WENDLAND *
(-4 * std::pow(2 - q, 3) * (1 + 2 * q) + 2 * std::pow(2 - q, 4)) /
q;
} else {
return 0.0;
}
}
};
struct W_fun {
typedef double result_type;
double operator()(const double r, const double h) const {
const double q = r / h;
if (q <= 2.0) {
return (1 / std::pow(h, NDIM)) * WCON_WENDLAND * std::pow(2.0 - q, 4) *
(1.0 + 2.0 * q);
} else {
return 0.0;
}
}
};
ABORIA_BINARY_FUNCTION(F, F_fun, SymbolicDomain);
ABORIA_BINARY_FUNCTION(W, W_fun, SymbolicDomain);
int main() {
ABORIA_VARIABLE(kernel_radius, double, "kernel radius");
ABORIA_VARIABLE(velocity, vdouble3, "velocity");
ABORIA_VARIABLE(velocity_tmp, vdouble3, "temp velocity");
ABORIA_VARIABLE(varh_omega, double, "varh omega");
ABORIA_VARIABLE(density, double, "density");
ABORIA_VARIABLE(total_force, vdouble3, "total force");
ABORIA_VARIABLE(is_fxed, uint8_t, "fxed boundary");
ABORIA_VARIABLE(pressure_div_density2, double, "pressure div density2");
typedef Particles<
std::tuple<kernel_radius, velocity, velocity_tmp, varh_omega,
density, total_force, is_fxed,
pressure_div_density2>, 3>
sph_type;
typedef position_d<3> position;
sph_type sph;
Symbol<position> p;
Symbol<id> id_;
Symbol<velocity> v;
Symbol<velocity_tmp> v0;
Symbol<density> rho;
Symbol<total_force> dvdt;
Symbol<is_fxed> fxed;
Symbol<varh_omega> omega;
Symbol<kernel_radius> h;
Symbol<pressure_div_density2> pdr2;
Label<0, sph_type> a(sph);
Label<1, sph_type> b(sph);
const int timesteps = 200;
const int nout = 10;
const int timesteps_per_out = timesteps / nout;
const double L = 31.0 / 1000.0;
const int nx = 5;
/*
* sph parameters
*/
const double hfac = 1.5;
const double visc = 8.9e-07;
const double refd = 1000.0;
const double dens = 1000.0;
const double gamma = 7;
const double VMAX = 2.0 * sqrt(2 * 9.81 * L);
const double CSFAC = 10.0;
const double spsound = CSFAC * VMAX;
const double prb = std::pow(refd / dens, gamma - 1.0) *
std::pow(spsound, 2) * refd / gamma;
const double psep = L / nx;
double dt = std::min(0.25 * hfac * psep / spsound,
0.125 * std::pow(hfac * psep, 2) / visc);
const double mass = dens * std::pow(psep, NDIM);
std::cout << "h = " << hfac * psep << " vmax = " << VMAX << std::endl;
const double time_damping = dt * 500;
double t = 0;
const vdouble3 low(0, 0, -3.0 * psep);
const vdouble3 high(L, L, L);
const vbool3 periodic(true, true, false);
for (int i = 0; i < nx; i++) {
for (int j = 0; j < nx; j++) {
for (int k = 0; k < nx + 3; k++) {
typename sph_type::value_type p;
get<position>(p) = low + vdouble3((i + 0.5) * psep, (j + 0.5) * psep,
(k + 0.5) * psep);
get<kernel_radius>(p) = hfac * psep;
get<velocity>(p) = vdouble3(0, 0, 0);
get<velocity_tmp>(p) = vdouble3(0, 0, 0);
get<varh_omega>(p) = 1.0;
get<density>(p) = dens;
get<total_force>(p) = vdouble3(0, 0, 0);
get<is_fxed>(p) = get<position>(p)[2] < 0;
sph.push_back(p);
}
}
}
std::cout << "starting...." << std::endl;
sph.init_neighbour_search(low, high, periodic);
We create a set of basis functions around a set of $N$ particles with positions $\mathbf{x}_i$. In this case the radial coordinate around
each point is $r = ||\mathbf{x}_i - \mathbf{x}||$. The function $f$ is approximated using the sum of these basis functions, with the addition of
a constant factor $\beta$
Note that the sum $j$ is over the same particle set.
The basis function coeffcients $\mathbf{\gamma}$ are found by solving this equation. To do this, we use the iterative solvers found in the
Eigen package and Aboria's ability to wrap C++ function objects as Eigen matricies.
#include "Aboria.h"
#include <random>
using namespace Aboria;
int main() {
auto funct = [](const double x, const double y) {
return std::exp(-9 * std::pow(x - 0.5, 2) - 9 * std::pow(y - 0.25, 2));
// return x;
};
ABORIA_VARIABLE(alpha, double, "alpha value")
ABORIA_VARIABLE(interpolated, double, "interpolated value")
ABORIA_VARIABLE(constant2, double, "c2 value")
typedef Particles<std::tuple<alpha, constant2, interpolated>, 2,
std::vector, SearchMethod>
ParticlesType;
typedef position_d<2> position;
typedef typename ParticlesType::const_reference const_particle_reference;
typedef Eigen::Matrix<double, Eigen::Dynamic, 1> vector_type;
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> matrix_type;
ParticlesType knots;
ParticlesType augment;
ParticlesType test;
const double c = 0.5;
const int N = 1000;
const int max_iter = 100;
const int restart = 101;
typename ParticlesType::value_type p;
std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0, 1.0);
for (int i = 0; i < N; ++i) {
get<position>(p) =
vdouble2(distribution(generator), distribution(generator));
get<constant2>(p) = std::pow(c, 2);
knots.push_back(p);
get<position>(p) =
vdouble2(distribution(generator), distribution(generator));
get<constant2>(p) = std::pow(c, 2);
test.push_back(p);
}
// knots.init_neighbour_search(min,max,periodic);
augment.push_back(p);
auto kernel = [](const_particle_reference a, const_particle_reference b) {
return std::sqrt((get<position>(b) - get<position>(a)).squaredNorm() +
get<constant2>(b));
};
auto one = [](const_particle_reference a, const_particle_reference b) {
return 1.0;
};
auto G = create_dense_operator(knots, knots, kernel);
auto P = create_dense_operator(knots, augment, one);
auto Pt = create_dense_operator(augment, knots, one);
auto Zero = create_zero_operator(augment, augment);
auto W = create_block_operator<2, 2>(G, P, Pt, Zero);
auto G_test = create_dense_operator(test, knots, kernel);
auto W_test = create_block_operator<2, 2>(G_test, P, Pt, Zero);
vector_type phi(N + 1), gamma(N + 1);
for (size_t i = 0; i < knots.size(); ++i) {
const double x = get<position>(knots[i])[0];
const double y = get<position>(knots[i])[1];
phi[i] = funct(x, y);
}
phi[knots.size()] = 0;
matrix_type W_matrix(N + 1, N + 1);
W.assemble(W_matrix);
gamma = W_matrix.ldlt().solve(phi);
Eigen::GMRES<matrix_type> gmres;
gmres.setMaxIterations(max_iter);
gmres.set_restart(restart);
gmres.compute(W_matrix);
gamma = gmres.solve(phi);
std::cout << "GMRES: #iterations: " << gmres.iterations()
<< ", estimated error: " << gmres.error() << std::endl;
phi = W * gamma;
double rms_error = 0;
double scale = 0;
for (size_t i = 0; i < knots.size(); ++i) {
const double x = get<position>(knots[i])[0];
const double y = get<position>(knots[i])[1];
const double truth = funct(x, y);
const double eval_value = phi[i];
rms_error += std::pow(eval_value - truth, 2);
scale += std::pow(truth, 2);
// TS_ASSERT_DELTA(eval_value,truth,2e-3);
}
std::cout << "rms_error for global support, at centers = "
<< std::sqrt(rms_error / scale) << std::endl;
TS_ASSERT_LESS_THAN(std::sqrt(rms_error / scale), 1e-6);
phi = W_test * gamma;
rms_error = 0;
scale = 0;
for (size_t i = 0; i < test.size(); ++i) {
const double x = get<position>(test[i])[0];
const double y = get<position>(test[i])[1];
const double truth = funct(x, y);
const double eval_value = phi[i];
rms_error += std::pow(eval_value - truth, 2);
scale += std::pow(truth, 2);
// TS_ASSERT_DELTA(eval_value,truth,2e-3);
}
std::cout << "rms_error for global support, away from centers = "
#include "Aboria.h"
using namespace Aboria;
int main() {
auto funct = [](const double x, const double y) {
return std::cos(4*x+4*y);
};
auto laplace_funct = [](const double x, const double y) {
return -32*std::cos(4*x+4*y);
};
ABORIA_VARIABLE(boundary,uint8_t,"is boundary knot")
ABORIA_VARIABLE(interpolated,double,"interpolated value")
ABORIA_VARIABLE(constant2,double,"c2 value")
ABORIA_VARIABLE(alpha,double,"alpha value")
typedef Particles<std::tuple<alpha,boundary,constant2,interpolated>,2> ParticlesType;
typedef position_d<2> position;
typedef typename ParticlesType::const_reference const_particle_reference;
typedef Eigen::Map<Eigen::Matrix<double,Eigen::Dynamic,1>> map_type;
typedef Eigen::Matrix<double,Eigen::Dynamic,1> vector_type;
ParticlesType knots,augment;
const double c = 0.5;
const int max_iter = 100;
const int restart = 100;
const int nx = 7;
constexpr int N = (nx+1)*(nx+1);
const double delta = 1.0/nx;
typename ParticlesType::value_type p;
for (int i=0; i<=nx; ++i) {
for (int j=0; j<=nx; ++j) {
get<position>(p) = vdouble2(i*delta,j*delta);
if ((i==0)||(i==nx)||(j==0)||(j==nx)) {
get<boundary>(p) = true;
} else {
get<boundary>(p) = false;
}
get<constant2>(p) = std::pow(c,2);
knots.push_back(p);
}
}
augment.push_back(p);
auto kernel = [](
const_particle_reference a,
const_particle_reference b) {
const vdouble2 dx = get<position>(b) - get<position>(a);
return std::exp(-dx.squaredNorm()/get<constant2>(b));
};
auto laplace_kernel = [](
const_particle_reference a,
const_particle_reference b) {
const vdouble2 dx = get<position>(b) - get<position>(a);
return 4.0*(dx.squaredNorm()-get<constant2>(b))*
std::exp(-dx.squaredNorm()/get<constant2>(b))/
(get<constant2>(b)*get<constant2>(b));
};
auto G = create_dense_operator(knots,knots,
[kernel,laplace_kernel](
const_particle_reference a,
const_particle_reference b) {
if (get<boundary>(a)) {
return kernel(a,b);
} else {
return laplace_kernel(a,b);
}
});
auto P = create_dense_operator(knots,augment,
[](
const_particle_reference a,
const_particle_reference b) {
if (get<boundary>(a)) {
return 1.0;
} else {
return 0.0;
}
});
auto Pt = create_dense_operator(augment,knots,
[](
const_particle_reference a,
const_particle_reference b) {
if (get<boundary>(b)) {
return 1.0;
} else {
return 0.0;
}
});
auto Zero = create_zero_operator(augment,augment);
auto W = create_block_operator<2,2>(G, P,
Pt,Zero);
map_type alpha_wrap(get<alpha>(knots).data(),N);
map_type interp_wrap(get<interpolated>(knots).data(),N);
alpha_wrap = gamma.segment<N>(0);
vector_type beta = vector_type::Constant(N,gamma[N]);
auto K = create_dense_operator(knots,knots,kernel);
interp_wrap = K*alpha_wrap + beta;
double rms_error = 0;
double scale = 0;
for (int i=0; i<N; ++i) {
const double x = get<position>(knots[i])[0];
const double y = get<position>(knots[i])[1];
const double truth = funct(x,y);
const double eval_value = get<interpolated>(knots[i]);
rms_error += std::pow(eval_value-truth,2);
scale += std::pow(truth,2);
TS_ASSERT_DELTA(eval_value,truth,1e-2);
}
std::cout << "rms_error for global support, at centers =
"<<std::sqrt(rms_error/scale)<<std::endl;
TS_ASSERT_LESS_THAN(std::sqrt(rms_error/scale),1e-3);
}
Benchmarks
Vector Addition
DAXPY
Dense non-linear operator
Neighbour search non-linear operator
Vector Addition
Here we aim to compute a simple vector addition operation
A particle set containing the variables $a$, $b$ and $c$ can be defned in Aboria like so
ABORIA_VARIABLE(a_var,double,"a")
ABORIA_VARIABLE(b_var,double,"b")
ABORIA_VARIABLE(c_var,double,"c")
typedef Particles<std::tuple<a_var,b_var,c_var>,3> nodes_type;
nodes_type nodes(N);
The vector addition operation can then be calculated using the Level 3 layer like so
Symbol<a_var> a;
Symbol<b_var> b;
Symbol<c_var> c;
Label<0,nodes_type> i(nodes);
a[i] = b[i] + c[i];
We compare this with Level 1 Aboria using the get functions and looping through the container
std::vector<double> a(N),b(N),c(N);
for (size_t i=0; i<N; i++) {
a[i] = b[i] + c[i];
}
We can measure the time taken by the last line in the code segment above for varying $N$, and compare the four different
implementations
The resultant benchmarks are shown in the Figure below, where it can be seen that the four approaches are very similar in speed,
confrming that [Aboria][] can achieve zero-cost abstraction, at least in this simple case. More complicated cases are explored below.
DAXPY
This benchmark is for the BLAS DAXPY operation, given by
a[i] += 0.1*b[i];
std::vector<double> a(N),b(N);
for (size_t i=0; i<N; i++) {
a[i] += 0.1*b[i];
}
$$ a_i = a_i + \sum_j^N a_j \sqrt{\mathbf{dx}_{ij} \cdot \mathbf{dx}_{ij} + b_j^2} \text{ for } i = 0...N. $$
where $\mathbf{dx}_{ij}$ is the shortest vector from particle $i$ to $i$. This is implemented in Level 3 Aboria like so
Label<1,nodes_type> j(nodes);
auto dx = create_dx(i,j);
Accumulate<std::plus<double> > sum;
a[i] += sum(j,true,a[j]*sqrt(dot(dx,dx)+b[j]*b[j]));
This is compared against a std::vector implementation. Note that this operator involves aliasing, in that the update variable $a$
appears within the sum, so we need to accumulate the update to a temporary buffer before we assign to $a_i$.
The implementation is shown below (note the openMP parallel loops are turned off for the plot below)
a[i] = sum(j,norm(dx)<r,(r-norm(dx))/norm(dx)*dx);
API Overview
libaboria
Header: <Aboria.h>
Utility
Vector - a $n$-dimensional vector of a given type
Aboria::Particles The main particle set container, implemented as a zipped set of vectors
Objects of this class are normally never created. Instead, this class is used as a "tag" type, and is
Aboria::Variable
used to name variables that are added to the particle set
This is a pre-processor macro that creates a Aboria::Variable class, use this rather than
ABORIA_VARIABLE
using Aboria::Variable directly
This class is an iterator for the Aboria::Particles class. It points to a single particle
Aboria::zip_iterator within the particle set. Dereferencing it gives you a Aboria::getter_type that contains
references to the particle's variables
This spatial data structure implements a cell list. That is, it divides the space into a
Aboria::CellList regular grid of cells, or buckets, that contain particles. This is the default spatial
data structure used within Aboria::Particles
This implements a kdtree spatial data structure. Note that this wraps the
Aboria::KdtreeNanofann Nanofann library <https://github.com/jlblancoc/nanofann> for tree construction,
but Aboria routines are used for all queries.
Aboria::CellListOrderedQuery This is the query object for the Aboria::CellListOrdered data structure
Aboria::KdtreeQuery This is the query object for the kd-tree data structure
Aboria::KdtreeNanofannQuery This is the query object for the kd-tree data structure
Aboria::HyperOctreeQuery This is the query object for the hyper oct-tree data structure
Level 2 - Algorithms
performs a distance search around a given point, using a given p-norm for the distance
Aboria::distance_search
measure
Aboria::euclidean_search performs a distance search around a given point, using euclidean distance
Aboria::manhatten_search performs a distance search around a given point, using manhatten distance
Aboria::chebyshev_search performs a distance search around a given point, using chebyshev distance
Returns a set of expansions for the black box fast multipole method.
Aboria::make_black_box_expansion
Uses chebyshev interpolation to approximate a kernel function
Returns a set of expansions for the black box fast multipole method,
Aboria::make_h2lib_black_box_expansion
designed to be used in conjunction with Aboria::H2LibMatrix
This is a matrix replacement class that can be used within the Eigen linear algebra
library. It follows the layout given in the Eigen documentation for matrix-free operators.
Aboria::MatrixReplacement
Note that this "matrix" can only be used in a matrix-vector multiply with a standard
Eigen vector, or in Eigen's iterative solvers
An object of this class is a symbolic reference to a particle set, and can participate in symbolic
Aboria::Label
expressions
A function that creates a symbolic reference to the shortest difference between two particle's
Aboria::create_dx
positions. It takes two ::Label objects as its arguments
Aboria::dot A lazy function that calculates the dot product of two vectors
libaboria
Header </home/travis/build/martinjrobins/Aboria/src/CellList.h>
Header </home/travis/build/martinjrobins/Aboria/src/CellListOrdered.h>
Header </home/travis/build/martinjrobins/Aboria/src/Chebyshev.h>
Header </home/travis/build/martinjrobins/Aboria/src/Evaluate.h>
Header </home/travis/build/martinjrobins/Aboria/src/FastMultipoleMethod.h>
Header </home/travis/build/martinjrobins/Aboria/src/Functions.h>
Header </home/travis/build/martinjrobins/Aboria/src/Get.h>
Header </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
Header </home/travis/build/martinjrobins/Aboria/src/Kdtree.h>
Header </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
Header </home/travis/build/martinjrobins/Aboria/src/Log.h>
Header </home/travis/build/martinjrobins/Aboria/src/NanoFlannAdaptor.h>
Header </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
Header </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
Header </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Header </home/travis/build/martinjrobins/Aboria/src/Particles.h>
Header </home/travis/build/martinjrobins/Aboria/src/Search.h>
Header </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Header </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Header </home/travis/build/martinjrobins/Aboria/src/Utils.h>
Header </home/travis/build/martinjrobins/Aboria/src/Variable.h>
Header </home/travis/build/martinjrobins/Aboria/src/Vector.h>
Header </home/travis/build/martinjrobins/Aboria/src/CellList.h>
namespace Aboria {
template<typename Traits> struct CellListQuery;
template<typename Traits> class CellList;
}
Header </home/travis/build/martinjrobins/Aboria/src/CellListOrdered.h>
namespace Aboria {
template<typename Traits> struct CellListOrdered_params;
template<typename Traits> struct CellListOrderedQuery;
template<typename Traits> class CellListOrdered;
}
Header </home/travis/build/martinjrobins/Aboria/src/Chebyshev.h>
namespace Aboria {
template<unsigned int D, typename InputIterator, typename OutputIterator,
typename PositionIterator, typename Kernel>
void chebyshev_interpolation(InputIterator input_iterator_begin,
InputIterator input_iterator_end,
OutputIterator output_iterator_begin,
OutputIterator output_iterator_end,
PositionIterator source_positions_begin,
PositionIterator target_positions_begin,
Kernel kernel, unsigned int n);
}
Header </home/travis/build/martinjrobins/Aboria/src/Evaluate.h>
namespace Aboria {
template<typename VariableType, typename Functor, typename ExprRHS,
typename LabelType>
void evaluate_nonlinear(ExprRHS const &, LabelType &);
}
Header </home/travis/build/martinjrobins/Aboria/src/FastMultipoleMethod.h>
namespace Aboria {
template<typename Expansions, typename Kernel, typename RowParticles,
typename ColParticles>
class FastMultipoleMethod;
template<unsigned int D, unsigned int N, typename Function,
typename KernelHelper = detail::position_kernel_helper<D, Function>,
typename Block = typename KernelHelper::Block>
unspecifed make_black_box_expansion(const Function & function);
template<typename Expansions, typename Kernel, typename RowParticles,
typename ColParticles>
FastMultipoleMethod< Expansions, Kernel, RowParticles, ColParticles >
make_fmm(const RowParticles & row_particles,
const ColParticles & col_particles,
const Expansions & expansions, const Kernel & kernel);
}
Header </home/travis/build/martinjrobins/Aboria/src/Functions.h>
ABORIA_TAGGED_FUNCTION(name, tag)
namespace Aboria {
struct norm_fun;
struct inf_norm_fun;
struct dot_fun;
struct exp_fun;
struct sqrt_fun;
struct sign_fun;
struct erf_fun;
struct erfc_fun;
struct log_fun;
struct abs_fun;
struct pow_fun;
template<typename T> struct refect_fun;
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, norm_fun, Expr const &
>::type const
norm(Expr const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, inf_norm_fun, Expr const &
>::type const
inf_norm(Expr const &);
template<typename Expr1, typename Expr2>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, dot_fun, Expr1 const &, Expr2
const & >::type const
dot(Expr1 const &, Expr2 const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, exp_fun, Expr const & >::type
const
exp(Expr const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, sqrt_fun, Expr const &
>::type const
sqrt(Expr const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, sign_fun, Expr const &
>::type const
sign(Expr const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, erf_fun, Expr const & >::type
const
erf(Expr const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, erfc_fun, Expr const &
>::type const
erfc(Expr const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, log_fun, Expr const & >::type
const
log(Expr const &);
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, abs_fun, Expr const & >::type
const
abs(Expr const &);
template<typename Expr1, typename Expr2>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, pow_fun, Expr1 const &, Expr2
const & >::type const
pow(Expr1 const &, Expr2 const &);
ABORIA_TERNARY_FUNCTION(refect_, refect_fun< Expr3 >, SymbolicDomain);
}
Header </home/travis/build/martinjrobins/Aboria/src/Get.h>
namespace Aboria {
template<typename Tuple, typename MplVector> struct getter_type;
template<typename iterator_tuple_type, typename mpl_vector_type>
class zip_iterator;
template<typename TupleType, typename MplVector> struct zip_pointer;
template<typename MplVector, typename... Types>
struct getter_type<std::tuple< Types...>, MplVector>;
template<typename MplVector, typename TT1, typename TT2, typename TT3,
typename TT4, typename TT5, typename TT6, typename TT7,
typename TT8, typename TT9>
struct getter_type<thrust::tuple< TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9 >, MplVector>;
template<typename MplVector, typename... Types>
struct zip_pointer<std::tuple< Types *...>, MplVector>;
template<typename MplVector, typename TT1, typename TT2, typename TT3,
typename TT4, typename TT5, typename TT6, typename TT7,
typename TT8, typename TT9>
struct zip_pointer<thrust::tuple< TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9 >, MplVector>;
template<typename mpl_vector_type, typename... Types>
class zip_iterator<std::tuple< Types...>, mpl_vector_type>;
template<typename mpl_vector_type, typename... Types>
class zip_iterator<thrust::tuple< Types...>, mpl_vector_type>;
template<typename tuple_type, typename tuple_type2,
typename mpl_vector_type>
Header </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
namespace Aboria {
class H2Lib_LR_Decomposition;
class H2LibCholeskyDecomposition;
class HLib_LR_Decomposition;
class HLibCholeskyDecomposition;
class H2LibMatrix;
class HLibMatrix;
template<unsigned int D, typename Function,
typename KernelHelper = detail::position_kernel_helper<D, Function>,
typename Block = typename KernelHelper::Block>
unspecifed make_h2lib_black_box_expansion(size_t order,
const Function & function);
template<typename Expansions, typename Kernel, typename RowParticlesType,
typename ColParticlesType>
HLibMatrix make_h2lib_h_matrix(const RowParticlesType & row_particles,
const ColParticlesType & col_particles,
const Expansions & expansions,
const Kernel & kernel);
template<typename Expansions, typename Kernel, typename RowParticlesType,
typename ColParticlesType>
H2LibMatrix make_h2lib_matrix(const RowParticlesType & row_particles,
const ColParticlesType & col_particles,
const Expansions & expansions,
const Kernel & kernel, const double eta);
}
Header </home/travis/build/martinjrobins/Aboria/src/Kdtree.h>
namespace Aboria {
template<typename Traits> struct KdtreeQuery;
template<typename Traits> class Kdtree;
template<typename Query> class KdtreeChildIterator;
}
Header </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
namespace Aboria {
template<typename RowElements, typename ColElements, typename F>
class KernelBase;
template<typename RowElements, typename ColElements, typename F>
class KernelDense;
template<typename RowElements, typename ColElements, typename F>
class KernelMatrix;
template<typename RowElements, typename ColElements, typename PositionF,
size_t QuadratureOrder = 8,
typename F = detail::position_kernel<RowElements, ColElements, PositionF> >
class KernelChebyshev;
template<typename RowElements, typename ColElements, typename PositionF,
typename F>
class KernelH2;
template<typename RowElements, typename ColElements, typename PositionF,
typename F, unsigned int N>
class KernelFMM;
template<typename RowElements, typename ColElements, typename FRadius,
typename FWithDx,
typename F = detail::sparse_kernel<RowElements, ColElements, FRadius, FWithDx> >
class KernelSparse;
Header </home/travis/build/martinjrobins/Aboria/src/Log.h>
ASSERT(condition, message)
ASSERT_CUDA(condition)
CHECK(condition, message)
CHECK_CUDA(condition, message)
ERROR(message)
ERROR_CUDA(message)
ABORIA_LOG_LEVEL
LOG(level, message)
LOG_CUDA(level, message)
LOG_CUDA1(level, message, variable)
LOG_CUDA2(level, message, variable1, variable2)
LOG_BOLD(level, message)
Header </home/travis/build/martinjrobins/Aboria/src/NanoFlannAdaptor.h>
namespace Aboria {
template<typename Traits> class KdtreeNanofann;
template<typename Traits> struct KdtreeNanofannQuery;
template<typename Traits> class nanofann_child_iterator;
}
Header </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
namespace Aboria {
template<typename IteratorType> struct iterator_range;
template<typename Derived, typename Traits, typename QueryType>
class neighbour_search_base;
template<typename Traits> struct NeighbourQueryBase;
template<typename Traits> class ranges_iterator;
template<typename Traits> class linked_list_iterator;
template<typename Traits, typename Iterator> class index_vector_iterator;
template<typename Query> class depth_frst_iterator;
template<typename Query, int LNormNumber> class tree_query_iterator;
template<unsigned int D> class lattice_iterator;
template<typename Query, int LNormNumber>
class lattice_iterator_within_distance;
template<typename IteratorType>
iterator_range< IteratorType >
make_iterator_range(IteratorType &&, IteratorType &&);
}
Header </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
namespace Aboria {
template<typename Traits> struct HyperOctreeQuery;
template<typename Traits> class HyperOctree;
template<unsigned int D> class octree_child_iterator;
}
Header </home/travis/build/martinjrobins/Aboria/src/Operators.h>
namespace Aboria {
template<unsigned int NI, unsigned int NJ, typename Blocks>
class MatrixReplacement;
template<typename RowParticles, typename ColParticles, typename F,
typename Kernel = KernelDense<RowParticles, ColParticles, F>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>> >
Operator create dense operator(const RowParticles &, const ColParticles &,
const F &);
template<typename RowParticles, typename ColParticles, typename F,
typename Kernel = KernelMatrix<RowParticles, ColParticles, F>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>> >
Operator create_matrix_operator(const RowParticles &,
const ColParticles &, const F &);
template<typename RowParticles, typename ColParticles, typename F,
typename Kernel = KernelChebyshev<RowParticles, ColParticles, F>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>> >
Operator create_chebyshev_operator(const RowParticles &,
const ColParticles &,
const unsigned int, const F &);
template<unsigned int N, typename RowParticles, typename ColParticles,
typename PositionF, typename F,
typename Kernel = KernelFMM<RowParticles, ColParticles, PositionF, F, N>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>> >
Operator create_fmm_operator(const RowParticles &, const ColParticles &,
const PositionF &, const F &);
template<typename RowParticles, typename ColParticles, typename PositionF,
typename F,
typename Kernel = KernelH2<RowParticles, ColParticles, PositionF, F>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>> >
Operator create_h2_operator(const RowParticles &, const ColParticles &,
const int, const PositionF &, const F &,
const double = 1.0);
template<typename RowParticles, typename ColParticles, typename FRadius,
typename F,
typename Kernel = KernelSparse<RowParticles, ColParticles, FRadius, F>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>>,
typename = typename std::enable_if<!std::is_arithmetic<FRadius>::value>::type>
Operator create_sparse_operator(const RowParticles &,
const ColParticles &, const FRadius &,
const F &);
template<typename RowParticles, typename ColParticles, typename F,
typename Kernel = KernelSparseConst<RowParticles, ColParticles, F>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>> >
Operator create_sparse_operator(const RowParticles &,
const ColParticles &, const double,
const F &);
template<typename RowParticles, typename ColParticles,
typename Kernel = KernelZero<RowParticles, ColParticles>,
typename Operator = MatrixReplacement<1, 1, std::tuple<Kernel>> >
Operator create_zero_operator(const RowParticles &, const ColParticles &);
template<unsigned int NI, unsigned int NJ, typename... T>
MatrixReplacement< NI, NJ, std::tuple< typename std::tuple_element< 0, T >::type...> >
create_block_operator(const MatrixReplacement< 1, 1, T > &...);
}
Header </home/travis/build/martinjrobins/Aboria/src/Particles.h>
namespace Aboria {
template<typename VAR, unsigned int DomainD,
template< typename, typename > class VECTOR,
template< typename > class SearchMethod, typename TRAITS_USER>
class Particles;
}
Header </home/travis/build/martinjrobins/Aboria/src/Search.h>
namespace Aboria {
template<typename Query, int LNormNumber> class search_iterator;
template<typename Query> class bucket_pair_iterator;
template<int LNormNumber, typename Query,
typename SearchIterator = search_iterator<Query, LNormNumber> >
SearchIterator
distance_search(const Query &, const typename Query::double_d &,
const double);
template<typename Query,
typename SearchIterator = search_iterator<Query, -1> >
SearchIterator
chebyshev_search(const Query &, const typename Query::double_d &,
const double);
template<typename Query,
typename SearchIterator = search_iterator<Query, 1> >
SearchIterator
manhatten_search(const Query &, const typename Query::double_d &,
const double);
template<typename Query,
typename SearchIterator = search_iterator<Query, 2> >
SearchIterator
euclidean_search(const Query &, const typename Query::double_d &,
const double);
template<typename Query, typename Iterator = bucket_pair_iterator<Query> >
Iterator get_neighbouring_buckets(const Query &);
}
Header </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
namespace Aboria {
template<typename T> struct Symbol;
template<unsigned int I, typename P> struct Label;
template<typename L1, typename L2> struct Dx;
struct Normal;
struct Uniform;
template<typename T, unsigned int N> struct VectorSymbolic;
template<typename T> struct Accumulate;
template<typename T, int LNormNumber = 2,
typename Terminal = typename detail::accumulate_within_distance< T,
mpl::int_<LNormNumber>> >
struct AccumulateWithinDistance;
template<typename T> struct min;
template<typename T> struct max;
template<typename Expr> unspecifed deep_copy(Expr const &);
template<typename Expr> unspecifed eval(Expr &);
template<typename Expr> unspecifed eval(Expr &, unspecifed);
template<typename Expr, typename ParticleReference>
unspecifed eval(Expr &, const ParticleReference &);
template<typename Expr, typename AnyRef>
unspecifed eval(Expr &, const AnyRef &);
template<typename Expr>
unspecifed eval(Expr &, unspecifed, unspecifed, unspecifed);
template<typename Expr, typename AnyRef>
unspecifed eval(Expr &, unspecifed, unspecifed, const AnyRef &);
template<typename Expr, typename AnyRef>
unspecifed eval(Expr &, unspecifed, const AnyRef &, unspecifed);
template<typename Expr, typename AnyDx, typename AnyRef1, typename AnyRef2>
unspecifed eval(Expr &, const AnyDx &, const AnyRef1 &, const AnyRef2 &);
template<typename Expr> unspecifed is_trivially_zero(Expr &);
// returns false for non constant expressions (might be not zero)
template<typename Expr> unspecifed is_trivially_zero(Expr & expr);
// returns true if the expression always evaluates to false
template<typename IfExpr> unspecifed is_trivially_false(IfExpr & expr);
// returns false for non constant expressions (might be not false)
template<typename IfExpr> unspecifed is_trivially_false(IfExpr & expr);
// returns true if the expression always evaluates to true
template<typename IfExpr> unspecifed is_trivially_true(IfExpr & expr);
// returns false for non constant expressions (might be not true)
template<typename IfExpr> unspecifed is_trivially_true(IfExpr & expr);
template<unsigned int I, typename P> Label< I, P > create_label(P & p);
template<typename L1, typename L2> Dx< L1, L2 > create_dx(L1 &, L2 &);
}
Header </home/travis/build/martinjrobins/Aboria/src/Traits.h>
namespace Aboria {
struct default_traits;
template<template< typename, typename > class VECTOR> struct Traits;
template<> struct Traits<std::vector>;
template<> struct Traits<thrust::device_vector>;
template<> struct Traits<thrust::host_vector>;
template<typename ARG, unsigned int DomainD, unsigned int SelfD,
typename TRAITS>
struct TraitsCommon;
template<typename traits, unsigned int DomainD, unsigned int SelfD,
typename... TYPES>
struct TraitsCommon<std::tuple< TYPES...>, DomainD, SelfD, traits>;
}
Header </home/travis/build/martinjrobins/Aboria/src/Utils.h>
namespace Aboria {
template<typename T = void>
void vtkWriteGrid(const char *, int,
vtkSmartPointer< vtkUnstructuredGrid >,
const std::map< std::string, double > & = {});
template<typename PTYPE, typename GTYPE, typename RNDGTYPE>
void create_n_particles_with_rejection_sampling(const unsigned int n,
PTYPE & particles,
const GTYPE & generator_fun,
const Vector< double, 3 > & low,
const Vector< double, 3 > & high,
RNDGTYPE & generator);
template<typename T>
void radial_distribution_function(const T & particles, const double min,
Header </home/travis/build/martinjrobins/Aboria/src/Variable.h>
namespace Aboria {
template<typename T, typename NAME> struct Variable;
}
Header </home/travis/build/martinjrobins/Aboria/src/Vector.h>
UNARY_OPERATOR(the_op)
OPERATOR(the_op)
COMPARISON(the_op)
COMPOUND_ASSIGN(the_op)
UFUNC(the_op)
namespace Aboria {
template<typename T, unsigned int N> class Vector;
template<typename T> struct is_vector;
template<typename T, unsigned int N> struct is_vector<Vector< T, N >>;
template<typename T> struct is_eigen_vector;
template<typename T, int N>
struct is_eigen_vector<Eigen::Matrix< T, N, 1 >>;
template<typename T, typename Enable = void> struct scalar;
template<typename T>
struct scalar<T, typename std::enable_if< std::is_arithmetic< T >::value >::type>;
template<typename T>
struct scalar<T, typename std::enable_if< is_vector< T >::value >::type>;
template<typename T, typename Enable = void> struct dim;
template<typename T>
struct dim<T, typename std::enable_if< std::is_arithmetic< T >::value >::type>;
template<typename T>
struct dim<T, typename std::enable_if< is_vector< T >::value >::type>;
typedef Vector< double, 1 > vdouble1;
typedef Vector< double, 2 > vdouble2;
typedef Vector< double, 3 > vdouble3;
typedef Vector< double, 4 > vdouble4;
typedef Vector< double, 5 > vdouble5;
typedef Vector< double, 6 > vdouble6;
typedef Vector< double, 7 > vdouble7;
typedef Vector< int, 1 > vint1;
typedef Vector< int, 2 > vint2;
typedef Vector< int, 3 > vint3;
typedef Vector< int, 4 > vint4;
typedef Vector< int, 5 > vint5;
typedef Vector< int, 6 > vint6;
typedef Vector< int, 7 > vint7;
typedef Vector< bool, 1 > vbool1;
typedef Vector< bool, 2 > vbool2;
typedef Vector< bool, 3 > vbool3;
typedef Vector< bool, 4 > vbool4;
typedef Vector< bool, 5 > vbool5;
typedef Vector< bool, 6 > vbool6;
typedef Vector< bool, 7 > vbool7;
// returns arg.pow(exponent)
template<typename T, unsigned int N, typename EXP_T>
Vector< T, N > pow(Vector< T, N > arg, EXP_T exponent);
// unary - operator for Vector class
template<typename T, unsigned int N>
Vector< double, N > operator-(const Vector< T, N > & arg1);
// binary + operator for Vector class
template<typename T1, typename T2, unsigned int N,
typename = typename std::enable_if<std::is_arithmetic<T1>::value>::type>
Vector< double, N >
operator+(const T1 & arg1, const Vector< T2, N > & arg2);
operator<(const Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N,
typename = typename std::enable_if<std::is_arithmetic<T2>::value>::type>
Vector< bool, N > operator<(const Vector< T1, N > & arg1, const T2 & arg2);
// binary <= comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< bool, N >
operator<=(const Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N,
typename = typename std::enable_if<std::is_arithmetic<T2>::value>::type>
Vector< bool, N >
operator<=(const Vector< T1, N > & arg1, const T2 & arg2);
// binary >= comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< bool, N >
operator>=(const Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N,
typename = typename std::enable_if<std::is_arithmetic<T2>::value>::type>
Vector< bool, N >
operator>=(const Vector< T1, N > & arg1, const T2 & arg2);
// binary == comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< bool, N >
operator==(const Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N,
typename = typename std::enable_if<std::is_arithmetic<T2>::value>::type>
Vector< bool, N >
operator==(const Vector< T1, N > & arg1, const T2 & arg2);
// binary != comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< bool, N >
operator!=(const Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N,
typename = typename std::enable_if<std::is_arithmetic<T2>::value>::type>
Vector< bool, N >
operator!=(const Vector< T1, N > & arg1, const T2 & arg2);
// compound assign += comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< double, N > &
operator+=(Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N>
Vector< double, N > & operator+=(Vector< T1, N > & arg1, const T2 & arg2);
template<int , int , unsigned int N>
Vector< int, N > &
operator+=(Vector< int, N > & arg1, const Vector< int, N > & arg2);
template<int , int , unsigned int N>
Vector< int, N > & operator+=(Vector< int, N > & arg1, const int & arg2);
// compound assign -= comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< double, N > &
operator-=(Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N>
Vector< double, N > & operator-=(Vector< T1, N > & arg1, const T2 & arg2);
template<int , int , unsigned int N>
Vector< int, N > &
operator-=(Vector< int, N > & arg1, const Vector< int, N > & arg2);
template<int , int , unsigned int N>
Vector< int, N > & operator-=(Vector< int, N > & arg1, const int & arg2);
// compound assign *= comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< double, N > &
operator*=(Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N>
Vector< double, N > & operator*=(Vector< T1, N > & arg1, const T2 & arg2);
template<int , int , unsigned int N>
Vector< int, N > &
operator*=(Vector< int, N > & arg1, const Vector< int, N > & arg2);
template<int , int , unsigned int N>
Vector< int, N > & operator*=(Vector< int, N > & arg1, const int & arg2);
// compound assign /= comparison operator for Vector class
template<typename T1, typename T2, unsigned int N>
Vector< double, N > &
operator/=(Vector< T1, N > & arg1, const Vector< T2, N > & arg2);
template<typename T1, typename T2, unsigned int N>
Vector< double, N > & operator/=(Vector< T1, N > & arg1, const T2 & arg2);
template<int , int , unsigned int N>
Vector< int, N > &
operator/=(Vector< int, N > & arg1, const Vector< int, N > & arg2);
template<int , int , unsigned int N>
Vector< int, N > & operator/=(Vector< int, N > & arg1, const int & arg2);
template<typename T, int I> double norm(const Vector< T, I > &);
// return arg1.squaredNorm()
template<typename T, int I> double squaredNorm(const Vector< T, I > & arg1);
template<typename T1, typename T2, int I>
double dot(const Vector< T1, I > &, const Vector< T2, I > &);
// cross-product function for 3D vectors
template<typename T>
Vector< T, 3 >
cross(const Vector< T, 3 > & arg1, const Vector< T, 3 > & arg2);
// returns the input Vector x (for Eigen)
template<typename T, unsigned int N>
const Vector< T, N > & conj(const Vector< T, N > & x);
// returns the input Vector x (for Eigen)
template<typename T, unsigned int N>
const Vector< T, N > & real(const Vector< T, N > & x);
// returns imaginary component of Vector class (i.e. 0, for Eigen)
template<typename T, unsigned int N>
const Vector< T, N > imag(const Vector< T, N > & x);
template<typename T, unsigned int N>
const Vector< T, N > abs(const Vector< T, N > &);
// element-wise e_i*e_i function for Vector class
template<typename T, unsigned int N>
const Vector< T, N > abs2(const Vector< T, N > & x);
// stream output operator for Vector class
template<typename T, unsigned int N>
std::ostream & operator<<(std::ostream & out, const Vector< T, N > & v);
// stream input operator for Vector class
template<typename T, unsigned int N>
std::istream & operator>>(std::istream & out, Vector< T, N > & v);
}namespace boost {
namespace serialization {
template<typename Archive, typename S, int Rows_, int Cols_, int Ops_,
int MaxRows_, int MaxCols_>
void serialize(Archive & ar,
Eigen::Matrix< S, Rows_, Cols_, Ops_, MaxRows_, MaxCols_ > & matrix,
const unsigned int version);
template<typename Archive, typename S, int Dim_, int Mode_, int Options_>
void serialize(Archive & ar,
Eigen::Transform< S, Dim_, Mode_, Options_ > & transform,
const unsigned int version);
}
}
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Particles.h>
template<typename VAR, unsigned int DomainD,
template< typename, typename > class VECTOR,
template< typename > class SearchMethod, typename TRAITS_USER>
class Particles {
public:
// types
typedef Particles< VAR, DomainD, VECTOR, SearchMethod, TRAITS_USER > particles_type; // This
type.
typedef TraitsCommon< VAR, DomainD, 1, TRAITS_USER > traits_type;
typedef traits_type::value_type value_type; // a
tuple type containing value_types for each Variable
typedef traits_type::reference reference; // a
tuple type containing references to value_types for each Variable
typedef traits_type::const_reference const_reference; // a
tuple type containing const_references to value_types for each Variable
typedef traits_type::raw_pointer raw_pointer; // a
tuple type containing raw references to value_types for each Variable
typedef traits_type::raw_reference raw_reference;
typedef traits_type::raw_const_reference raw_const_reference; // a
tuple type containing raw references to value_types for each Variable
typedef traits_type::data_type data_type; // type
used to hold data (a tuple of vectors)
typedef traits_type::size_type size_type; // type
used to hold and return size information
typedef traits_type::size_type difference_type;
typedef traits_type::iterator iterator;
typedef traits_type::const_iterator const_iterator;
typedef SearchMethod< traits_type > search_type; // the
neighbourhood data structure that the particles will be embedded into
typedef search_type::query_type query_type; // the
query class that is associated with search_type
typedef traits_type::mpl_type_vector mpl_type_vector;
typedef unspecifed elem_by_type;
typedef unspecifed return_type;
typedef Vector< double, dimension > double_d; // a
type to store a vector of doubles with given dimension
typedef Vector< double, dimension > int_d; // a
type to store a vector of doubles with given dimension
typedef Vector< bool, dimension > bool_d; // a
type to store a vector of bool with given dimension
typedef traits_type::position position; // the
tag type for the default position variable
// construct/copy/destruct
Particles();
Particles(const size_t);
Particles(const particles_type &);
Particles(iterator, iterator);
// public member functions
void resize(size_type);
void push_back(const value_type &, bool = true);
void print_data_structure() const;
void set_seed(const uint32_t);
void push_back(const double_d &);
void push_back(const particles_type &);
void pop_back(bool = true);
reference operator[](std::size_t);
const_reference operator[](std::size_t) const;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
void clear();
iterator erase(iterator, const bool = true);
iterator erase(iterator, iterator, const bool = true);
iterator insert(iterator, const value type &);
Description
Each particle has a 3D position and user-defned data-package (for other variables such as velocity, density etc) and is optionally
embedded within a cuboidal spatial domain (for neighbourhood searches) that can be periodic or not. Each particle also has its own
random number generator that is seeded via its own unique id.
For example, the following creates a set of particles which each have (along with the standard variables such as position, id etc) a data
package consisting of one double variable type named scalar.
See Also:
ABORIA_VARIABLE
The traits type used to build up the Particle container. Contains Level 0 vector class and dimension information
a tuple type containing raw references to value_types for each Variable note that this is only different from reference when using a
thrust::device_vector level 0 vector
type used to hold and return the difference of iterator, or distance between
See Also:
zip_iterator
See Also:
zip_iterator
a boost mpl vector type containing a vector of Variable attached to the particles (includes position, id and alive fag as well as all
user-supplied variables)
range-based copy-constructor. performs deep copying of all particles from frst to last
Note that if new particles are created, they are NOT added to the neighbour search structure, and might be outside the domain
Parameters:
n the new size of the container
push the particle val to the back of the container (if it is within the searchable domain)
See Also:
update_positions()
Parameters:
update_neighbour_search the default is to update the neighbour search set this to false to
not update
val the value_type to add
Print to stdout the current state of the internal neighbourhood data structure. Used for debugging purposes
set the base seed of the container. Note that the random number generator for each particle is set to value plus the particle's id
push a new particle with position position to the back of the container. All other variables for the new particle are left at the
defaults
Parameters:
update_neighbour_search by default update the neighbour data structure. Set this to false to
turn off the update
See Also:
update_positions
Parameters:
i erase particle pointed to by i. This simply sets the id variable of
that particle to false and (if
update_neighbour_search==true) calls ::update_positions
update_neighbour_search by default this function will update the neighbour search data
structure. Set this to false to turn off update
See Also:
erase(iterator)
Parameters:
update_neighbour_search By default this updates the neighbourhood data structure. Set to
false to turn off this update
Note that this will copy across the id, generator and alive variables from val, which might confict with particles already in the
container (e.g. the new container might have identical ids or generators, which are generally assumed to be unique).
Note that this will copy across the id, generator and alive variables from val, which might confict with particles already in the
container (e.g. the new container might have identical ids or generators, which are generally assumed to be unique).
Note that this will copy across the id, generator and alive variables from the range, which might confict with particles already
in the container (e.g. the new container might have identical ids or generators, which are generally assumed to be unique).
23. void init_neighbour_search(const double_d & low, const double_d & high,
const bool_d & periodic,
const double n_particles_in_leaf = 10.0);
initialise the neighbourhood searching for the particle container. The neighbourhood searching is performed over a cuboidal domain
from low to high.
Parameters:
high the highest point in the search domain
low the lowest point in the search domain
n_particles_in_leaf By default the neighbourhood data structure will have either an
average (cell-list) or a maximum of this number of particles within each
bucket. Set this argument to change this number
periodic a boolean 3d vector indicating whether each dimension is periodic
(true) or not (false)
Initialise the "search by id" functionality. This will switch on the creation and updating of an internal data structure to enable search
by id.
See Also:
::init_neighbour_search()
Returns the query_type object that can be used for neighbourhood queries. This object is designed to be as lightweight as possible
so that it can by copied (for example to the GPU)
takes an vector uncorrected_dx that might come from the difference between two particle positions, and returns the shortest
possible dx, according to the periodicity of the domain
See Also:
init_neighbour_search()
See Also:
init_neighbour_search()
See Also:
init_neighbour_search()
See Also:
init_neighbour_search()
A neighbourhood search data structure can be ordered (i.e. the order of the particles in the container is important) or not.
Update the neighbourhood search data for particles between update_begin and update_end (not including update_end).
This function must be called after altering the particle positions (e.g. with set<position>(particle,new_position)) in order
for accurate neighbourhood searching. This function will also delete any particles that have their alive fags set to false. If any
particles within the range have alive==false, then the update_end iterator must be the same as that returned by end()
Update the neighbourhood search data for all particles in the container
This function must be called after altering the particle positions (e.g. with set<position>(particle,new_position)) in order
for accurate neighbourhood searching. This function will also delete any particles that have their alive fags set to false.
get a vtk unstructured grid version of the particle container This grid is cached internally. The frst time this function is called the grid
is created and updated with the particle data. If the particle data is updated subsequently you need to set refresh=true for the
grid to be updated
update the particle data according to a supplied VTK unstructured grid it is assumed that grid has been generated from
copy_to_vtk_grid() or get_grid()
See Also:
get_grid()
copy_to_vtk_grid()
Used by update_particles(). The parameters update_begin and update_end are the same as given to update_particles(). This
function reorders particles within this range according to the order_start and order_end range, using a gather.
2. template<typename InputIterator>
iterator insert_dispatch(iterator position, InputIterator frst,
InputIterator last, std::false_type);
3. template<typename InputIterator>
iterator insert_dispatch(iterator position, InputIterator frst,
InputIterator last, std::true_type);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
Description
get a variable from a particle arg
See Also:
ABORIA_VARIABLE
Parameters:
arg the particle
the object with type ValueType
Template Parameters:
T the variable type to get,
ValueType the getter_type, zip_iterator, zip_pointer, or Particles
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T, unsigned int N>
class Vector {
public:
// types
typedef T value_type;
// construct/copy/destruct
Vector();
Vector(T, T);
Vector(T, T, T);
Vector(T, T, T, T);
Vector(const Vector< T, N > &);
template<typename Derived> Vector(const Eigen::DenseBase< Derived > &);
template<typename T2> Vector(const Vector< T2, N > &);
template<typename T2> Vector& operator=(Vector< T2, N > &);
template<typename T2> Vector& operator=(T2 *);
template<typename Derived>
Vector& operator=(const Eigen::DenseBase< Derived > &);
// public member functions
const T & operator[](unsigned int) const;
T & operator[](unsigned int);
template<typename T2> double inner_product(const Vector< T2, N > &) const;
template<typename T2> Vector< T2, N > cast();
template<typename T2> double dot(const Vector< T2, N > &) const;
double squaredNorm() const;
double norm() const;
double inf_norm() const;
template<typename EXP_T> Vector< T, N > pow(const EXP_T);
void normalize();
bool all() const;
bool any() const;
T minCoeff() const;
T maxCoeff() const;
T prod() const;
T * data();
template<typename Archive> void serialize(Archive &, const unsigned int);
// public static functions
static Vector Zero();
static Vector Constant(const T &);
// public data members
static const int size;
};
Description
Normal C++ operators ('*','/','<' etc.) operate on this vector class in an element-wise fashion.
Parameters:
arg1 All the elements of the vector are set to this value Constructs an vector with initial values.
The frst element is set to this value
arg2 The second element is set to this value
Parameters:
arg1 The frst element is set to this value
arg2 The second element is set to this value
arg3 The third element is set to this value
Parameters:
arg1 The frst element is set to this value
arg2 The second element is set to this value
arg3 The third element is set to this value
arg4 The fourth element is set to this value
Vector copy-constructor
Parameters:
arg constructs a vector as a copy of this arguement
Vector assignment
Assigns a vector with different type T2 but same length N to this vector
Parameters:
arg Assigns the frst N values from arg to this vector.
Parameters:
arg Vector-like object (with index operator)
Parameters:
n the element number to index
Index operator
Parameters:
n the element number to index
3. template<typename T2> double inner_product(const Vector< T2, N > & arg) const;
inner product
Returns: the inner product (dot product) of this vector with arg
5. template<typename T2> double dot(const Vector< T2, N > & arg) const;
inner product
See Also:
inner_product
Returns: The inner product (dot product) of this vector with arg
squared norm
2-norm
inf-norm
See Also:
norm
Returns: the accumulated & of all the vectors elements, i.e. v_1 & v_2 & v3 & ...
Returns: the accumulated | of all the vectors elements, i.e. v_1 | v_2 | v3 | ...
16. T * data();
returns the raw memory array containing the data for the vector
Zero Vector
Vector
Constant
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename Tuple, typename MplVector>
struct getter_type {
};
Description
Template Parameters
1. typename Tuple
2. typename MplVector
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Utils.h>
template<typename T = void>
void vtkWriteGrid(const char * name, int timestep,
vtkSmartPointer< vtkUnstructuredGrid > grid,
const std::map< std::string, double > & felds = {});
Description
Write a vtk unstructured grid to a flename of the form: printf("name%05d",timestep). User can optionally provide felds, which is a set of
key/value pairs (e.g. "time"->0.1) written as additional felds to the fle
Parameters:
felds a std::map of additional felds to write
grid the grid to write to the fle
name the base flename
timestep the index in the flename
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Search.h>
Description
Uses the euclidean distance https://en.wikipedia.org/wiki/Euclidean_distance
Parameters:
centre the central point of the search
max_distance the maximum distance to search around centre
query the query object
Template Parameters:
Query the query object type
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Search.h>
Description
Uses the manhatten distance https://en.wikipedia.org/wiki/Taxicab_geometry
Parameters:
centre the central point of the search
max_distance the maximum distance to search around centre
query the query object
Template Parameters:
Query the query object type
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Search.h>
template<typename Query,
typename SearchIterator = search_iterator<Query, -1> >
SearchIterator
chebyshev_search(const Query & query,
const typename Query::double_d & centre,
const double max_distance);
Description
Uses the chebyshev distance https://en.wikipedia.org/wiki/Chebyshev_distance
Parameters:
centre the central point of the search
max_distance the maximum distance to search around centre
query the query object
Template Parameters:
Query the query object type
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Search.h>
Description
Parameters:
centre the central point of the search
max_distance the maximum distance to search around centre
query the query object
Template Parameters:
Query the query object type
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Search.h>
template<typename Query, int LNormNumber>
class search_iterator {
public:
// types
typedef p_pointer pointer;
typedef std::forward_iterator_tag iterator_category;
typedef p_reference reference;
typedef p_value_type value_type;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
search_iterator();
search_iterator(const Query &, const double_d &, const double);
// public static functions
static periodic_iterator_type get_periodic_range(const bool_d);
// public member functions
const double_d & dx() const;
reference operator*() const;
reference operator->();
search_iterator & operator++();
search_iterator operator++(int);
size_t operator-(search_iterator) const;
size_t distance_to_end() const;
bool operator==(const search_iterator &);
bool operator!=(const search_iterator &);
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool equal(search_iterator const &) const;
bool equal(const bool) const;
bool get_valid_bucket();
bool get_valid_candidate();
bool go_to_next_candidate();
bool check_candidate();
void increment();
reference dereference() const;
};
Description
A const iterator to a set of neighbouring points. This iterator implements a STL forward iterator type
should generally use this constructor to make a search iterator. Returns an iterator that will search around the given point, and
iterate through all the particles it fnds within the given maximum distance
Parameters:
max_distance the maximum distance to search
query a query object for a spatial data structure
r the central point to search around
returns iterator for periodic lattice, given the periodicity of the domain
returns the distance $r_b-r_a$ between the current candidate position $r_b$ an the central search point $r_a$
3. reference operator->();
5. search_iterator operator++(int);
post increment the iterator, i.e. move to the next candidate particle and return the original iterator
returns how many candidate particle to go until the iterator becomes invalid
the search iterator can be converted to true if it is pointing to a valid candidate point, false otherwise
the search iterator can be converted to true if it is pointing to a valid candidate point, false otherwise
if both iterators are valid, and pointing to the same particle, then they are equal
3. bool get_valid_bucket();
to be called after incrementing m_current_bucket. If m_current bucket is no longer valid, then move to the next periodic lattice. If not
more periodic lattices to search through, then the iterator becomes invalid
4. bool get_valid_candidate();
to be called after incrementing m_current_particle. If m_current_particle is invalid, then move to the next bucket
5. bool go_to_next_candidate();
6. bool check_candidate();
checks that the current particle in m_current_particle is within the search distance
7. void increment();
main increment function, iterates internal iterators until a candidate particle is found (i.e. one within the search distance)
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
template<typename Traits>
class CellList : public Aboria::neighbour_search_base< CellList< Traits >, Traits, CellListQuery<
Traits > >
{
public:
// member classes/structs/unions
// function object to copy a range of particles to another index range
struct copy_points_in_bucket_lambda {
// construct/copy/destruct
copy_points_in_bucket_lambda(size_t, size_t, size_t, int *, int *);
// public member functions
void operator()(const int);
// public data members
int * m_linked_list;
int * m_buckets;
size_t start_index_deleted;
size_t start_index_copied;
size_t end_index_copied;
};
// function object to delete a range of particles within the buckets
struct delete_points_in_bucket_lambda {
// construct/copy/destruct
delete_points_in_bucket_lambda(int, int, int *, int *);
// public member functions
void operator()(const int);
// public data members
int * m_linked_list;
int * m_buckets;
int start_index_deleted;
int end_index_deleted;
};
// thread-safe function object to insert a list of non-consecutive particles
// into the data structure
struct insert_points_lambda_non_sequential {
// types
typedef Traits::double_d double_d;
typedef unspecifed ptobl_type;
// construct/copy/destruct
insert_points_lambda_non_sequential(double_d *, int *, const ptobl_type &,
int *, int *, int *, int);
// public member functions
void operator()(const int);
// public data members
double_d * m_positions;
int * m_alive_indices;
ptobl_type m_point_to_bucket_index;
int * m_buckets;
int * m_dirty_buckets;
int * m_linked_list;
int start;
};
// non-threadsafe function object to insert a non-consecutive list of
// particles into the data structure
struct insert points lambda non sequential serial {
// types
typedef Traits::double_d double_d;
typedef unspecifed ptobl_type;
// construct/copy/destruct
insert_points_lambda_non_sequential_serial(double_d *, int *,
const ptobl_type &, int *,
int *, int *, int *, int);
// public member functions
void operator()(const int);
// public data members
double_d * m_positions;
int * m_alive_indices;
ptobl_type m_point_to_bucket_index;
int * m_buckets;
int * m_dirty_buckets;
int * m_linked_list;
int * m_linked_list_reverse;
int start;
};
// thread-safe function object to insert a list of consecutive particles
// into the data structure
struct insert_points_lambda_sequential {
// types
typedef Traits::double_d double_d;
typedef unspecifed ptobl_type;
// construct/copy/destruct
insert_points_lambda_sequential(double_d *, const ptobl_type &, int *,
int *, int *, int);
// public member functions
void operator()(const int);
// public data members
double_d * m_positions;
ptobl_type m_point_to_bucket_index;
int * m_buckets;
int * m_dirty_buckets;
int * m_linked_list;
int start;
};
// non-threadsafe insert a consecutive vector of particles into the data
// structure
struct insert_points_lambda_sequential_serial {
// types
typedef Traits::double_d double_d;
typedef unspecifed ptobl_type;
// construct/copy/destruct
insert_points_lambda_sequential_serial(double_d *, const ptobl_type &,
int *, int *, int *, int *, int);
// public member functions
void operator()(const int);
// public data members
double_d * m_positions;
ptobl_type m_point_to_bucket_index;
int * m_buckets;
int * m_dirty_buckets;
int * m_linked_list;
int * m_linked_list_reverse;
int start;
};
// construct/copy/destruct
CellList();
// public member functions
void print_data_structure() const;
// public static functions
static constexpr bool ordered();
// private member functions
bool set_domain_impl();
void check_data_structure();
void update_iterator_impl();
void update_positions_impl(iterator, iterator, const int, const bool = true);
void insert_points(typename vector_int::iterator,
typename vector_int::iterator, const int);
void insert_points(const int, const int);
const CellListQuery< Traits > & get_query_impl() const;
CellListQuery< Traits > & get_query_impl();
};
Description
This class implements neighbourhood searching using a bucket search, or cell list algorithm. The domain is frst divided up into a regular
grid of constant size "buckets".
After the buckets are created, a set of 3D points can be assigned to their respective buckets. After this, neighbourhood queries around a
given point can be performed be looking at all the points in the same bucket or surrounding buckets of the given point.
This structure is not ordered. That is, the order of the particles is not important to the search algorithm. Instead, the indicies of the
particles are kept in a linked list.
Returns: true if this function wishes to trigger a reconstruction of the data structure (i.e. resize the buckets and re-insert
all the particles to the linked list) set
2. void check_data_structure();
3. void update_iterator_impl();
Needs to handle: dead particles (only if update_end == m_particles_end), particles with different positions, and new particles
Parameters:
call_set_domain set to true (the default) if set_domain_impl() needs to be called
num_new_particles_added number of new particles to be added
update_begin iterator to the beginning of the update range
update_end iterator to the end of the update range
Parameters:
start the index of the particle set to start adding (the start of the update range)
start_adding iterator to the start of the list of indices to be inserted
stop_adding iterator to the end of the list of indices to be inserted
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
template<typename Traits>
struct CellListQuery : public Aboria::NeighbourQueryBase< Traits > {
// types
typedef Traits traits_type;
typedef Traits::raw_pointer raw_pointer;
typedef Traits::double_d double_d;
typedef Traits::bool_d bool_d;
typedef Traits::int_d int_d;
typedef Traits::unsigned_int_d unsigned_int_d;
typedef Traits::reference particle_reference;
typedef Traits::const_reference particle_const_reference;
typedef lattice_iterator_within_distance< CellListQuery, LNormNumber > query_iterator;
typedef lattice_iterator< dimension > all_iterator;
typedef lattice_iterator< dimension > child_iterator;
typedef query_iterator< 2 >::reference reference;
typedef query_iterator< 2 >::pointer pointer;
typedef query_iterator< 2 >::value_type value_type;
typedef linked_list_iterator< Traits > particle_iterator;
typedef bbox< dimension > box_type;
// construct/copy/destruct
CellListQuery();
// public member functions
raw_pointer fnd(const size_t) const;
child_iterator get_children() const;
child_iterator get_children(const child_iterator &) const;
size_t num_children() const;
const box_type get_bounds(const child_iterator &) const;
const box_type & get_bounds() const;
const bool_d & get_periodic() const;
particle_iterator get_bucket_particles(const reference) const;
bbox< dimension > get_bucket_bbox(const reference) const;
child_iterator get_bucket(const double_d &) const;
size_t get_bucket_index(const reference) const;
template<int LNormNumber = -1>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double) const;
template<int LNormNumber = -1>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double_d &) const;
const int_d & get_end_bucket() const;
all_iterator get_subtree(const child_iterator &) const;
all_iterator get_subtree() const;
size_t number_of_buckets() const;
size_t number_of_particles() const;
const raw_pointer & get_particles_begin() const;
raw_pointer & get_particles_begin();
unsigned number_of_levels() const;
// public static functions
static bool is_leaf_node(const value_type &);
static bool is_tree();
static size_t num_children(const child_iterator &);
// public data members
static const unsigned int dimension;
bool_d m_periodic; // periodicity of domain
double_d m_bucket_side_length; // bucket length in each dimension
int_d m_end_bucket; // index of last bucket
bbox< dimension > m_bounds; // domain min/max bounds
unspecifed m_point_to_bucket_index; // function object to calculate a bucket index from a
position
raw_pointer m_particles_begin; // pointer to the beginning of the particle set
raw_pointer m_particles_end; // pointer to the end of the particle set
int * m_buckets_begin; // pointer to the beginning of the buckets
int * m_linked_list_begin; // pointer to the beginning of the linked list
size_t * m_id_map_key; // pointer to the fnd-by-id map key
size t * m id map value; // pointer to the fnd-by-id map value
};
Description
This object is designed to be used within algorithms or gpu kernels, and can be obtained from a Particles type using the
Particles::get_query() function
Note that if you wish to run this on a gpu using Trust, you need to copy the query object to the kernel, and mark the lambda function as a
device function
Template Parameters
1. typename Traits
constructor checks that we are not using std::vector and cuda at the same time
implement fnd-by-id
Parameters:
id the id of the particle to fnd
Returns: pointer to the particle found, or a pointer to the end of the particle set if not found
for CellList this is all the buckets (fat tree with one root node, all the rest leafs)
Returns: a child_iterator that iterates through all the buckets in the data structure
Parameters:
ci this fuction returns all the children of ci
returns a particle_iterator range to all the particles within the given bucket
Parameters:
bucket a reference to the bucket in question
Parameters:
position (input)
This function can use multiple p-norm distance types by setting LNormNumber, and uses a isotropic distance value given by
max_distance. Note that only buckets within the domain are returned, and periodicity is not taken into account
See Also:
lattice_iterator_within_distance
Parameters:
max_distance the maximum distance of the buckets to be returned
position the position to search around
This function can use multiple p-norm distance types by setting LNormNumber, and uses a isotropic distance value given by
max_distance. Note that only buckets within the domain are returned, and periodicity is not taken into account
See Also:
lattice_iterator_within_distance
Parameters:
max_distance the maximum distance of the buckets to be returned
position the position to search around
Parameters:
ci the child_iterator to search under
Can use this range to loop through all the buckets in the data structure, wether it is a tree or not
can use this and number_of_particles() to loop through all the particles
can use this and number_of_particles() to loop through all the particles
given a reference to a bucket, checks if that bucket is a leaf (i.e. does not have any children)
Parameters:
bucket the bucket to check
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellListOrdered.h>
template<typename Traits>
class CellListOrdered : public Aboria::neighbour_search_base< CellListOrdered< Traits >, Traits,
CellListOrderedQuery< Traits > >
{
public:
// construct/copy/destruct
CellListOrdered();
// public member functions
void print_data_structure() const;
// public static functions
static constexpr bool ordered();
// private member functions
bool set_domain_impl();
void update_iterator_impl();
void update_positions_impl(iterator, iterator, const int, const bool = true);
const CellListOrderedQuery< Traits > & get_query_impl() const;
CellListOrderedQuery< Traits > & get_query_impl();
};
Description
This class implements neighbourhood searching using a cell list. That is, the domain is divided up into a regular grid of constant size
"buckets", and particles are assigned to their containing bucket.
The main difference between this class and CellList is that the particle set is reordered according to which cell each particle belongs to.
This correlates memory locality with spatial locality, and improves cache access if you are often looping over neighbouring particles. It also
mean that particles within a given bucket are sequential in memory.
2. void update_iterator_impl();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellListOrdered.h>
template<typename Traits>
struct CellListOrderedQuery : public Aboria::NeighbourQueryBase< Traits > {
// types
typedef Traits traits_type;
typedef Traits::raw_pointer raw_pointer;
typedef Traits::double_d double_d;
typedef Traits::bool_d bool_d;
typedef Traits::int_d int_d;
typedef Traits::unsigned_int_d unsigned_int_d;
typedef lattice_iterator_within_distance< CellListOrderedQuery, LNormNumber > query_iterator;
typedef lattice_iterator< dimension > all_iterator;
typedef lattice_iterator< dimension > child_iterator;
typedef query_iterator< 2 >::reference reference;
typedef query_iterator< 2 >::pointer pointer;
typedef query_iterator< 2 >::value_type value_type;
typedef ranges_iterator< Traits > particle_iterator;
typedef bbox< dimension > box_type;
// construct/copy/destruct
CellListOrderedQuery();
// public member functions
raw_pointer fnd(const size_t) const;
child_iterator get_children() const;
child_iterator get_children(const child_iterator &) const;
size_t num_children() const;
const box_type get_bounds(const child_iterator &) const;
const box_type & get_bounds() const;
const bool_d & get_periodic() const;
particle_iterator get_bucket_particles(const reference) const;
bbox< dimension > get_bucket_bbox(const reference) const;
child_iterator get_bucket(const double_d &) const;
size_t get_bucket_index(const reference) const;
template<int LNormNumber = -1>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double) const;
template<int LNormNumber = -1>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double_d &) const;
const int_d & get_end_bucket() const;
all_iterator get_subtree(const child_iterator &) const;
all_iterator get_subtree() const;
size_t number_of_buckets() const;
size_t number_of_particles() const;
const raw_pointer & get_particles_begin() const;
raw_pointer & get_particles_begin();
unsigned number_of_levels() const;
// public static functions
static bool is_leaf_node(const value_type &);
static bool is_tree();
static size_t num_children(const child_iterator &);
// public data members
static const unsigned int dimension;
raw_pointer m_particles_begin; // pointer to the beginning of the particle set
raw_pointer m_particles_end; // pointer to the end of the particle set
bool_d m_periodic; // periodicity of the domain
double_d m_bucket_side_length; // dimensions of each bucket
int_d m_end_bucket; // index of the last bucket in the cell list
bbox< dimension > m_bounds; // min/max bounds of the domain
unspecifed m_point_to_bucket_index; // function object to transform a point to a bucket index
unsigned int * m_bucket_begin; // pointer to the beginning of the buckets
unsigned int * m_bucket_end; // pointer to the end of the buckets
unsigned int m_nbuckets; // the number of buckets
size_t * m_id_map_key; // a pointer to the "key" values of the fnd-by-id map
size_t * m_id_map_value; // a pointer to the "value" values of the fnd-by-id map
};
Description
This object is designed to be used within algorithms or gpu kernels, and can be obtained from a Particles type using the
Particles::get_query() function
Note that if you wish to run this on a gpu using Trust, you need to copy the query object to the kernel, and mark the lambda function as a
device function
Template Parameters
1. typename Traits
implement fnd-by-id
Parameters:
id the id of the particle to fnd
Returns: pointer to the particle found, or a pointer to the end of the particle set if not found
Returns: a child_iterator that iterates through all the buckets in the data structure
Parameters:
ci this fuction returns all the children of ci
returns a particle_iterator range to all the particles within the given bucket
Parameters:
bucket a reference to the bucket in question
Parameters:
position (input)
This function can use multiple p-norm distance types by setting LNormNumber, and uses a isotropic distance value given by
max_distance. Note that only buckets within the domain are returned, and periodicity is not taken into account
Parameters:
max_distance the maximum distance of the buckets to be returned
position the position to search around
This function can use multiple p-norm distance types by setting LNormNumber, and uses a isotropic distance value given by
max_distance. Note that only buckets within the domain are returned, and periodicity is not taken into account
Parameters:
max_distance the maximum distance of the buckets to be returned
position the position to search around
Parameters:
ci the child_iterator to search under
Can use this range to loop through all the buckets in the data structure, wether it is a tree or not
can use this and number_of_particles() to loop through all the particles
can use this and number_of_particles() to loop through all the particles
given a reference to a bucket, checks if that bucket is a leaf (i.e. does not have any children)
Parameters:
bucket the bucket to check
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Search.h>
Description
Parameters:
query the query object
Template Parameters:
Query query object type (must be CellListQuery or CellListOrderedQuery)
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kdtree.h>
template<typename Traits>
class Kdtree : public Aboria::neighbour_search_base< Kdtree< Traits >, Traits, KdtreeQuery< Traits
> >
{
public:
// construct/copy/destruct
Kdtree();
// public member functions
void print_data_structure() const;
// public static functions
static constexpr bool ordered();
// private member functions
void set_domain_impl();
void update_iterator_impl();
void print_tree() const;
void print_level(int, int) const;
void update_positions_impl(iterator, iterator, const int, const bool = true);
const KdtreeQuery< Traits > & get_query_impl() const;
KdtreeQuery< Traits > & get_query_impl();
void build_tree();
};
Description
2. void update_iterator_impl();
8. void build_tree();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kdtree.h>
template<typename Traits>
struct KdtreeQuery {
// types
typedef Traits traits_type;
typedef Traits::raw_pointer raw_pointer;
typedef Traits::double_d double_d;
typedef Traits::bool_d bool_d;
typedef Traits::int_d int_d;
typedef Traits::unsigned_int_d unsigned_int_d;
typedef tree_query_iterator< KdtreeQuery, LNormNumber > query_iterator;
typedef depth_frst_iterator< KdtreeQuery > all_iterator;
typedef KdtreeChildIterator< KdtreeQuery > child_iterator;
typedef child_iterator::value_type value_type;
typedef child_iterator::reference reference;
typedef child_iterator::pointer pointer;
typedef ranges_iterator< Traits > particle_iterator;
typedef bbox< dimension > box_type;
// public member functions
const box_type & get_bounds() const;
const bool_d & get_periodic() const;
raw_pointer fnd(const size_t) const;
bool is_leaf_node(reference) const;
child_iterator get_children() const;
child_iterator get_children(const child_iterator &) const;
size_t num_children() const;
size_t num_children(const child_iterator &) const;
const box_type get_bounds(const child_iterator &) const;
particle_iterator get_bucket_particles(reference) const;
void go_to(const double_d &, child_iterator &) const;
child_iterator get_bucket(const double_d &) const;
size_t get_parent_index(const child_iterator &) const;
const box_type & get_parent_bounds(const child_iterator &) const;
size_t get_bucket_index(reference) const;
size_t number_of_buckets() const;
template<int LNormNumber>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double) const;
template<int LNormNumber>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double_d &) const;
all_iterator get_subtree(const child_iterator &) const;
all_iterator get_subtree() const;
size_t number_of_particles() const;
raw_pointer get_particles_begin() const;
unsigned number_of_levels() const;
// private member functions
int get_parent_index(reference) const;
int get_child_index(reference) const;
// public static functions
static bool is_tree();
// public data members
static const unsigned int dimension;
static const unsigned int m_max_tree_depth;
bool_d m_periodic;
bbox< dimension > m_bounds;
raw_pointer m_particles_begin;
raw_pointer m_particles_end;
size_t m_number_of_buckets;
size_t m_number_of_levels;
int * m_nodes_child;
int * m_nodes_split_dim;
double * m_nodes_split_pos;
size_t * m_id_map_key;
size_t * m_id_map_value;
};
Description
This object is designed to be used within algorithms or gpu kernels, and can be obtained from a Particles type using the
Particles::get_query() function
Note that if you wish to run this on a gpu using Trust, you need to copy the query object to the kernel, and mark the lambda function as a
device function
Template Parameters
1. typename Traits
11. void go_to(const double_d & position, child_iterator & ci) const;
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NanoFlannAdaptor.h>
template<typename Traits>
class KdtreeNanofann : public Aboria::neighbour_search_base< KdtreeNanofann< Traits >, Traits,
KdtreeNanofannQuery< Traits > >
{
public:
// construct/copy/destruct
KdtreeNanofann();
// public member functions
size_t kdtree_get_point_count() const;
double kdtree_distance(const double *, const size_t, size_t) const;
double kdtree_get_pt(const size_t, int) const;
template<typename BBOX> bool kdtree_get_bbox(BBOX &) const;
void print_data_structure() const;
// public static functions
static constexpr bool ordered();
// private member functions
void set_domain_impl();
void end_list_of_copies_impl();
void update_iterator_impl();
void print_tree(const node_type *) const;
void print_level(std::vector< const node_type * > &) const;
void update_positions_impl(iterator, iterator, const int, const bool = true);
const KdtreeNanofannQuery< Traits > & get_query_impl() const;
KdtreeNanofannQuery< Traits > & get_query_impl();
};
Description
This class implements neighbourhood searching using a bucket search algorithm. The domain is frst divided up into a regular grid of
constant size "buckets", either by using the class constructor to initialise the domain extents, bucket size etc., or by using the reset()
member function to reset these parameters.
After the buckets are created, a set of 3D points can be assigned to their respective buckets using the embed_points() member function.
After this, neighbourhood queries around a given point can be performed using fnd_broadphase_neighbours(), which returns a const
iterator to all the points in the same bucket or surrounding buckets of the given point.
2. void end_list_of_copies_impl();
3. void update_iterator_impl();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NanoFlannAdaptor.h>
template<typename Traits>
struct KdtreeNanofannQuery {
// types
typedef unspecifed kd_tree_type;
typedef kd_tree_type::Node value_type;
typedef const value_type & reference;
typedef const value_type * pointer;
typedef Traits traits_type;
typedef Traits::raw_pointer raw_pointer;
typedef Traits::double_d double_d;
typedef Traits::bool_d bool_d;
typedef Traits::int_d int_d;
typedef Traits::unsigned_int_d unsigned_int_d;
typedef tree_query_iterator< KdtreeNanofannQuery, LNormNumber > query_iterator;
typedef value_type * root_iterator;
typedef depth_frst_iterator< KdtreeNanofannQuery > all_iterator;
typedef nanofann_child_iterator< Traits > child_iterator;
typedef ranges_iterator< Traits > particle_iterator;
typedef bbox< dimension > box_type;
// public member functions
const box_type & get_bounds() const;
const bool_d & get_periodic() const;
raw_pointer fnd(const size_t) const;
child_iterator get_children() const;
child_iterator get_children(reference, const box_type &) const;
size_t num_children() const;
size_t num_children(const child_iterator &) const;
particle_iterator get_bucket_particles(reference) const;
child_iterator get_bucket(const double_d &) const;
size_t get_bucket_index(reference) const;
size_t number_of_buckets() const;
template<int LNormNumber>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double) const;
template<int LNormNumber>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double_d &) const;
iterator_range< root_iterator > get_root_buckets() const;
all_iterator get_subtree(const child_iterator &) const;
all_iterator get_subtree() const;
size_t number_of_particles() const;
raw_pointer get_particles_begin() const;
unsigned number_of_levels() const;
// public static functions
static bool is_leaf_node(reference);
static bool is_tree();
static size_t get_dimension_index(reference);
static double get_cut_low(reference);
static double get_cut_high(reference);
static pointer get_child1(pointer);
static pointer get_child2(pointer);
static child_iterator get_children(const child_iterator &);
static const box_type get_bounds(const child_iterator &);
// public data members
static const unsigned int dimension;
static const unsigned int m_max_tree_depth;
bool_d m_periodic;
bbox< dimension > m_bounds;
raw_pointer m_particles_begin;
raw_pointer m_particles_end;
size_t m_number_of_buckets;
size_t m_number_of_levels;
value_type * m_root;
value_type m_dummy_root;
size_t * m_id_map_key;
size t * m id map value;
};
Description
This object is designed to be used within algorithms or gpu kernels, and can be obtained from a Particles type using the
Particles::get_query() function
Note that if you wish to run this on a gpu using Trust, you need to copy the query object to the kernel, and mark the lambda function as a
device function
Template Parameters
1. typename Traits
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
template<typename Traits>
struct HyperOctreeQuery {
// types
typedef Traits traits_type;
typedef Traits::raw_pointer raw_pointer;
typedef Traits::double_d double_d;
typedef Traits::bool_d bool_d;
typedef Traits::int_d int_d;
typedef Traits::unsigned_int_d unsigned_int_d;
typedef tree_query_iterator< HyperOctreeQuery, LNormNumber > query_iterator;
typedef depth_frst_iterator< HyperOctreeQuery > root_iterator;
typedef depth_frst_iterator< HyperOctreeQuery > all_iterator;
typedef octree_child_iterator< dimension > child_iterator;
typedef child_iterator::reference reference;
typedef child_iterator::pointer pointer;
typedef child_iterator::value_type value_type;
typedef bbox< dimension > box_type;
typedef ranges_iterator< Traits > particle_iterator;
// public member functions
raw_pointer fnd(const size_t) const;
const box_type & get_bounds() const;
const bool_d & get_periodic() const;
child_iterator get_children() const;
child_iterator get_children(reference, const box_type &) const;
child_iterator get_children(const child_iterator &) const;
particle_iterator get_bucket_particles(reference) const;
child_iterator get_bucket(const double_d &) const;
size_t get_bucket_index(reference) const;
size_t number_of_buckets() const;
template<int LNormNumber>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double) const;
template<int LNormNumber>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double_d &) const;
iterator_range< root_iterator > get_root_buckets() const;
all_iterator get_subtree(const child_iterator &) const;
all_iterator get_subtree() const;
size_t number_of_particles() const;
unsigned number_of_levels() const;
const raw_pointer & get_particles_begin() const;
raw_pointer & get_particles_begin();
// public static functions
static bool is_leaf_node(reference);
static bool is_tree();
static size_t num_children();
static size_t num_children(const child_iterator &);
static box_type get_bounds(const child_iterator &);
// public data members
static const unsigned int dimension;
static const unsigned int m_max_tree_depth;
bool_d m_periodic;
box_type m_bounds;
raw_pointer m_particles_begin;
raw_pointer m_particles_end;
size_t m_number_of_nodes;
unsigned m_number_of_levels;
vint2 * m_leaves_begin;
int * m_nodes_begin;
size_t * m_id_map_key;
size_t * m_id_map_value;
};
Description
This object is designed to be used within algorithms or gpu kernels, and can be obtained from a Particles type using the
Particles::get_query() function
Note that if you wish to run this on a gpu using Trust, you need to copy the query object to the kernel, and mark the lambda function as a
device function
Template Parameters
1. typename Traits
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Traits>
struct NeighbourQueryBase {
// types
typedef Traits::raw_pointer raw_pointer;
typedef Traits::double_d double_d;
typedef Traits::bool_d bool_d;
typedef Traits::int_d int_d;
typedef Traits::unsigned_int_d unsigned_int_d;
typedef Traits::reference particle_reference;
typedef Traits::const_reference particle_const_reference;
typedef bbox< dimension > box_type;
typedef query_iterator< 2 >::reference reference; // A reference to a bucket in
the tree.
typedef query_iterator< 2 >::pointer pointer; // A pointer to a bucket in the
tree.
typedef query_iterator< 2 >::value_type value_type; // A value_type for a bucket in
the tree.
// member classes/structs/unions
// An iterator that steps through all the buckets in the tree (depth-frst)
struct all_iterator {
};
// An iterator that steps through the children of a single bucket in the
// tree.
struct child_iterator {
};
// An iterator that steps through the particles within a given bucket.
struct particle_iterator {
};
template<int LNormNumber>
struct query_iterator {
};
// public member functions
raw_pointer fnd(const size_t) const;
bool is_leaf_node(const value_type &);
bool is_tree();
child_iterator get_children() const;
child_iterator get_children(const child_iterator &) const;
size_t num_children() const;
size_t num_children(const child_iterator &) const;
const box_type get_bounds(const child_iterator &) const;
const box_type & get_bounds() const;
const bool_d & get_periodic() const;
particle_iterator get_bucket_particles(const reference);
bbox< dimension > get_bucket_bbox(const reference) const;
void get_bucket(const double_d &, pointer &, box_type &) const;
size_t get_bucket_index(const reference) const;
template<int LNormNumber = -1>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double) const;
template<int LNormNumber = -1>
query_iterator< LNormNumber >
get_buckets_near_point(const double_d &, const double_d &) const;
const int_d & get_end_bucket() const;
all_iterator get_subtree(const child_iterator &) const;
all_iterator get_subtree() const;
size_t number_of_buckets() const;
size_t number_of_particles() const;
const raw_pointer & get_particles_begin() const;
raw_pointer & get_particles_begin();
unsigned number_of_levels() const;
Description
This object is designed to be used within algorithms or gpu kernels, and can be obtained from a Particles type using the
Particles::get_query() function
Note that if you wish to run this on a gpu using Trust, you need to copy the query object to the kernel, and mark the lambda function as a
device function
Template Parameters
1. typename Traits
implement fnd-by-id
Parameters:
id the id of the particle to fnd
Returns: pointer to the particle found, or a pointer to the end of the particle set if not found
given a reference to a bucket, checks if that bucket is a leaf (i.e. does not have any children)
Parameters:
bucket the bucket to check
3. bool is_tree();
Returns: a child_iterator that iterates through all the buckets in the data structure
Parameters:
ci this fuction returns all the children of ci
returns a particle_iterator range to all the particles within the given bucket
Parameters:
bucket a reference to the bucket in question
Parameters:
bounds (output)
bucket (output)
position (input)
This function can use multiple p-norm distance types by setting LNormNumber, and uses a isotropic distance value given by
max_distance. Note that only buckets within the domain are returned, and periodicity is not taken into account
Parameters:
max_distance the maximum distance of the buckets to be returned
position the position to search around
This function can use multiple p-norm distance types by setting LNormNumber, and uses a anisotropic distance value given by
max_distance. Note that only buckets within the domain are returned, and periodicity is not taken into account
Parameters:
max_distance the maximum distance of the buckets to be returned
position the position to search around
Parameters:
ci the child_iterator to search under
Can use this range to loop through all the buckets in the data structure, wether it is a tree or not
can use this and number_of_particles() to loop through all the particles
can use this and number_of_particles() to loop through all the particles
Struct child_iterator
Aboria::NeighbourQueryBase::child_iterator — An iterator that steps through the children of a single bucket in the tree.
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
// An iterator that steps through the children of a single bucket in the tree.
struct child_iterator {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
template<typename Traits>
class HyperOctree : public Aboria::neighbour_search_base< HyperOctree< Traits >, Traits,
HyperOctreeQuery< Traits > >
{
public:
// member classes/structs/unions
struct child_index_to_tag_mask {
// types
typedef vector_int::const_pointer ptr_type;
// construct/copy/destruct
child_index_to_tag_mask(int, int, ptr_type);
// public member functions
int operator()(int) const;
// public data members
const int level;
const int max_level;
ptr_type m_nodes;
static const unsigned mask;
};
struct classify_node {
// construct/copy/destruct
classify_node(int, int);
// public member functions
template<typename tuple_type> int operator()(const tuple_type &) const;
// public data members
const int threshold;
const int last_level;
};
struct classify_point {
// construct/copy/destruct
classify_point(const bbox< dimension > &, int);
// public member functions
int operator()(const double_d &);
// public data members
bbox< dimension > box;
int max_level;
};
struct make_leaf {
// types
typedef vint2 result_type;
// public member functions
template<typename tuple_type>
result_type operator()(const tuple_type &) const;
};
struct write_nodes {
// construct/copy/destruct
write_nodes(int, int);
// public member functions
template<typename tuple_type> int operator()(const tuple_type &) const;
// public data members
int num_nodes;
int num_leaves;
};
// construct/copy/destruct
HyperOctree();
// public member functions
void build_tree();
void print_data_structure() const;
// public static functions
static constexpr bool ordered();
// private member functions
void set_domain_impl();
void update_iterator_impl();
void update_positions_impl(iterator, iterator, const int, const bool = true);
const HyperOctreeQuery< Traits > & get_query_impl() const;
HyperOctreeQuery< Traits > & get_query_impl();
};
Description
An hyper octree is the general n-dimensional analog of an octree (aside: a normal octree is only defned for three dimensions). This data
structure is a tree, where each level of the tree splits each bucket along the middle of each dimension. Each new bucket formed by this split
becomes a child bucket for that bucket. Once the number of particles within a box falls below a threshold value (default: 10) then it is a leaf
of the tree with no children
For example, consider a certain level of the tree in two dimensions which has 3 buckets, one a leaf with 9 particles, the other two non-leafs
with 44 and 11 particles respectivly. The threshold value is set at 10. <heading>~~~ </heading>
| | | | leaf | |
9 44
|---------------<mdash></mdash>+-----------------<mdash></mdash>|
11
<hruler></hruler>
~~~
Template Parameters
1. typename Traits
an instatiation of TraitsCommon
1. HyperOctree();
2. void update_iterator_impl();
Struct all_iterator
Aboria::NeighbourQueryBase::all_iterator — An iterator that steps through all the buckets in the tree (depth-frst)
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
// An iterator that steps through all the buckets in the tree (depth-frst)
struct all_iterator {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<int LNormNumber>
struct query_iterator {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename iterator_tuple_type, typename mpl_vector_type>
class zip_iterator {
};
Description
Template Parameters
1. typename iterator_tuple_type
2. typename mpl_vector_type
Specializations
Class template zip_iterator<std::tuple< Types...>, mpl_vector_type>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
template<unsigned int NI, unsigned int NJ, typename Blocks>
class MatrixReplacement :
public Eigen::EigenBase< MatrixReplacement< NI, NJ, Blocks > >
{
public:
// types
typedef frst_block_type::Scalar Scalar;
typedef Scalar RealScalar;
typedef size_t Index;
typedef int StorageIndex;
typedef unspecifed InnerIterator;
enum @0 { ColsAtCompileTime = = Eigen::Dynamic,
RowsAtCompileTime = = Eigen::Dynamic,
MaxColsAtCompileTime = = Eigen::Dynamic,
MaxRowsAtCompileTime = = Eigen::Dynamic, IsRowMajor = = false };
// construct/copy/destruct
MatrixReplacement(const Blocks &);
MatrixReplacement(Blocks &&);
// public member functions
Index rows() const;
Index cols() const;
Index innerSize() const;
Index outerSize() const;
void resize(Index, Index);
Scalar coeff(const Index, const Index) const;
template<typename Rhs>
Eigen::Product< MatrixReplacement, Rhs, Eigen::AliasFreeProduct >
operator*(const Eigen::MatrixBase< Rhs > &) const;
template<unsigned int I, unsigned int J>
const std::tuple_element< I *NJ+J, Blocks >::type & get_kernel() const;
const std::tuple_element< 0, Blocks >::type & get_frst_kernel() const;
template<unsigned int I, unsigned int J>
std::tuple_element< I *NJ+J, Blocks >::type & get_kernel();
std::tuple_element< 0, Blocks >::type & get_frst_kernel();
template<typename Derived>
void assemble(Eigen::DenseBase< Derived > &) const;
template<int _Options, typename _StorageIndex>
void assemble(Eigen::SparseMatrix< Scalar, _Options, _StorageIndex > &);
template<std::size_t... I> Index rows_impl(unspecifed) const;
template<std::size_t... J> Index cols_impl(unspecifed) const;
template<int I> Index start_col() const;
template<int I> Index size_col() const;
template<int I> Index start_row() const;
template<int I> Index size_row() const;
template<typename block_type>
Scalar coeff_impl_block(const Index, const Index, const block_type &) const;
template<std::size_t... I>
Scalar coeff_impl(const Index, const Index, unspecifed) const;
template<typename Block>
void assemble_block_impl(const size_t, const size_t,
std::vector< Eigen::Triplet< Scalar >> &,
const Block &) const;
template<typename Block, typename Derived>
void assemble_block_impl(const Eigen::MatrixBase< Derived > &,
const Block &) const;
template<std::size_t... I>
void assemble_impl(std::vector< Eigen::Triplet< Scalar >> &, unspecifed) const;
template<typename Derived, std::size_t... I>
void assemble_impl(Eigen::DenseBase< Derived > &, unspecifed) const;
// public data members
Blocks m_blocks;
};
Description
This provides a class that acts like a sparse matrix within Eigen, at least for matrix-vector multiplication and the iterative solvers (it has not
been tested with anything else and will not work, for example, in matrix-matrix addition or multiplication).
It is templated on a set of NI x NJ blocks, each containing a kernel defned in Kernels.h . This kernel performs the actual operator
See Also:
Template Parameters
1. unsigned int NI
2. unsigned int NJ
3. typename Blocks
7. template<typename Rhs>
Eigen::Product< MatrixReplacement, Rhs, Eigen::AliasFreeProduct >
operator*(const Eigen::MatrixBase< Rhs > & x) const;
template<typename Derived>
12.
void assemble(Eigen::DenseBase< Derived > & matrix) const;
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a dense linear operator (i.e. matrix) in Eigen.
Parameters:
col_particles The columns of the linear operator index this frst particle set
function A function object that returns the value of the operator for a given particle
pair
row_particles The rows of the linear operator index this frst particle set
Template
Parameters: ColParticles The type of the column particle set
F The type of the function object
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a dense linear operator (i.e. matrix) in Eigen. It uses chebyshev
interpolation to speed up its application to a vector.
Parameters:
col_particles The columns of the linear operator index this frst particle set
function A function object that returns the value of the operator for a given particle
pair
n The number of chebyshev nodes in each dimension to use
row_particles The rows of the linear operator index this frst particle set
Template
Parameters: ColParticles The type of the column particle set
F The type of the function object
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename PositionF,
size_t QuadratureOrder = 8,
typename F = detail::position_kernel<RowElements, ColElements, PositionF> >
class KernelChebyshev :
public Aboria::KernelDense< RowElements, ColElements, F >
{
public:
// types
typedef base_type::Scalar Scalar;
typedef base_type::Block Block;
// construct/copy/destruct
KernelChebyshev(const RowElements &, const ColElements &,
const unsigned int, const PositionF &);
// public member functions
void set_n(const unsigned int);
void update_row_positions();
void update_kernel_matrix();
void update_col_positions();
template<typename DerivedLHS, typename DerivedRHS>
void evaluate(Eigen::DenseBase< DerivedLHS > &,
const Eigen::DenseBase< DerivedRHS > &) const;
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
2. void update_row_positions();
3. void update_kernel_matrix();
4. void update_col_positions();
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a dense linear operator (i.e. matrix) in Eigen. It uses FMM speed up its
application to a vector. For repeated uses it is better to use create_h2_operator
Parameters:
col_particles The columns of the linear operator index this frst particle set
function A function object that returns the value of the operator for a given particle
pair (used for close particle pairs)
position_function A function object that returns the value of the operator for a given position
pair (used for well-separated position pairs)
row_particles The rows of the linear operator index this frst particle set
Template
Parameters: ColParticles The type of the column particle set
F The type of the function object
N The number of chebyshev nodes in each dimension to use
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a dense linear operator (i.e. matrix) in Eigen. It internally creates a H2
hierarchical matrix to speed up repeated applications of the operator
Parameters:
col_particles The columns of the linear operator index this frst particle set
function A function object that returns the value of the operator for a given particle
pair (used for close particle pairs)
order Chebyshev order of the approximation within each cluster
position_function A function object that returns the value of the operator for a given position
pair (used for well-separated position pairs)
row_particles The rows of the linear operator index this frst particle set
Template
Parameters: ColParticles The type of the column particle set
F The type of the function object
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
creates a matrix-free linear block operator for use with Eigen
Struct template Dx
Aboria::Dx
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename L1, typename L2>
struct Dx {
// types
typedef unspecifed data_type;
typedef proto::terminal< data_type >::type expr_type;
// construct/copy/destruct
explicit Dx(L1 &, L2 &);
};
Description
a symbolic class used to refer to the difference between neighbouring particles position vectors. Note that for periodic domains this might
be different than get<position)(a)-get<position>(b), and in this case always gives the shortest position difference
Dx public construct/copy/destruct
1. explicit Dx(L1 & la, L2 & lb);
constructor
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Variable.h>
template<typename T, typename NAME>
struct Variable {
// types
typedef T value_type;
// public data members
const char * name;
};
Description
Copyright © 2015-2018 Martin Robinson
Macro ABORIA_VARIABLE
ABORIA_VARIABLE — a macro to conveniently defne variable types
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Variable.h>
ABORIA_VARIABLE(NAME, DATA_TYPE, NAME_STRING)
Description
Parameters:
DATA_TYPE the type used to contain the data of the variable, e.g. int, double
NAME the name of the generated type
NAME_STRING a string used to name or describe the variable, e.g. "scalar", "velocity"
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<template< typename, typename > class VECTOR>
struct Traits {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/FastMultipoleMethod.h>
template<typename Expansions, typename Kernel, typename RowParticles,
typename ColParticles>
class FastMultipoleMethod {
public:
// construct/copy/destruct
FastMultipoleMethod(const RowParticles &, const ColParticles &,
const Expansions &, const Kernel &);
// public member functions
template<typename VectorTypeTarget, typename VectorTypeSource>
void matrix_vector_multiply(VectorTypeTarget &, const VectorTypeSource &) const;
// private member functions
template<typename VectorType>
m_expansion_type &
calculate_dive_P2M_and_M2M(const col_child_iterator &, const VectorType &,
const int) const;
template<typename VectorTypeTarget, typename VectorTypeSource>
void calculate_dive_M2L_and_L2L(VectorTypeTarget &,
const col_child_iterator_vector_type &,
const l_expansion_type &,
const box_type &,
const row_child_iterator &,
const VectorTypeSource &, const int) const;
};
Description
Class H2LibMatrix
Aboria::H2LibMatrix
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
class H2LibMatrix {
public:
// construct/copy/destruct
template<typename RowParticles, typename ColParticles, typename Expansions,
typename Kernel>
H2LibMatrix(const RowParticles &, const ColParticles &,
const Expansions &, const Kernel &, const double);
// public member functions
void compress(const double);
ph2matrix get_ph2matrix() const;
pblock get_pblock() const;
H2Lib_LR_Decomposition lr(const double) const;
H2LibCholeskyDecomposition chol(const double) const;
template<typename T1, typename T2>
void matrix_vector_multiply(std::vector< T1 > &, const double, const bool,
const std::vector< T2 > &) const;
template<typename T1, typename T2>
void matrix_vector_multiply(Eigen::DenseBase< T1 > &, const double,
const bool, const Eigen::DenseBase< T2 > &) const;
// private member functions
template<typename Particles>
pcluster set_root_idx(uint *, const Particles &, const size_t);
template<typename ChildIterator, typename Particles>
pcluster set_idx(const ChildIterator, uint *, const Particles &,
const size_t);
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a sparse linear operator (i.e. matrix) in Eigen, in that only particle pairs
(i.e. a row/column pair) with a separation less that a given value are considered to be non-zero
Parameters:
col_particles The columns of the linear operator index this frst particle set
function A function object that returns the value of the operator for a given particle pair
radius_function A function object that takes a const_reference to a particle and returns a double
value. It is assumed that function returns a zero value for all particle pairs with a
separation greater than this value
row_particles The rows of the linear operator index this frst particle set
Template
Parameters: ColParticles The type of the column particle set
F The type of the function object
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a $n m$ zero matrix. That is the application of this linear operator to a
vector will always return a zero vector.
Parameters:
col_particles The columns of the linear operator index this frst particle set
row_particles The rows of the linear operator index this frst particle set
Template Parameters:
ColParticles The type of the column particle set
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename T>
struct Symbol {
// types
typedef unspecifed expr_type; // type of the (terminal) expression used to express Symbol
typedef T variable_type; // the underlying Variable type
typedef T::value_type value_type; // value_type of the underlying Variable type
typedef unspecifed data_type;
// construct/copy/destruct
explicit Symbol();
};
Description
defne a symbol from a Variable type T. This symbol can then be used in expressions
type of internal data class used to store Symbol information (e.g. buffering)
constructor
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<unsigned int I, typename P>
struct Label {
// types
typedef unspecifed expr_type; // type of the (terminal) expression used to express Label
typedef unspecifed data_type; // type of internal data class used to store Label information
// construct/copy/destruct
explicit Label(P &);
// public member functions
template<typename Variable> void resize_buffer(const size_t);
};
Description
defne a label with a given depth I that referres to a particle container with type P
constructor
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename L1, typename L2> Dx< L1, L2 > create_dx(L1 & la, L2 & lb);
Description
helper function to create a Dx class that refers to the shortest distance between two particles given by labels la and lb
See Also:
Dx
Label
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename T>
struct Accumulate {
// types
typedef unspecifed expr_type;
typedef unspecifed data_type;
// construct/copy/destruct
explicit Accumulate();
template<typename T2> explicit Accumulate(const T2 &);
// public member functions
void set_init(const typename data_type::init_type &);
};
Description
an accumulation expression, for example a sum or product over neighbouring particles
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, norm_fun, Expr const & >::type
const
norm(Expr const & arg);
Description
a symbolic norm function for Vect3d
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, inf_norm_fun, Expr const &
>::type const
inf_norm(Expr const & arg);
Description
a symbolic norm function for Vect3d
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
Description
a symbolic dot-product function for Vect3d
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, exp_fun, Expr const & >::type
const
exp(Expr const & arg);
Description
a symbolic exponential function for scalars
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
Description
a symbolic power function for that takes two arguements arg1 and arg2 and returns arg1 to the power of arg2
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, abs_fun, Expr const & >::type
const
abs(Expr const & arg);
Description
a symbolic absolute value function for scalars
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, log_fun, Expr const & >::type
const
log(Expr const & arg);
Description
a symbolic log function for scalars
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, erf_fun, Expr const & >::type
const
erf(Expr const & arg);
Description
a symbolic error function for scalars
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, sign_fun, Expr const & >::type
const
sign(Expr const & arg);
Description
a symbolic sign function for scalars
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellListOrdered.h>
template<typename Traits>
struct CellListOrdered_params {
// types
typedef Traits::double_d double_d;
// construct/copy/destruct
CellListOrdered_params();
CellListOrdered_params(const double_d &);
// public data members
double_d side_length;
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Evaluate.h>
Description
Evaluates a non-linear operator expr over a set of particles given by label label and stores the result, using the functor Functor, in
variable with type VariableType
Macro ABORIA_UNARY_FUNCTION
ABORIA_UNARY_FUNCTION
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
ABORIA_UNARY_FUNCTION(function_name, function_to_wrap, domain)
Description
a macro to generate a symbolic function taking a single argument using a given functor
Parameters:
domain the domain of the symbolic function (normally SymbolicDomain)
function_name the name of the symbolic function to generate
function_to_wrap a functor that defnes a typedef result_type with the returned type, and a
operator() that takes a single argument and returns result_type
Macro ABORIA_BINARY_FUNCTION
ABORIA_BINARY_FUNCTION
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
ABORIA_BINARY_FUNCTION(function_name, function_to_wrap, domain)
Description
a macro to generate a symbolic function taking two arguments using a given functor
Parameters:
domain the domain of the symbolic function (normally SymbolicDomain)
function_name the name of the symbolic function to generate
function_to_wrap a functor that defnes a typedef result_type with the returned type, and a
operator() that takes two arguments and returns result_type
Macro ABORIA_TERNARY_FUNCTION
ABORIA_TERNARY_FUNCTION
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
ABORIA_TERNARY_FUNCTION(function_name, function_to_wrap, domain)
Description
a macro to generate a symbolic function taking three arguments using a given functor
Parameters:
domain the domain of the symbolic function (normally SymbolicDomain)
function_name the name of the symbolic function to generate
function_to_wrap a functor that defnes a typedef result_type with the returned type, and a
operator() that takes three arguments and returns result_type
Macro ABORIA_TAGGED_FUNCTION
ABORIA_TAGGED_FUNCTION
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
ABORIA_TAGGED_FUNCTION(name, tag)
Struct norm_fun
Aboria::norm_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct norm_fun {
// types
typedef double result_type;
// public member functions
template<typename T, unsigned int N>
result_type operator()(const Vector< T, N > &) const;
};
Description
Struct inf_norm_fun
Aboria::inf_norm_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct inf_norm_fun {
// types
typedef double result_type;
// public member functions
template<typename T, unsigned int N>
result_type operator()(const Vector< T, N > &) const;
};
Description
Struct dot_fun
Aboria::dot_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct dot_fun {
// types
typedef double result_type;
// public member functions
template<typename T, unsigned int N>
result_type operator()(const Vector< T, N > &, const Vector< T, N > &) const;
};
Description
Struct exp_fun
Aboria::exp_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct exp_fun {
// types
typedef double result_type;
// public member functions
result_type operator()(const double &) const;
};
Description
Struct sqrt_fun
Aboria::sqrt_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct sqrt_fun {
// types
typedef double result_type;
// public member functions
result_type operator()(const double &) const;
};
Description
Struct sign_fun
Aboria::sign_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct sign_fun {
// types
typedef double result_type;
// public member functions
result_type operator()(const double &) const;
};
Description
Struct erf_fun
Aboria::erf_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct erf_fun {
// types
typedef double result_type;
// public member functions
result_type operator()(const double &) const;
};
Description
Struct erfc_fun
Aboria::erfc_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct erfc_fun {
// types
typedef double result_type;
// public member functions
result_type operator()(const double &) const;
};
Description
Struct log_fun
Aboria::log_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct log_fun {
// types
typedef double result_type;
// public member functions
result_type operator()(const double &) const;
};
Description
Struct abs_fun
Aboria::abs_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct abs_fun {
// types
typedef double result_type;
// public member functions
result_type operator()(const double &) const;
};
Description
Struct pow_fun
Aboria::pow_fun
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
struct pow_fun {
// types
typedef double result_type;
// public member functions
double operator()(const double, const double) const;
double operator()(const double, const int) const;
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename T>
struct refect_fun {
// types
typedef Vector< double, 3 > Vect3d;
typedef Vect3d result_type;
// public member functions
result_type operator()(const Vect3d &, const Vect3d &, const T) const;
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, sqrt_fun, Expr const & >::type
const
sqrt(Expr const & arg);
Description
a symbolic square root function for scalars
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Functions.h>
template<typename Expr>
proto::result_of::make_expr< proto::tag::function, SymbolicDomain, erfc_fun, Expr const & >::type
const
erfc(Expr const & arg);
Description
a symbolic complimentary error function for scalars
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename TupleType, typename MplVector>
struct zip_pointer {
};
Description
Template Parameters
1. typename TupleType
2. typename MplVector
a boost::mpl typelist
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename MplVector, typename... Types>
struct getter_type<std::tuple< Types...>, MplVector> {
// types
typedef std::tuple< Types...> tuple_type;
typedef MplVector mpl_vector_type;
typedef unspecifed tuple_reference;
typedef unspecifed elem_by_type;
typedef unspecifed return_type;
// construct/copy/destruct
getter_type();
explicit getter_type(const tuple_type &);
getter_type(const getter_type &);
getter_type(getter_type &&);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(const getter_type< tuple_reference, mpl_vector_type > &);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(getter_type< tuple_reference, mpl_vector_type > &&);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T, tuple_reference>::value)>::type>
getter_type(const getter_type< T, mpl_vector_type > &);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T, tuple_reference>::value)>::type>
getter_type(getter_type< T, mpl_vector_type > &&);
template<typename T1, typename T2, typename... T3>
getter_type(T1 &&, T2 &&, T3 &&...);
getter_type& operator=(const getter_type &);
getter_type& operator=(getter_type &&);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type&
operator=(const getter_type< tuple_reference, mpl_vector_type > &);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type& operator=(getter_type< tuple_reference, mpl_vector_type > &&);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T, tuple_type>::value)>::type>
getter_type& operator=(const getter_type< T, mpl_vector_type > &);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T, tuple_type>::value)>::type>
getter_type& operator=(getter_type< T, mpl_vector_type > &&);
// public member functions
template<typename T> int throw_away(const T &);
template<typename Tuple, std::size_t... I>
void copy_impl(const Tuple &, unspecifed);
template<typename T1, typename T2>
bool operator==(const getter_type< T1, T2 > &);
void swap(getter_type &);
template<typename tuple_type2, std::size_t... I>
void swap_via_tie(tuple_type2 &, unspecifed);
const tuple_type & get_tuple() const;
tuple_type & get_tuple();
// public data members
tuple_type data;
};
Description
This needs to be all host only code, use thrust::tuple specialisation for device code
5. template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(const getter_type< tuple_reference, mpl_vector_type > & other);
6. template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(getter_type< tuple_reference, mpl_vector_type > && other);
7. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T,
tuple_reference>::value)>::type>
getter_type(const getter_type< T, mpl_vector_type > & other);
8. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T,
tuple_reference>::value)>::type>
getter_type(getter_type< T, mpl_vector_type > && other);
14. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T,
tuple_type>::value)>::type>
15. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T,
tuple_type>::value)>::type>
getter_type& operator=(getter_type< T, mpl_vector_type > && other);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename MplVector, typename TT1, typename TT2, typename TT3,
typename TT4, typename TT5, typename TT6, typename TT7, typename TT8,
typename TT9>
struct getter_type<thrust::tuple< TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9 >, MplVector> {
// types
typedef thrust::tuple< TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9 > tuple_type;
typedef MplVector mpl_vector_type;
typedef unspecifed tuple_reference;
typedef unspecifed tuple_device_reference;
typedef unspecifed index_type;
typedef unspecifed elem_by_type;
typedef unspecifed return_type;
// construct/copy/destruct
getter_type();
explicit getter_type(const tuple_type &);
getter_type(const getter_type &);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(const getter_type< tuple_reference, mpl_vector_type > &);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(getter_type< tuple_reference, mpl_vector_type > &&);
template<typename T = tuple_device_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(const getter_type< tuple_device_reference, mpl_vector_type > &);
template<typename T = tuple_device_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(getter_type< tuple_device_reference, mpl_vector_type > &&);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T, tuple_reference>::value)>::type>
getter_type(const getter_type< T, mpl_vector_type > &);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T, tuple_reference>::value)>::type>
getter_type(getter_type< T, mpl_vector_type > &&);
template<typename T1, typename T2, typename... T3>
getter_type(T1 &&, T2 &&, T3 &&...);
getter_type& operator=(const getter_type &);
getter_type& operator=(getter_type &&);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type&
operator=(const getter_type< tuple_reference, mpl_vector_type > &);
template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type& operator=(getter_type< tuple_reference, mpl_vector_type > &&);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T, tuple_type>::value)>::type>
getter_type& operator=(const getter_type< T, mpl_vector_type > &);
template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T, tuple_type>::value)>::type>
getter_type& operator=(getter_type< T, mpl_vector_type > &&);
template<typename T, typename Tag>
getter_type&
Description
Use device code only in this specialisation : api is not good, consider doing an iterator_facade type thing
4. template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(const getter_type< tuple_reference, mpl_vector_type > & other);
5. template<typename T = tuple_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(getter_type< tuple_reference, mpl_vector_type > && other);
6. template<typename T = tuple_device_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(const getter_type< tuple_device_reference, mpl_vector_type > & other);
7. template<typename T = tuple_device_reference,
typename = typename std::enable_if< !std::is_same<T,
tuple_type>::value>::type>
getter_type(getter_type< tuple_device_reference, mpl_vector_type > && other);
8. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T,
tuple_reference>::value)>::type>
getter_type(const getter_type< T, mpl_vector_type > & other);
9. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_type>::value) && (!std::is_same<T,
tuple_reference>::value)>::type>
getter_type(getter_type< T, mpl_vector_type > && other);
15. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T,
tuple_type>::value)>::type>
getter_type& operator=(const getter_type< T, mpl_vector_type > & other);
16. template<typename T,
typename = typename std::enable_if< (!std::is_same<T,
tuple_reference>::value) && (!std::is_same<T,
tuple_type>::value)>::type>
getter_type& operator=(getter_type< T, mpl_vector_type > && other);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename MplVector, typename... Types>
struct zip_pointer<std::tuple< Types *...>, MplVector> {
// types
typedef std::tuple< Types *...> tuple_type;
typedef MplVector mpl_vector_type;
typedef unspecifed elem_by_type;
typedef unspecifed return_type;
typedef unspecifed reference;
typedef unspecifed difference_type;
typedef unspecifed index_type;
// construct/copy/destruct
zip_pointer();
explicit zip_pointer(const tuple_type &);
zip_pointer(const zip_pointer &);
zip_pointer(zip_pointer &&);
template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > &);
template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > &&);
template<typename T1, typename T2, typename... T3>
zip_pointer(T1 &&, T2 &&, T3 &&...);
zip_pointer& operator=(const zip_pointer &);
zip_pointer& operator=(zip_pointer &&);
template<typename T1, typename T2>
zip_pointer& operator=(const zip_pointer< T1, T2 > &);
template<typename T1, typename T2>
zip_pointer& operator=(zip_pointer< T1, T2 > &&);
// public member functions
void swap(zip_pointer &);
const tuple_type & get_tuple() const;
tuple_type & get_tuple();
bool operator==(const zip_pointer &) const;
zip_pointer & operator++();
zip_pointer operator++(int);
zip_pointer operator+(const difference_type &) const;
zip_pointer operator-(const difference_type &) const;
zip_pointer & operator+=(const difference_type &);
difference_type operator-(const zip_pointer &) const;
bool operator<(const zip_pointer &) const;
bool operator<=(const zip_pointer &) const;
bool operator>(const zip_pointer &) const;
bool operator>=(const zip_pointer &) const;
zip_pointer & operator--();
zip_pointer operator--(int);
reference operator*() const;
void increment();
void decrement();
bool equal(zip_pointer const &) const;
reference dereference() const;
difference_type distance_to(zip_pointer const &) const;
void advance(difference_type);
// public data members
tuple_type data;
};
Description
5. template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > & other);
6. template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > && other);
6. zip_pointer operator++(int);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename MplVector, typename TT1, typename TT2, typename TT3,
typename TT4, typename TT5, typename TT6, typename TT7, typename TT8,
typename TT9>
struct zip_pointer<thrust::tuple< TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9 >, MplVector> {
// types
typedef thrust::tuple< TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9 > tuple_type;
typedef MplVector mpl_vector_type;
typedef unspecifed elem_by_type;
typedef unspecifed return_type;
typedef unspecifed reference;
typedef unspecifed difference_type;
typedef unspecifed index_type;
// construct/copy/destruct
zip_pointer();
explicit zip_pointer(const tuple_type &);
zip_pointer(const zip_pointer &);
zip_pointer(zip_pointer &&);
template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > &);
template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > &&);
template<typename T1, typename T2, typename... T3>
zip_pointer(T1 &&, T2 &&, T3 &&...);
zip_pointer& operator=(const zip_pointer &);
zip_pointer& operator=(zip_pointer &&);
template<typename T1, typename T2>
zip_pointer& operator=(const zip_pointer< T1, T2 > &);
template<typename T1, typename T2>
zip_pointer& operator=(zip_pointer< T1, T2 > &&);
// public member functions
void swap(zip_pointer &);
const tuple_type & get_tuple() const;
tuple_type & get_tuple();
bool operator==(const zip_pointer &) const;
zip_pointer & operator++();
zip_pointer operator++(int);
zip_pointer operator+(const difference_type &) const;
zip_pointer & operator+=(const difference_type &);
zip_pointer operator-(const difference_type &) const;
difference_type operator-(const zip_pointer &) const;
zip_pointer & operator--();
zip_pointer operator--(int);
bool operator<(const zip_pointer &) const;
bool operator<=(const zip_pointer &) const;
bool operator>(const zip_pointer &) const;
bool operator>=(const zip_pointer &) const;
reference operator*() const;
void increment();
void decrement();
bool equal(zip_pointer const &) const;
reference dereference() const;
difference_type distance_to(zip_pointer const &) const;
void advance(difference_type);
// public data members
tuple_type data;
};
Description
Use device only code in this specialisation
5. template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > & other);
6. template<typename tuple_type2,
typename = typename std::enable_if< std::is_convertible<tuple_type2,
tuple_type>::value>::type>
zip_pointer(const zip_pointer< tuple_type2, mpl_vector_type > && other);
6. zip_pointer operator++(int);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename mpl_vector_type, typename... Types>
class zip_iterator<std::tuple< Types...>, mpl_vector_type> {
public:
// types
typedef iterator_tuple_type tuple_type;
typedef unspecifed value_type;
typedef unspecifed reference;
typedef unspecifed difference_type;
typedef unspecifed iterator_category;
typedef unspecifed pointer;
typedef unspecifed getter_raw_pointer;
typedef unspecifed getter_raw_reference;
typedef unspecifed elem_by_type;
// member classes/structs/unions
template<typename T>
struct return_type {
// types
typedef unspecifed type;
// public data members
static const size_t N;
};
// construct/copy/destruct
zip_iterator();
explicit zip_iterator(iterator_tuple_type);
template<typename... T> explicit zip_iterator(T...);
// public member functions
const iterator_tuple_type & get_tuple() const;
iterator_tuple_type & get_tuple();
// private member functions
void increment();
void decrement();
bool equal(zip_iterator const &) const;
reference dereference() const;
difference_type distance_to(zip_iterator const &) const;
void advance(difference_type);
};
Description
Use host only code in this specialisation
2. void decrement();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename mpl_vector_type, typename... Types>
class zip_iterator<thrust::tuple< Types...>, mpl_vector_type> {
public:
// types
typedef iterator_tuple_type tuple_type;
typedef unspecifed value_type;
typedef unspecifed reference;
typedef unspecifed difference_type;
typedef unspecifed iterator_category;
typedef unspecifed pointer;
typedef unspecifed getter_raw_pointer;
typedef unspecifed getter_raw_reference;
typedef unspecifed elem_by_type;
// member classes/structs/unions
template<typename T>
struct return_type {
// types
typedef unspecifed type;
// public data members
static const size_t N;
};
// construct/copy/destruct
zip_iterator();
explicit zip_iterator(iterator_tuple_type);
template<typename... T> explicit zip_iterator(T...);
// public member functions
const iterator_tuple_type & get_tuple() const;
iterator_tuple_type & get_tuple();
// private member functions
void increment();
void decrement();
bool equal(zip_iterator const &) const;
reference dereference() const;
difference_type distance_to(zip_iterator const &) const;
void advance(difference_type);
};
Description
Use device only code in this specialisation
2. void decrement();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
Description
Parameters:
arg the actual iterator object to be converted
Template Parameters:
Iterator the iterator type to be converted. Can be a normal STL iterator or a
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
Description
See Also:
ABORIA_VARIABLE
Parameters:
arg the object with type ValueType
Template Parameters:
T the variable type to get,
ValueType the getter_type, zip_iterator, zip_pointer, or Particles
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
Description
See Also:
ABORIA_VARIABLE
Parameters:
arg the object with type ValueType
Template Parameters:
T the variable type to get,
ValueType the getter_type, zip_iterator, zip_pointer, or Particles
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
Description
Parameters:
arg the object with type ValueType
Template
Parameters: N the index of the variable to get. The order of variables is set to
(position,id,alive,generator,user_variable1,user_variable2,...)
ValueType the getter_type, zip_iterator, zip_pointer, or Particles
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
Description
Parameters:
arg the object with type ValueType
Template
Parameters: N the index of the variable to get. The order of variables is set to
(position,id,alive,generator,user_variable1,user_variable2,...)
ValueType the getter_type, zip_iterator, zip_pointer, or Particles
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
Description
Parameters:
arg the object with type ValueType
Template
Parameters: N the index of the variable to get. The order of variables is set to
(position,id,alive,generator,user_variable1,user_variable2,...)
ValueType the getter_type, zip_iterator, zip_pointer, or Particles
Class H2Lib_LR_Decomposition
Aboria::H2Lib_LR_Decomposition
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
class H2Lib_LR_Decomposition {
public:
// construct/copy/destruct
H2Lib_LR_Decomposition(const ph2matrix, const pblock, const double);
// public member functions
template<typename T1, typename T2>
void solve(const std::vector< T1 > &, std::vector< T2 > &);
};
Description
Class H2LibCholeskyDecomposition
Aboria::H2LibCholeskyDecomposition
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
class H2LibCholeskyDecomposition {
public:
// construct/copy/destruct
H2LibCholeskyDecomposition(const ph2matrix, const pblock, const double);
// public member functions
template<typename DerivedRHS>
void solve(const Eigen::DenseBase< DerivedRHS > &,
Eigen::Matrix< double, Eigen::Dynamic, 1 > &);
template<typename T1, typename T2>
void solve(const std::vector< T1 > &, std::vector< T2 > &);
double determinant() const;
double log_determinant() const;
// private member functions
double log_determinant_sum(ph2matrix) const;
};
Description
returns the determinant of the H2 matrix that was used to make this decomposition
Returns: double
NaN if negative eigenvalues found (i.e. H2 matrix not positive defnite)
returns the log determinant of the H2 matrix that was used to make this decomposition.
Returns: double
NaN if negative eigenvalues found (i.e. H2 matrix not positive defnite)
-HUGE_VAL if zero eigenvalues found
Class HLib_LR_Decomposition
Aboria::HLib_LR_Decomposition
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
class HLib_LR_Decomposition {
public:
// construct/copy/destruct
HLib_LR_Decomposition(const phmatrix, const double);
~HLib_LR_Decomposition();
// public member functions
template<typename T1, typename T2>
void solve(const std::vector< T1 > &, std::vector< T2 > &);
};
Description
2. ~HLib_LR_Decomposition();
Class HLibCholeskyDecomposition
Aboria::HLibCholeskyDecomposition
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
class HLibCholeskyDecomposition {
public:
// construct/copy/destruct
HLibCholeskyDecomposition(const phmatrix, const double);
~HLibCholeskyDecomposition();
// public member functions
template<typename DerivedRHS>
void solve(const Eigen::DenseBase< DerivedRHS > &,
Eigen::Matrix< double, Eigen::Dynamic, 1 > &);
template<typename T>
void solve(const std::vector< T > &, std::vector< double > &);
};
Description
2. ~HLibCholeskyDecomposition();
2. template<typename T>
void solve(const std::vector< T > & source, std::vector< double > & dest);
Class HLibMatrix
Aboria::HLibMatrix
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/H2Lib.h>
class HLibMatrix {
public:
// construct/copy/destruct
template<typename RowParticles, typename ColParticles, typename Expansions,
typename Kernel>
HLibMatrix(const RowParticles &, const ColParticles &, const Expansions &,
const Kernel &);
// private static functions
template<typename RowParticles, typename ColParticles, typename Expansions,
typename Kernel>
static void assemble_block_hmatrix(pcblock, uint, uint, uint, uint,
void *);
static void truncate_block_hmatrix(pcblock, uint, uint, uint, uint, void *);
// public member functions
void compress(const double);
phmatrix get_phmatrix() const;
HLib_LR_Decomposition lr(const double) const;
HLibCholeskyDecomposition chol(const double) const;
template<typename T1, typename T2>
void matrix_vector_multiply(std::vector< T1 > &, const double, const bool,
const std::vector< T2 > &) const;
// private member functions
template<typename Particles>
pcluster set_root_idx(uint *, const Particles &, const size_t);
template<typename ChildIterator, typename Particles>
pcluster set_idx(const ChildIterator, uint *, const Particles &,
const size_t);
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kdtree.h>
template<typename Query>
class KdtreeChildIterator {
public:
// types
typedef const value_type * pointer;
typedef std::forward_iterator_tag iterator_category;
typedef const value_type & reference;
typedef std::ptrdiff_t difference_type;
// member classes/structs/unions
struct value_type {
// public data members
int high;
const int * parent;
box_type bounds;
};
// construct/copy/destruct
KdtreeChildIterator();
KdtreeChildIterator(const int *, const box_type &);
// public member functions
bool is_high() const;
int get_child_number() const;
reference operator*() const;
reference operator->() const;
KdtreeChildIterator & operator++();
KdtreeChildIterator operator++(int);
bool operator==(const KdtreeChildIterator &) const;
bool operator!=(const KdtreeChildIterator &) const;
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool equal(KdtreeChildIterator const &) const;
bool equal(const bool) const;
reference dereference() const;
void increment();
// public data members
value_type m_data;
};
Description
6. KdtreeChildIterator operator++(int);
4. void increment();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename F>
class KernelBase {
public:
// types
typedef kernel_helper::Block Block;
typedef kernel_helper::Scalar Scalar;
typedef kernel_helper::BlockRHSVector BlockRHSVector;
typedef kernel_helper::BlockLHSVector BlockLHSVector;
typedef RowElements row_elements_type;
typedef ColElements col_elements_type;
typedef F function_type;
typedef size_t Index;
enum @1 { ColsAtCompileTime = = -1, RowsAtCompileTime = = -1 };
// construct/copy/destruct
KernelBase(const RowElements &, const ColElements &, const F &);
// public member functions
RowElements & get_row_elements();
const RowElements & get_row_elements() const;
ColElements & get_col_elements();
const function_type & get_kernel_function() const;
const ColElements & get_col_elements() const;
size_t rows() const;
size_t cols() const;
Scalar coeff(const size_t, const size_t) const;
template<typename MatrixType> void assemble(const MatrixType &) const;
template<typename Triplet>
void assemble(std::vector< Triplet > &, const size_t = 0,
const size_t = 0) const;
template<typename VectorLHS, typename VectorRHS>
void evaluate(VectorLHS &, const VectorRHS &) const;
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename F>
class KernelDense : public Aboria::KernelBase< RowElements, ColElements, F > {
public:
// types
typedef base_type::Block Block;
typedef base_type::BlockLHSVector BlockLHSVector;
typedef base_type::Scalar Scalar;
// construct/copy/destruct
KernelDense(const RowElements &, const ColElements &, const F &);
// public member functions
template<typename Derived>
void assemble(const Eigen::DenseBase< Derived > &) const;
template<typename Triplet>
void assemble(std::vector< Triplet > &, const size_t = 0,
const size_t = 0) const;
template<typename DerivedLHS, typename DerivedRHS>
void evaluate(Eigen::DenseBase< DerivedLHS > &,
const Eigen::DenseBase< DerivedRHS > &) const;
template<typename LHSType, typename RHSType>
void evaluate(std::vector< LHSType > &, const std::vector< RHSType > &) const;
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
2. template<typename Triplet>
void assemble(std::vector< Triplet > & triplets, const size_t startI = 0,
const size_t startJ = 0) const;
Evaluates a matrix-free linear operator given by expr if expr, and particle sets a and b on a vector rhs and accumulates the
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename F>
class KernelMatrix : public Aboria::KernelBase< RowElements, ColElements, F > {
public:
// types
typedef base_type::Scalar Scalar;
typedef base_type::Block Block;
// construct/copy/destruct
KernelMatrix(const RowElements &, const ColElements &, const F &);
// public member functions
void assemble_matrix();
Scalar coeff(const size_t, const size_t) const;
template<typename MatrixType> void assemble(const MatrixType &) const;
template<typename LHSType, typename RHSType>
void evaluate(std::vector< LHSType > &, const std::vector< RHSType > &) const;
template<typename DerivedLHS, typename DerivedRHS>
void evaluate(Eigen::DenseBase< DerivedLHS > &,
const Eigen::DenseBase< DerivedRHS > &) const;
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename PositionF,
typename F>
class KernelH2 : public Aboria::KernelDense< RowElements, ColElements, F > {
public:
// types
typedef base_type::Block Block;
typedef base_type::Scalar Scalar;
// construct/copy/destruct
KernelH2(const RowElements &, const ColElements &, const int,
const PositionF &, const F &, const double);
// public member functions
const h2_matrix_type & get_h2_matrix() const;
const PositionF & get_position_function() const;
void compress(const double);
template<typename VectorLHS, typename VectorRHS>
void evaluate(VectorLHS &, const VectorRHS &) const;
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
Evaluates a h2 matrix linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the result
in vector lhs
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename PositionF,
typename F, unsigned int N>
class KernelFMM : public Aboria::KernelDense< RowElements, ColElements, F > {
public:
// types
typedef base_type::Block Block;
typedef base_type::Scalar Scalar;
// construct/copy/destruct
KernelFMM(const RowElements &, const ColElements &, const PositionF &,
const F &);
// public member functions
template<typename VectorLHS, typename VectorRHS>
void evaluate(VectorLHS &, const VectorRHS &) const;
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename FRadius,
typename FWithDx,
typename F = detail::sparse_kernel<RowElements, ColElements, FRadius, FWithDx> >
class KernelSparse : public Aboria::KernelBase< RowElements, ColElements, F > {
public:
// types
typedef base_type::Block Block;
typedef base_type::Scalar Scalar;
// construct/copy/destruct
KernelSparse(const RowElements &, const ColElements &, const FRadius &,
const FWithDx &);
// public member functions
template<typename MatrixType> void assemble(const MatrixType &) const;
template<typename Triplet>
void assemble(std::vector< Triplet > &, const size_t = 0,
const size_t = 0) const;
template<typename LHSType, typename RHSType>
void evaluate(std::vector< LHSType > &, const std::vector< RHSType > &) const;
template<typename DerivedLHS, typename DerivedRHS>
void evaluate(Eigen::DenseBase< DerivedLHS > &,
const Eigen::DenseBase< DerivedRHS > &) const;
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
2. template<typename Triplet>
void assemble(std::vector< Triplet > & triplets, const size_t startI = 0,
const size_t startJ = 0) const;
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements, typename F,
typename RadiusFunction = detail::constant_radius<RowElements> >
class KernelSparseConst :
public Aboria::KernelSparse< RowElements, ColElements, RadiusFunction, F >
{
public:
// types
typedef base_type::Block Block;
typedef base_type::Scalar Scalar;
// construct/copy/destruct
KernelSparseConst(const RowElements &, const ColElements &, const double,
const F &);
// public data members
static const size_t BlockRows;
static const size_t BlockCols;
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kernels.h>
template<typename RowElements, typename ColElements,
typename F = detail::zero_kernel<RowElements, ColElements> >
class KernelZero : public Aboria::KernelBase< RowElements, ColElements, F > {
public:
// types
typedef base_type::Block Block;
typedef base_type::Scalar Scalar;
// construct/copy/destruct
KernelZero(const RowElements &, const ColElements &);
// public member functions
template<typename MatrixType> void assemble(const MatrixType &) const;
template<typename Triplet>
void assemble(std::vector< Triplet > &, const size_t = 0,
const size_t = 0) const;
template<typename VectorLHS, typename VectorRHS>
void evaluate(VectorLHS &, const VectorRHS &) const;
};
Description
2. template<typename Triplet>
void assemble(std::vector< Triplet > & triplets, const size_t startI = 0,
const size_t startJ = 0) const;
Evaluates a matrix-free linear operator given by expr if_expr, and particle sets a and b on a vector rhs and accumulates the
result in vector lhs
Macro ASSERT
ASSERT
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
ASSERT(condition, message)
Macro ASSERT_CUDA
ASSERT_CUDA
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
ASSERT_CUDA(condition)
Macro CHECK
CHECK
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
CHECK(condition, message)
Macro CHECK_CUDA
CHECK_CUDA
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
CHECK_CUDA(condition, message)
Macro ERROR
ERROR
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
ERROR(message)
Macro ERROR_CUDA
ERROR_CUDA
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
ERROR_CUDA(message)
Macro ABORIA_LOG_LEVEL
ABORIA_LOG_LEVEL
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
ABORIA_LOG_LEVEL
Macro LOG
LOG
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
LOG(level, message)
Macro LOG_CUDA
LOG_CUDA
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
LOG_CUDA(level, message)
Macro LOG_CUDA1
LOG_CUDA1
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
LOG_CUDA1(level, message, variable)
Macro LOG_CUDA2
LOG_CUDA2
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
LOG_CUDA2(level, message, variable1, variable2)
Macro LOG_BOLD
LOG_BOLD
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Log.h>
LOG_BOLD(level, message)
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NanoFlannAdaptor.h>
template<typename Traits>
class nanofann_child_iterator {
public:
// types
typedef const kd_tree_type::Node * pointer;
typedef std::forward_iterator_tag iterator_category;
typedef const kd_tree_type::Node value_type;
typedef const kd_tree_type::Node & reference;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
nanofann_child_iterator();
nanofann_child_iterator(pointer, const box_type &);
// public member functions
void go_to(const double_d &);
int get_child_number() const;
bool is_high() const;
box_type get_bounds() const;
reference operator*() const;
reference operator->() const;
nanofann_child_iterator & operator++();
nanofann_child_iterator operator++(int);
bool operator==(const nanofann_child_iterator &) const;
bool operator!=(const nanofann_child_iterator &) const;
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool equal(nanofann_child_iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
void increment();
};
Description
8. nanofann_child_iterator operator++(int);
4. void increment();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename IteratorType>
struct iterator_range {
// types
typedef IteratorType iterator;
// construct/copy/destruct
iterator_range(const IteratorType &, const IteratorType &);
// public member functions
const IteratorType & begin() const;
const IteratorType & end() const;
IteratorType & begin();
IteratorType & end();
// public data members
IteratorType m_begin;
IteratorType m_end;
};
Description
Template Parameters
1. typename IteratorType
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Derived, typename Traits, typename QueryType>
class neighbour_search_base {
public:
// types
typedef QueryType query_type;
typedef Traits::double_d double_d;
typedef Traits::bool_d bool_d;
typedef Traits::iterator iterator;
typedef Traits::vector_unsigned_int vector_unsigned_int;
typedef Traits::vector_int vector_int;
typedef Traits::vector_size_t vector_size_t;
typedef Traits::reference reference;
typedef Traits::raw_reference raw_reference;
// member classes/structs/unions
// A function object used to enforce the domain extents on the set of
// particles.
template<unsigned int D, typename Reference>
struct enforce_domain_lambda {
// types
typedef Vector< double, D > double_d;
typedef Vector< bool, D > bool_d;
typedef position_d< D > position;
// construct/copy/destruct
enforce_domain_lambda(const double_d &, const double_d &, const bool_d &);
// public member functions
void operator()(Reference) const;
// public data members
const double_d low;
const double_d high;
const bool_d periodic;
};
// construct/copy/destruct
neighbour_search_base();
// public member functions
const Derived & cast() const;
Derived & cast();
void set_domain(const double_d &, const double_d &, const bool_d &,
const double = 10, const bool = true);
size_t fnd_id_map(const size_t) const;
void init_id_map();
void print_id_map();
bool update_positions(iterator, iterator, iterator, iterator,
const bool = true);
void update_iterators(iterator, iterator);
const query_type & get_query() const;
const vector_int & get_alive_indicies() const;
bool get_id_map() const;
const double_d & get_min() const;
const double_d & get_max() const;
const bool_d & get_periodic() const;
bool domain_has_been_set() const;
double get_max_bucket_size() const;
// public static functions
static constexpr bool ordered();
};
Description
It implements generic functionality such as setting up the spatial domain, logging, and the fnd-by-id map. In particular see
<xrefsect><xreftitle>Todo</xreftitle><xrefdescription>
it uses curiously recurring template pattern (CRTP) to implement compile-time polymorphism for historical reasons, but I don't think this is
neccessary anymore as all the member functions are quite slow
</xrefdescription></xrefsect>
Template Parameters
1. typename Derived
2. typename Traits
3. typename QueryType
The spatial domain is set to 1/3 of the maximum and minimum extents possible using the double type. All periodicity is turned off,
and the number of particle per bucket is set to 10
resets the domain extents, periodicity and number of particles within each bucket
Parameters:
max_in the upper extent of the search domain
min_in the lower extent of the search domain
n_particles_in_leaf indicates the average, or maximum number of particles in each bucket
not_in_constructor used to determine if this function is called within the constructor
periodic_in wether or not each dimension is periodic
Parameters:
5. void init_id_map();
Find-by-id works using a key and value vector pair that act as a map between ids and particle indicies. This pair is sorted by id for
quick(ish) searching, especially in parallel. It is not as good as std::map on a (single-core) CPU, but can be done on a GPU using
thrust::vector
See Also:
fnd_id_map
6. void print_id_map();
This is the base function for updates to any of the spatial data structures. It handles the domain enforcement, the deletion or
addition of particles, and the fnd-by-id map. It also calls the update_positions_impl of the Derived class.
One of the key responsibilities of this function is to set m_alive_indices, which is a vector of indices that are still alive after taking into
account the alive fags and the position of the particles within the domain. The Particles::update_positions() function uses this
vector to delete and reorder the particles in the container
Parameters:
begin The begin iterator of the particle set
delete_dead_particles If true (the default), the function will ensure that the particles with
an false alive variable are removed from the particle set. Note
that this function does not actually do this
end The end iterator of the particle set
update_begin The begin iterator of the range of particles to be updated
update_end The end iterator of the range of particles to be updated. Note that if
any particles are to be deleted, this must be the same as end
updates the internal copies held of the begin and end iterators of the particle set
Parameters:
begin the begin iterator of the particle set
end the end iterator of the particle set
See Also:
update_positions(), m_alive_indices
Returns: a vector of ints that shows the new order of the particles within the particle container
See Also:
set_domain()
Returns true if this spatial data structure relies on the order of particles in the Particles container. This is overloaded by the
Derived class.
Returns: true
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Traits>
class ranges_iterator {
public:
// types
typedef Traits traits_type;
typedef const p_pointer pointer;
typedef std::random_access_iterator_tag iterator_category;
typedef const p_reference reference;
typedef const p_reference value_type;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
ranges_iterator();
ranges_iterator(const p_pointer &, const p_pointer &);
// public member functions
size_t distance_to_end() const;
reference operator*() const;
reference operator->() const;
ranges_iterator & operator++();
ranges_iterator operator++(int);
ranges_iterator operator+(int);
size_t operator-(ranges_iterator) const;
bool operator==(const ranges_iterator &) const;
bool operator!=(const ranges_iterator &) const;
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool equal(ranges_iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
void increment();
void increment(const int);
};
Description
5. ranges_iterator operator++(int);
4. void increment();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Traits>
class linked_list_iterator {
public:
// types
typedef Traits traits_type;
typedef const p_pointer pointer;
typedef std::forward_iterator_tag iterator_category;
typedef const p_reference reference;
typedef const p_reference value_type;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
linked_list_iterator();
linked_list_iterator(const int, const p_pointer &, int *const);
linked_list_iterator(const linked_list_iterator &);
linked_list_iterator& operator=(const linked_list_iterator &);
// public member functions
size_t distance_to_end() const;
reference operator*() const;
reference operator->();
linked_list_iterator & operator++();
linked_list_iterator operator++(int);
linked_list_iterator operator+(int);
size_t operator-(linked_list_iterator) const;
bool operator==(const linked_list_iterator &) const;
bool operator!=(const linked_list_iterator &) const;
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool increment();
bool equal(linked_list_iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
};
Description
A const iterator to a set of neighbouring points. This iterator implements a STL forward iterator type
this constructor is used to start the iterator at the head of a bucket list
3. reference operator->();
5. linked_list_iterator operator++(int);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Traits, typename Iterator>
class index_vector_iterator {
public:
// types
typedef Traits traits_type;
typedef const p_pointer pointer;
typedef std::forward_iterator_tag iterator_category;
typedef const p_reference reference;
typedef const p_reference value_type;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
index_vector_iterator();
index_vector_iterator(Iterator, const p_pointer &);
// public member functions
reference operator*() const;
reference operator->();
iterator & operator++();
iterator operator++(int);
size_t operator-(iterator) const;
bool operator==(const iterator &) const;
bool operator!=(const iterator &) const;
// private member functions
void increment();
bool equal(iterator const &) const;
reference dereference() const;
};
Description
this constructor is used to start the iterator at the head of a bucket list
2. reference operator->();
4. iterator operator++(int);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Query>
class depth_frst_iterator {
public:
// types
typedef child_iterator::value_type value_type;
typedef child_iterator pointer;
typedef std::forward_iterator_tag iterator_category;
typedef child_iterator::reference reference;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
depth_frst_iterator();
depth_frst_iterator(const child_iterator &, const unsigned, const Query *);
depth_frst_iterator(const iterator &);
depth_frst_iterator& operator=(const iterator &);
~depth_frst_iterator();
// public member functions
const child_iterator & get_child_iterator() const;
reference operator*() const;
reference operator->();
iterator & operator++();
iterator operator++(int);
size_t operator-(iterator) const;
bool operator==(const iterator &) const;
bool operator!=(const iterator &) const;
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
void increment();
bool equal(iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
};
Description
this constructor is used to start the iterator at the head of a bucket list
5. ~depth_frst_iterator();
3. reference operator->();
5. iterator operator++(int);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Query, int LNormNumber>
class tree_query_iterator {
public:
// types
typedef child_iterator::value_type value_type;
typedef child_iterator::pointer pointer;
typedef std::forward_iterator_tag iterator_category;
typedef child_iterator::reference reference;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
tree_query_iterator();
tree_query_iterator(const child_iterator &, const double_d &,
const double_d &, const unsigned, const Query *,
const bool = false);
tree_query_iterator(const iterator &);
tree_query_iterator& operator=(const iterator &);
~tree_query_iterator();
// public member functions
child_iterator get_child_iterator() const;
reference operator*() const;
reference operator->();
iterator & operator++();
iterator operator++(int);
size_t operator-(iterator) const;
bool operator==(const iterator &) const;
bool operator!=(const iterator &) const;
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool child_is_within_query(const child_iterator &);
void increment_stack();
void go_to_next_leaf();
void increment();
bool equal(iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
};
Description
this constructor is used to start the iterator at the head of a bucket list
5. ~tree_query_iterator();
3. reference operator->();
5. iterator operator++(int);
2. void increment_stack();
3. void go_to_next_leaf();
4. void increment();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<unsigned int D>
class lattice_iterator {
public:
// types
typedef proxy_int_d pointer;
typedef std::random_access_iterator_tag iterator_category;
typedef const proxy_int_d & reference;
typedef proxy_int_d value_type;
typedef std::ptrdiff_t difference_type;
// member classes/structs/unions
struct proxy_int_d : public Aboria::Vector< int, D > {
// construct/copy/destruct
proxy_int_d();
proxy_int_d(const int_d &);
// public member functions
proxy_int_d & operator&();
const proxy_int_d & operator&() const;
const proxy_int_d & operator*() const;
proxy_int_d & operator*();
const proxy_int_d * operator->() const;
proxy_int_d * operator->();
};
// construct/copy/destruct
lattice_iterator();
lattice_iterator(const int_d &, const int_d &);
lattice_iterator(const int_d &, const int_d &, const int_d &);
lattice_iterator& operator=(const int_d &);
// public member functions
explicit operator size_t() const;
const lattice_iterator & get_child_iterator() const;
reference operator*() const;
reference operator->() const;
iterator & operator++();
iterator operator++(int);
iterator operator+(const int);
iterator & operator+=(const int);
iterator & operator-=(const int);
iterator operator-(const int);
size_t operator-(const iterator &) const;
bool operator==(const iterator &) const;
bool operator==(const bool) const;
bool operator!=(const iterator &) const;
bool operator!=(const bool) const;
// private static functions
static int_d minus(const int_d &, const int_d &);
static int_d minus(const int_d &, const int);
// private member functions
int collapse_index_vector(const int_d &) const;
int_d reassemble_index_vector(const int) const;
bool equal(iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
void increment();
void increment(const int);
};
Description
3. lattice_iterator(const int_d & min, const int_d & max, const int_d & index);
6. iterator operator++(int);
6. void increment();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename Query, int LNormNumber>
class lattice_iterator_within_distance {
public:
// types
typedef proxy_int_d pointer;
typedef std::random_access_iterator_tag iterator_category;
typedef const proxy_int_d & reference;
typedef proxy_int_d value_type;
typedef std::ptrdiff_t difference_type;
// member classes/structs/unions
struct proxy_int_d : public Aboria::Vector< int, dimension > {
// construct/copy/destruct
proxy_int_d();
proxy_int_d(const int_d &);
// public member functions
proxy_int_d & operator&();
const proxy_int_d & operator&() const;
const proxy_int_d & operator*() const;
proxy_int_d & operator*();
const proxy_int_d * operator->() const;
proxy_int_d * operator->();
};
// construct/copy/destruct
lattice_iterator_within_distance();
lattice_iterator_within_distance(const double_d &, const double_d &,
const Query *);
// public member functions
explicit operator size_t() const;
lattice_iterator< dimension > get_child_iterator() const;
reference operator*() const;
reference operator->() const;
iterator & operator++();
iterator operator++(int);
size_t operator-(const iterator &) const;
bool operator==(const iterator &) const;
bool operator==(const bool) const;
bool operator!=(const iterator &) const;
bool operator!=(const bool) const;
// private member functions
bool equal(iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
bool ith_quadrant_bit(const int) const;
void reset_min_and_index();
bool outside_domain(const double_d &, const double_d &);
void increment();
};
Description
6. iterator operator++(int);
5. void reset_min_and_index();
7. void increment();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
template<typename IteratorType>
iterator_range< IteratorType >
make_iterator_range(IteratorType && begin, IteratorType && end);
Description
Parameters:
begin the iterator pointing to the beginning of the range
end the iterator pointing to the end of the range
Template Parameters:
IteratorType the type of the iterators
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
template<unsigned int D>
class octree_child_iterator {
public:
// types
typedef const int * pointer;
typedef std::forward_iterator_tag iterator_category;
typedef const int * value_type;
typedef const int & reference;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
octree_child_iterator();
octree_child_iterator(const int *, const box_type &);
// public member functions
void go_to(const double_d &);
int get_child_number() const;
bool is_high(const size_t) const;
box_type get_bounds() const;
reference operator*() const;
reference operator->() const;
octree_child_iterator & operator++();
octree_child_iterator operator++(int);
bool operator==(const octree_child_iterator &) const;
bool operator!=(const octree_child_iterator &) const;
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool equal(octree_child_iterator const &) const;
bool equal(const bool) const;
reference dereference() const;
void increment();
};
Description
8. octree_child_iterator operator++(int);
4. void increment();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a dense linear operator (i.e. matrix) in Eigen.
Parameters:
col_particles The columns of the linear operator index this frst particle set
function A function object that returns the value of the operator for a given particle
pair
row_particles The rows of the linear operator index this frst particle set
Template
Parameters: ColParticles The type of the column particle set
F The type of the function object
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Operators.h>
Description
This function returns a MatrixReplacement object that acts like a sparse linear operator (i.e. matrix) in Eigen, in that only particle pairs
(i.e. a row/column pair) with a separation less that a given value are considered to be non-zero
Parameters:
col_particles The columns of the linear operator index this frst particle set
function A function object that returns the value of the operator for a given particle pair
radius It is assumed that function returns a zero value for all particle pairs with a
separation greater than this value
row_particles The rows of the linear operator index this frst particle set
Template
Parameters: ColParticles The type of the column particle set
F The type of the function object
RowParticles The type of the row particle set
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Search.h>
template<typename Query>
class bucket_pair_iterator {
public:
// types
typedef const std::tuple< const int_d &, const int_d &, const double_d & > * pointer;
typedef std::forward_iterator_tag iterator_category;
typedef const std::tuple< const int_d &, const int_d &, const double_d & > reference;
typedef const std::tuple< const int_d, const int_d, const double_d > value_type;
typedef std::ptrdiff_t difference_type;
// construct/copy/destruct
bucket_pair_iterator();
bucket_pair_iterator(const Query &);
// public static functions
static lattice_iterator< dimension > get_periodic_it(const bool_d);
// public member functions
reference operator*() const;
reference operator->();
bucket_pair_iterator & operator++();
bucket_pair_iterator operator++(int);
size_t operator-(bucket_pair_iterator) const;
bool operator==(const bucket_pair_iterator &);
bool operator!=(const bucket_pair_iterator &);
bool operator==(const bool) const;
bool operator!=(const bool) const;
// private member functions
bool equal(bucket_pair_iterator const &) const;
bool equal(const bool) const;
void increment();
lattice_iterator< dimension >
get_neighbouring_buckets(const Query &, const int_d &) const;
lattice_iterator< dimension >
get_neighbouring_buckets(const Query &, const int_d &, const int_d &) const;
lattice_iterator< dimension >
get_regular_buckets(const Query &, const int_d &) const;
reference dereference() const;
};
Description
2. reference operator->();
4. bucket_pair_iterator operator++(int);
3. void increment();
Struct Normal
Aboria::Normal
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
struct Normal {
};
Description
a symbolic class used to return a normally distributed random variable. This uses the random number generator of the current particle to
generate the random variable
Struct Uniform
Aboria::Uniform
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
struct Uniform {
};
Description
a symbolic class used to return a uniformly distributed random variable. This uses the random number generator of the current particle to
generate the random variable
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename T, unsigned int N>
struct VectorSymbolic {
// types
typedef unspecifed expr_type;
typedef unspecifed data_type;
// construct/copy/destruct
explicit VectorSymbolic();
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename T, int LNormNumber = 2,
typename Terminal = typename detail::accumulate_within_distance< T,
mpl::int_<LNormNumber>> >
struct AccumulateWithinDistance {
// types
typedef Terminal data_type;
typedef proto::terminal< data_type >::type expr_type;
// construct/copy/destruct
explicit AccumulateWithinDistance(const double = 1);
template<typename T2>
explicit AccumulateWithinDistance(const double, const T2 &);
// public member functions
void set_init(const typename data_type::init_type &);
void set_max_distance(const double);
};
Description
an accumulation expression, for example a sum or product, over neighbouring particles within a given radius
2. template<typename T2>
explicit AccumulateWithinDistance(const double max_distance, const T2 & arg);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename T>
struct min {
// types
typedef T result_type;
// public member functions
T operator()(const T, const T) const;
};
Description
convenient functor to get a minumum value using the Accumulate expression
Accumulate<max<double>> max;
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename T>
struct max {
// types
typedef T result_type;
// public member functions
T operator()(const T, const T) const;
};
Description
convenient functor to get a maximum value using the Accumulate expression
Accumulate<min<double>> min;
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
returns a symbolic expression with the terminals held by value, rather than the normal held by reference.
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
evaluate a given expression that returns a constant value (scaler or vector) expr the expression to evaluate. Must be an expression that
returns a constant, i.e. that does not depend on a particle's variables
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
evaluate a given expression that depends on a single label $i$, for a single input particle expr the expression to evaluate particle_a the
particle to be substituted for the label $i$
Returns: the result of the expression after substituting in the particle values
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
evaluate a given expression that depends on a single label $i$, for a single input particle expr the expression to evaluate particle_a the
particle to be substituted for the label $i$
Returns: the result of the expression after substituting in the particle values
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
evaluate a given expression that returns a constant value (scaler or vector) expr the expression to evaluate. Must be an expression that
returns a constant, i.e. that does not depend on a particle's variables particle_a dummy arguement, not used
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
template<typename Expr>
unspecifed eval(Expr & expr, unspecifed dx, unspecifed particle_a,
unspecifed particle_b);
Description
evaluate a given expression that depends on two labels $i$ and $j$ expr the expression to evaluate dx the shortest vector from particle_a
to particle_b particle_a the particle to be substituted for the label $i$ particle_b the particle to be substituted for the label $j$
Returns: the result of the expression after substituting in the particle values
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
evaluate a given expression that depends on a single label $i$, for a single input particle expr the expression to evaluate dx dummy
arguement not used particle_a the particle to be substituted for the label $i$ particle_b dummy particle, not used
Returns: the result of the expression after substituting in the particle values
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
evaluate a given expression that depends on a single label $i$, for a single input particle expr the expression to evaluate dx dummy
arguement not used particle_a dummy particle, not used particle_b the particle to be substituted for the label $i$
Returns: the result of the expression after substituting in the particle values
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
evaluate a given expression that returns a constant value (scalar or vector) expr the expression to evaluate. Must be an expression that
returns a constant, i.e. that does not depend on a particle's variables dx dummy argument, not used particle_a dummy argument, not used
particle_b dummy argument, not used
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Symbolic.h>
Description
returns true if the expression always evaluates to less than or equal to std::numeric_limits<double>::epsilon()
Struct default_traits
Aboria::default_traits
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
struct default_traits {
// member classes/structs/unions
template<std::size_t I, typename T>
struct tuple_element {
// types
typedef std::tuple_element< I, T > type;
};
template<typename T>
struct tuple_size {
// types
typedef std::tuple_size< T > type;
};
template<typename... T>
struct tuple_type {
// types
typedef std::tuple< T...> type;
};
template<typename T>
struct vector_type {
// types
typedef std::vector< T > type;
};
// public static functions
template<typename ElementIterator, typename IndexIterator>
static auto make_permutation_iterator(ElementIterator, IndexIterator);
template<typename AdaptableUnaryFunction, typename Iterator>
static auto make_transform_iterator(Iterator, AdaptableUnaryFunction);
template<typename... T> static auto make_tuple(T...);
template<typename IteratorTuple>
static auto make_zip_iterator(IteratorTuple);
template<typename Incrementable>
static auto make_counting_iterator(Incrementable);
};
Description
4. template<typename IteratorTuple>
static auto make_zip_iterator(IteratorTuple arg);
5. template<typename Incrementable>
static auto make_counting_iterator(Incrementable x);
Struct Traits<std::vector>
Aboria::Traits<std::vector>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Struct Traits<thrust::device_vector>
Aboria::Traits<thrust::device_vector>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Description
4. template<typename IteratorTuple>
static auto make_zip_iterator(IteratorTuple arg);
5. template<typename Incrementable>
static auto make_counting_iterator(Incrementable x);
Struct Traits<thrust::host_vector>
Aboria::Traits<thrust::host_vector>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Description
4. template<typename IteratorTuple>
static auto make_zip_iterator(IteratorTuple arg);
5. template<typename Incrementable>
static auto make_counting_iterator(Incrementable x);
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename ARG, unsigned int DomainD, unsigned int SelfD,
typename TRAITS>
struct TraitsCommon {
// types
typedef ARG::ERROR_FIRST_TEMPLATE_ARGUMENT_TO_PARTICLES_MUST_BE_A_STD_TUPLE_TYPE error;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename traits, unsigned int DomainD, unsigned int SelfD,
typename... TYPES>
struct TraitsCommon<std::tuple< TYPES...>, DomainD, SelfD, traits> : public traits {
// types
typedef typename traits::template tuple_type< T...>::type
tuple;
typedef typename traits::template tuple_element< I, T >::type
tuple_element;
typedef typename traits::template vector_type< T >::type
vector;
typedef vector< Vector< double, DomainD > >
vector_double_d;
typedef vector_double_d::iterator
vector_double_d_iterator;
typedef vector_double_d::const_iterator
vector_double_d_const_iterator;
typedef traits::template vector_type< Vector< int, DomainD > >::type
vector_int_d;
typedef traits::template vector_type< Vector< unsigned int, DomainD > >::type
vector_unsigned_int_d;
typedef vector_unsigned_int_d::iterator
vector_unsigned_int_d_iterator;
typedef vector_unsigned_int_d::const_iterator
vector_unsigned_int_d_const_iterator;
typedef traits::template vector_type< Vector< bool, DomainD > >::type
vector_bool_d;
typedef traits::template vector_type< int >::type
vector_int;
typedef traits::template vector_type< double >::type
vector_double;
typedef traits::template vector_type< size_t >::type
vector_size_t;
typedef traits::template vector_type< unsigned int >::type
vector_unsigned_int;
typedef vector_unsigned_int::iterator
vector_unsigned_int_iterator;
typedef vector_unsigned_int::const_iterator
vector_unsigned_int_const_iterator;
typedef traits::template vector_type< Vector< int, 2 > >::type
vector_int2;
typedef Vector< double, dimension >
double_d;
typedef Vector< int, dimension >
int_d;
typedef Vector< unsigned int, dimension >
unsigned_int_d;
typedef Vector< bool, dimension >
bool_d;
typedef std::conditional<(SelfD > 1), particles_d< SelfD >, position_d< dimension > >::type
position;
typedef position::value_type
position_value_type;
typedef alive::value_type
alive_value_type;
typedef id::value_type
id_value_type;
typedef generator::value_type
random_value_type;
typedef traits::template vector_type< position_value_type >::type
position_vector_type;
typedef traits::template vector_type< alive_value_type >::type
alive_vector_type;
typedef traits::template vector_type< id_value_type >::type
id_vector_type;
typedef traits::template vector_type< random_value_type >::type
random_vector_type;
typedef traits
traits_type;
typedef mpl::vector< position, id, alive, generator, TYPES...>
mpl_type_vector;
typedef tuple< typename position_vector_type::iterator, typename id_vector_type::iterator,
typename alive_vector_type::iterator, typename random_vector_type::iterator, typename
traits::template vector_type< typename TYPES::value_type >::type::iterator...>
tuple_of_iterators_type;
typedef tuple< typename position_vector_type::const_iterator, typename
id_vector_type::const_iterator, typename alive_vector_type::const_iterator, typename
random_vector_type::const_iterator, typename traits::template vector_type< typename
TYPES::value_type >::type::const_iterator...> tuple_of_const_iterators_type;
typedef std::tuple< position_vector_type, id_vector_type, alive_vector_type, random_vector_type,
typename traits::template vector_type< typename TYPES::value_type >::type...>
vectors_data_type;
typedef Aboria::zip_iterator< tuple_of_iterators_type, mpl_type_vector >
iterator;
typedef Aboria::zip_iterator< tuple_of_const_iterators_type, mpl_type_vector >
const_iterator;
typedef iterator::reference
reference;
typedef iterator::value_type
value_type;
typedef iterator::pointer
pointer;
typedef iterator::getter_raw_pointer
raw_pointer;
typedef iterator::getter_raw_reference
raw_reference;
typedef const_iterator::getter_raw_reference
raw_const_reference;
typedef const_iterator::reference
const_reference;
typedef Aboria::getter_type< vectors_data_type, mpl_type_vector >
data_type;
typedef position_vector_type::size_type
size_type;
typedef position_vector_type::difference_type
difference_type;
// public static functions
template<std::size_t... I>
static iterator begin_impl(data_type &, unspecifed);
template<std::size_t... I>
static iterator end_impl(data_type &, unspecifed);
template<std::size_t... I>
static const_iterator cbegin_impl(const data_type &, unspecifed);
template<std::size_t... I>
static const_iterator cend_impl(const data_type &, unspecifed);
template<std::size_t... I>
static reference
index_impl(data_type &, const size_t, unspecifed, std::true_type);
template<std::size_t... I>
static reference
index_impl(data_type &, const size_t, unspecifed, std::false_type);
template<std::size_t... I>
static const_reference
index_const_impl(const data_type &, const size_t, unspecifed,
std::true_type);
template<std::size_t... I>
static const_reference
index_const_impl(const data_type &, const size_t, unspecifed,
std::false_type);
template<std::size_t... I> static void clear_impl(data_type &, unspecifed);
template<std::size_t... I>
static void resize_impl(data_type &, const size_t, unspecifed);
template<std::size_t... I>
static void push_back_impl(data_type &, const value_type &, unspecifed);
template<std::size_t... I>
static void pop_back_impl(data_type &, unspecifed);
template<std::size_t... I>
static iterator erase_impl(data_type &, iterator, unspecifed);
template<std::size_t... I>
static iterator erase_impl(data_type &, iterator, iterator, unspecifed);
template<std::size_t... I>
static iterator
insert_impl(data_type &, iterator, const value_type &, unspecifed);
template<std::size_t... I>
static void insert_impl(data_type &, iterator, size_t, const value_type &,
unspecifed);
template<typename InputIterator, std::size_t... I>
static iterator
insert_impl(data_type &, iterator, InputIterator, InputIterator,
unspecifed);
template<typename InputIterator, std::size_t... I>
static data_type construct_impl(InputIterator, InputIterator, unspecifed);
template<std::size_t... I>
static void header_to_stream_impl(std::ostream &, unspecifed);
template<typename InputIterator, std::size_t... I>
static void to_stream_impl(InputIterator, std::ostream &, unspecifed);
template<typename InputIterator, std::size_t... I>
static void from_stream_impl(InputIterator, std::istream &, unspecifed);
template<typename Archive, std::size_t... I>
static void serialize_impl(const data_type &, Archive &,
const unsigned int, unspecifed);
template<typename Indices = detail::make_index_sequence<N> >
static iterator begin(data_type &);
template<typename Indices = detail::make_index_sequence<N> >
Description
2. template<std::size_t... I>
static iterator end_impl(data_type & data, unspecifed);
3. template<std::size_t... I>
static const_iterator cbegin_impl(const data_type & data, unspecifed);
4. template<std::size_t... I>
static const_iterator cend_impl(const data_type & data, unspecifed);
5. template<std::size_t... I>
static reference
index_impl(data_type & data, const size_t i, unspecifed, std::true_type);
6. template<std::size_t... I>
static reference
index_impl(data_type & data, const size_t i, unspecifed, std::false_type);
7. template<std::size_t... I>
static const_reference
index_const_impl(const data_type & data, const size_t i, unspecifed,
std::true_type);
8. template<std::size_t... I>
static const_reference
index_const_impl(const data_type & data, const size_t i, unspecifed,
std::false_type);
9. template<std::size_t... I>
static void clear_impl(data_type & data, unspecifed);
Macro ABORIA_VARIABLE_VECTOR
ABORIA_VARIABLE_VECTOR
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Variable.h>
ABORIA_VARIABLE_VECTOR(NAME, DATA_TYPE, NAME_STRING)
Macro UNARY_OPERATOR
UNARY_OPERATOR
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
UNARY_OPERATOR(the_op)
Macro OPERATOR
OPERATOR
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
OPERATOR(the_op)
Macro COMPARISON
COMPARISON
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
COMPARISON(the_op)
Macro COMPOUND_ASSIGN
COMPOUND_ASSIGN
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
COMPOUND_ASSIGN(the_op)
Macro UFUNC
UFUNC
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
UFUNC(the_op)
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T>
struct is_vector : public false_type {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T, unsigned int N>
struct is_vector<Vector< T, N >> : public true_type {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T>
struct is_eigen_vector : public false_type {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T, int N>
struct is_eigen_vector<Eigen::Matrix< T, N, 1 >> : public true_type {
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T, typename Enable = void>
struct scalar {
// types
typedef void type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T>
struct scalar<T, typename std::enable_if< std::is_arithmetic< T >::value >::type> {
// types
typedef T type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T>
struct scalar<T, typename std::enable_if< is_vector< T >::value >::type> {
// types
typedef T::value_type type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T, typename Enable = void>
struct dim {
// types
typedef void type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T>
struct dim<T, typename std::enable_if< std::is_arithmetic< T >::value >::type> {
// public data members
static const size_t value;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
template<typename T>
struct dim<T, typename std::enable_if< is_vector< T >::value >::type> {
// public data members
static const size_t value;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
Description
element-wise ceil rounding function for Vector class element-wise round rounding function for Vector class return arg1.norm()
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
Description
external dot product for vector class (probably conficts with symbolic dot?)
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Vector.h>
Description
returns new Vector made from element-wise absolute value of input arg (for Eigen)
Struct copy_points_in_bucket_lambda
Aboria::CellList::copy_points_in_bucket_lambda — function object to copy a range of particles to another index range
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
Description
goes through bucket celli and updates the particle indices to point to the new range
Struct delete_points_in_bucket_lambda
Aboria::CellList::delete_points_in_bucket_lambda — function object to delete a range of particles within the buckets
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
Description
goes through all the particles in bucket celli and deletes particles within the range given by m_start_index_deleted < i <
m_end_index_deleted
Struct insert_points_lambda_non_sequential
Aboria::CellList::insert_points_lambda_non_sequential — thread-safe function object to insert a list of non-consecutive particles into the
data structure
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
Description
Struct insert_points_lambda_non_sequential_serial
Aboria::CellList::insert_points_lambda_non_sequential_serial — non-threadsafe function object to insert a non-consecutive list of particles
into the data structure
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
Description
Struct insert_points_lambda_sequential
Aboria::CellList::insert_points_lambda_sequential — thread-safe function object to insert a list of consecutive particles into the data
structure
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
Description
Struct insert_points_lambda_sequential_serial
Aboria::CellList::insert_points_lambda_sequential_serial — non-threadsafe insert a consecutive vector of particles into the data structure
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/CellList.h>
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
Description
Template Parameters
1. unsigned int D
2. typename Reference
updates the position of i (periodic domain) or its alive fag (non-periodic domain) based on its position relative to the spatial domain
If dimension $j$ is periodic, and $r_j$ is outside the domain, then $r_j$ is updated to the correct position within the domain. If
dimensino $j$ is non-periodic, and $r_j$ is outside the domain, then the alive variable for i is set to false
Struct particle_iterator
Aboria::NeighbourQueryBase::particle_iterator — An iterator that steps through the particles within a given bucket.
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
Struct child_index_to_tag_mask
Aboria::HyperOctree::child_index_to_tag_mask
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
struct child_index_to_tag_mask {
// types
typedef vector_int::const_pointer ptr_type;
// construct/copy/destruct
child_index_to_tag_mask(int, int, ptr_type);
// public member functions
int operator()(int) const;
// public data members
const int level;
const int max_level;
ptr_type m_nodes;
static const unsigned mask;
};
Description
Struct classify_node
Aboria::HyperOctree::classify_node
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
struct classify_node {
// construct/copy/destruct
classify_node(int, int);
// public member functions
template<typename tuple_type> int operator()(const tuple_type &) const;
// public data members
const int threshold;
const int last_level;
};
Description
Struct classify_point
Aboria::HyperOctree::classify_point
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
struct classify_point {
// construct/copy/destruct
classify_point(const bbox< dimension > &, int);
// public member functions
int operator()(const double_d &);
// public data members
bbox< dimension > box;
int max_level;
};
Description
Struct make_leaf
Aboria::HyperOctree::make_leaf
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
struct make_leaf {
// types
typedef vint2 result_type;
// public member functions
template<typename tuple_type>
result_type operator()(const tuple_type &) const;
};
Description
Struct write_nodes
Aboria::HyperOctree::write_nodes
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/OctTree.h>
struct write_nodes {
// construct/copy/destruct
write_nodes(int, int);
// public member functions
template<typename tuple_type> int operator()(const tuple_type &) const;
// public data members
int num_nodes;
int num_leaves;
};
Description
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename T>
struct vector_type {
// types
typedef std::vector< T > type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename T>
struct return_type {
// types
typedef unspecifed type;
// public data members
static const size_t N;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Get.h>
template<typename T>
struct return_type {
// types
typedef unspecifed type;
// public data members
static const size_t N;
};
Struct value_type
Aboria::KdtreeChildIterator::value_type
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Kdtree.h>
struct value_type {
// public data members
int high;
const int * parent;
box_type bounds;
};
Struct proxy_int_d
Aboria::lattice_iterator::proxy_int_d
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
Description
6. proxy_int_d * operator->();
Struct proxy_int_d
Aboria::lattice_iterator_within_distance::proxy_int_d
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/NeighbourSearchBase.h>
Description
6. proxy_int_d * operator->();
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename T>
struct tuple_size {
// types
typedef std::tuple_size< T > type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename... T>
struct tuple_type {
// types
typedef std::tuple< T...> type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename T>
struct tuple_size {
// types
typedef thrust::tuple_size< T > type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename T>
struct vector_type {
// types
typedef thrust::device_vector< T > type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename T>
struct tuple_size {
// types
typedef thrust::tuple_size< T > type;
};
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
Synopsis
// In header: </home/travis/build/martinjrobins/Aboria/src/Traits.h>
template<typename T>
struct vector_type {
// types
typedef thrust::host_vector< T > type;
};