Page MenuHomec4science

container_neighbor_atoms.hh
No OneTemporary

File Metadata

Created
Sat, Jun 29, 05:59

container_neighbor_atoms.hh

/**
* @file container_neighbor_atoms.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
*
* @date Wed Jan 23 15:53:40 2013
*
* @brief This class virtualize a container of neighbors for a collection of
* atoms
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but
* WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LIBMULTISCALE_CONTAINER_NEIGHBOR_ATOMS_HH__
#define __LIBMULTISCALE_CONTAINER_NEIGHBOR_ATOMS_HH__
/* -------------------------------------------------------------------------- */
#include "container.hh"
#include "container_neighbor_atoms_interface.hh"
#include "spatial_grid_libmultiscale.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
template <typename T, UInt Dim>
class ContainerNeighborAtoms : public SpatialGridLibMultiScale<T, Dim>,
public ContainerNeighborAtomsInterface,
public Container_base<T> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
class iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ContainerNeighborAtoms(const LMID &id, Cube &c, Real p);
ContainerNeighborAtoms(const LMID &id, Cube &c, Real x, Real y, Real z);
ContainerNeighborAtoms(const LMID &id, Cube &c, UInt *p);
virtual ~ContainerNeighborAtoms();
template <typename Vec> auto &to(Vec &&vec) {
for (UInt i = 0; i < Dim; ++i) {
position[i] = vec[i];
}
return *this;
}
T &get(UInt) override { LM_TOIMPLEMENT; };
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template <typename Cont> void fillGrid(Cont &c);
template <typename Cont> void fillGridWithInitialPositions(Cont &c);
iterator begin();
iterator end();
UInt size() const override { LM_TOIMPLEMENT; };
void setPBCFlag(bool *pbc);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
UInt pbc_flag[Dim];
Vector<Dim> position;
};
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
ContainerNeighborAtoms<T, Dim>::ContainerNeighborAtoms(const LMID &id, Cube &c,
Real p)
: LMObject(id), SpatialGridLibMultiScale<T, Dim>(c, p) {
for (UInt i = 0; i < Dim; ++i) {
pbc_flag[i] = 0;
}
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
ContainerNeighborAtoms<T, Dim>::ContainerNeighborAtoms(const LMID &id, Cube &c,
Real x, Real y, Real z)
: LMObject(id), SpatialGridLibMultiScale<T, Dim>(c, x, y, z) {
for (UInt i = 0; i < Dim; ++i) {
pbc_flag[i] = 0;
}
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
ContainerNeighborAtoms<T, Dim>::ContainerNeighborAtoms(const LMID &id, Cube &c,
UInt *p)
: LMObject(id), SpatialGridLibMultiScale<T, Dim>(c, p) {
for (UInt i = 0; i < Dim; ++i) {
pbc_flag[i] = 0;
}
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
ContainerNeighborAtoms<T, Dim>::~ContainerNeighborAtoms() {}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
typename ContainerNeighborAtoms<T, Dim>::iterator
ContainerNeighborAtoms<T, Dim>::begin() {
typename ContainerNeighborAtoms<T, Dim>::iterator it(*this);
this->getNeighborhood(this->position, it.neighborhood_indexes,
this->pbc_flag);
it.findNextNeighborBlock();
it.current_el = 0;
return it;
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
typename ContainerNeighborAtoms<T, Dim>::iterator
ContainerNeighborAtoms<T, Dim>::end() {
typename ContainerNeighborAtoms<T, Dim>::iterator it(*this);
it.current_block = nullptr;
it.current_el = 0;
return it;
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
template <typename Cont>
void ContainerNeighborAtoms<T, Dim>::fillGrid(Cont &c) {
for (auto &&at : c) {
auto X = at.position();
this->addElement(at, X);
}
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
template <typename Cont>
void ContainerNeighborAtoms<T, Dim>::fillGridWithInitialPositions(Cont &c) {
typename Cont::iterator it = c.begin();
typename Cont::Ref at;
for (at = it.getFirst(); !it.end(); at = it.getNext()) {
Real x[Dim];
at.getPositions0(x);
this->addElement(at, x);
}
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
void ContainerNeighborAtoms<T, Dim>::setPBCFlag(bool *pbc) {
for (UInt i = 0; i < Dim; ++i) {
pbc_flag[i] = pbc[i];
}
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
class ContainerNeighborAtoms<T, Dim>::iterator : public iterator_base<T> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
friend class ContainerNeighborAtoms<T, Dim>;
public:
iterator(ContainerNeighborAtoms<T, Dim> &c);
~iterator();
// template <typename R> T &getFirst(R &dof);
// template <typename R> T &getFirst0(R &dof);
// T &getFirst(Real *x);
// T &getNext();
T &operator*();
iterator_base<T> &operator++() override;
bool operator!=(const iterator_base<T> &) const override;
bool operator==(const iterator_base<T> &) const override;
void findNextNeighborBlock();
protected:
UInt central_block;
std::vector<T> *current_block;
std::vector<UInt> neighborhood_indexes;
UInt current_el;
};
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
ContainerNeighborAtoms<T, Dim>::iterator::iterator(
ContainerNeighborAtoms<T, Dim> &c)
: iterator_base<T>(c) {
if (Dim == 1)
neighborhood_indexes.reserve(3);
if (Dim == 2)
neighborhood_indexes.reserve(9);
if (Dim == 3)
neighborhood_indexes.reserve(27);
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
ContainerNeighborAtoms<T, Dim>::iterator::~iterator() {}
/* -------------------------------------------------------------------------- */
// template <typename T, UInt Dim>
// template <typename R>
// T &ContainerNeighborAtoms<T, Dim>::iterator::getFirst(R &dof) {
// Real x[3];
// dof.getPositions(x);
// return getFirst(x);
// }
// /* --------------------------------------------------------------------------
// */
// template <typename T, UInt Dim>
// template <typename R>
// T &ContainerNeighborAtoms<T, Dim>::iterator::getFirst0(R &dof) {
// Real x[3];
// dof.getPositions0(x);
// return getFirst(x);
// }
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
iterator_base<T> &ContainerNeighborAtoms<T, Dim>::iterator::operator++() {
if (current_el + 1 >= current_block->size()) {
findNextNeighborBlock();
current_el = 0;
} else
++current_el;
return *this;
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
bool ContainerNeighborAtoms<T, Dim>::iterator::operator!=(
const iterator_base<T> &other) const {
return !(*this == other);
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
bool ContainerNeighborAtoms<T, Dim>::iterator::operator==(
const iterator_base<T> &o) const {
auto &other =
static_cast<const typename ContainerNeighborAtoms<T, Dim>::iterator &>(o);
if (current_block != other.current_block)
return false;
if (current_el != other.current_el)
return false;
return true;
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
T &ContainerNeighborAtoms<T, Dim>::iterator::operator*() {
if (current_block == nullptr)
LM_FATAL("this iterator points to the end");
return current_block->at(current_el);
}
/* -------------------------------------------------------------------------- */
template <typename T, UInt Dim>
void ContainerNeighborAtoms<T, Dim>::iterator::findNextNeighborBlock() {
auto &c = static_cast<ContainerNeighborAtoms<T, Dim> &>(*this->cont);
if (neighborhood_indexes.size() == 0) {
current_block = nullptr;
current_el = 0;
return;
}
do {
UInt neigh = neighborhood_indexes.back();
LM_ASSERT(neigh != UINT_MAX, "invalid neighbor block number");
neighborhood_indexes.pop_back();
auto &blocks = c.getBlocks();
current_block = blocks[neigh];
} while (!current_block && neighborhood_indexes.size() > 0);
}
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif /* __LIBMULTISCALE_CONTAINER_NEIGHBOR_ATOMS_HH__ */

Event Timeline