Page MenuHomec4science

container_array.hh
No OneTemporary

File Metadata

Created
Fri, Sep 6, 12:38

container_array.hh

/**
* @file container_array.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Thu Jul 24 14:21:58 2014
*
* @brief This is the contiguous array-like container for LM
*
* @section LICENSE
*
* Copyright INRIA and CEA
*
* The LibMultiScale is a C++ parallel framework for the multiscale
* coupling methods dedicated to material simulations. This framework
* provides an API which makes it possible to program coupled simulations
* and integration of already existing codes.
*
* This Project was initiated in a collaboration between INRIA Futurs Bordeaux
* within ScAlApplix team and CEA/DPTA Ile de France.
* The project is now continued at the Ecole Polytechnique Fédérale de Lausanne
* within the LSMS/ENAC laboratory.
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*
*/
#ifndef __LIBMULTISCALE_CONTAINER_ARRAY_HH__
#define __LIBMULTISCALE_CONTAINER_ARRAY_HH__
/* -------------------------------------------------------------------------- */
#include "container.hh"
#include <algorithm>
#include <vector>
template <typename Ref> class ReferenceManager;
/* -------------------------------------------------------------------------- */
#ifdef TRACE_ATOM
#include "lammps/ref_atom_lammps.hh"
#include "trace_atom.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/**
* Class ContainerArray<T>
* array implementation of a generic container
*/
/* -------------------------------------------------------------------------- */
template <class T> struct GetDim {
static constexpr UInt Dim = T::Dim;
inline UInt getDim() { return T::Dim; }
};
template <> struct GetDim<Real> {};
template <> struct GetDim<UInt> {};
/* -------------------------------------------------------------------------- */
template <typename T> class ContainerArrayIterator;
template <typename T> class ContainerArray;
template <typename T>
std::enable_if_t<!std::is_arithmetic<T>::value, UInt>
getContainerArrayDim(ContainerArray<T> &cont) {
return T::Dim;
};
template <typename T>
std::enable_if_t<std::is_arithmetic<T>::value, UInt>
getContainerArrayDim(ContainerArray<T> &cont) {
return cont.cols();
};
/* -------------------------------------------------------------------------- */
template <class T>
class ContainerArray : public Container_base<T>,
public GetDim<T>,
public virtual LMObject {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
using ContainerSubSet = ContainerArray<T>;
using iterator = ContainerArrayIterator<T>;
using EigenArray = Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic>;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
ContainerArray(const LMID &id);
ContainerArray();
ContainerArray(UInt size);
ContainerArray(ContainerArray &&);
ContainerArray(ContainerArray &);
ContainerArray &operator=(const ContainerArray &);
ContainerArray &operator=(const EigenArray &);
~ContainerArray();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
UInt getDim() { return getContainerArrayDim(*this); }
//! return an associated iterator
virtual iterator begin(DOFType dt = dt_local);
virtual iterator end(DOFType dt = dt_local);
//! sort items
virtual void sort() override;
//! search for a given item
virtual UInt search(T &el) override;
//! add a particular item
virtual void push_back(const T &el) override;
// //! search for a given item in a previously sorted array
// UInt searchInSorted(T &el);
// //! add an entry in a sorted array
// void addInSorted(T &el);
//! resize the container (by clearing the additional values)
virtual void resize(UInt size);
//! assign all values up to size to a single value
virtual void assign(UInt size, T val);
//! get an item from its index
inline T &get(UInt index) override;
//! get an item from its index
inline T &operator[](UInt index) override;
//! return the number of contained items
virtual UInt size(DOFType dt = dt_local) override;
//! return the number of columns in the array
UInt cols() { return array->cols(); };
//! function that clear the container
virtual void clear();
// ! copy the container info
virtual void copyContainerInfo(ContainerInterface &cont) override;
// //! get an item from its computed name
// virtual Real &operator()(const std::string &name, UInt index = 0) {
// std::vector<std::string>::iterator it;
// it = find(name_computed.begin(), name_computed.end(), name);
// if (it == name_computed.end()) {
// LM_FATAL("Name computed '" << name << "' not found");
// } else {
// UInt position = it - name_computed.begin();
// LM_FATAL("temp " << position);
// }
// }
// virtual UInt getDim() { return name_computed.size(); };
std::vector<std::string> name_computed;
private:
EigenArray array_storage;
std::unique_ptr<Eigen::Map<EigenArray>> array;
};
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#include "iterator_array.hh"
#include "reference_manager.hh"
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template <typename T>
ContainerArray<T>::ContainerArray(const LMID &id)
: LMObject(id), Container_base<T>() {
array = std::make_unique<Eigen::Map<EigenArray>>(array_storage.data(), 0, 1);
}
/* -------------------------------------------------------------------------- */
template <typename T>
ContainerArray<T>::ContainerArray()
: LMObject("anonymous"), Container_base<T>() {
array = std::make_unique<Eigen::Map<EigenArray>>(array_storage.data(), 0, 1);
}
/* -------------------------------------------------------------------------- */
template <typename T>
ContainerArray<T>::ContainerArray(UInt size)
: LMObject("anonymous"), Container_base<T>() {
array =
std::make_unique<Eigen::Map<EigenArray>>(array_storage.data(), size, 1);
}
/* -------------------------------------------------------------------------- */
template <typename T>
ContainerArray<T>::ContainerArray(ContainerArray &&other)
: LMObject(other.getID()) {
this->array_storage = other.array_storage;
array = std::make_unique<Eigen::Map<EigenArray>>(
array_storage.data(), other.array->rows(), other.array->cols());
}
/* -------------------------------------------------------------------------- */
template <typename T>
ContainerArray<T>::ContainerArray(ContainerArray &other)
: LMObject(other.getID()) {
this->array_storage = other.array_storage;
array = std::make_unique<Eigen::Map<EigenArray>>(
array_storage.data(), other.array->rows(), other.array->cols());
}
/* -------------------------------------------------------------------------- */
template <typename T>
ContainerArray<T> &ContainerArray<T>::operator=(const ContainerArray &other) {
this->array_storage = other.array_storage;
array = std::make_unique<Eigen::Map<EigenArray>>(
array_storage.data(), other.array->rows(), other.array->cols());
return *this;
}
/* -------------------------------------------------------------------------- */
template <typename T>
ContainerArray<T> &ContainerArray<T>::operator=(const EigenArray &other) {
this->array_storage = other;
array = std::make_unique<Eigen::Map<EigenArray>>(array_storage.data(),
other.rows(), other.cols());
return *this;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline void
copy_ref_manager(std::weak_ptr<ReferenceManagerInterface> refmanager,
std::weak_ptr<ReferenceManagerInterface> other_refmanager) {
try {
__attribute__((unused)) auto &test =
dynamic_cast<ReferenceManager<T> &>(*other_refmanager.lock());
refmanager = other_refmanager;
} catch (...) {
}
}
template <>
inline void copy_ref_manager<Real>(
std::weak_ptr<ReferenceManagerInterface> refmanager,
std::weak_ptr<ReferenceManagerInterface> other_refmanager) {}
template <typename T>
void ContainerArray<T>::copyContainerInfo(ContainerInterface &cont) {
ContainerInterface::copyContainerInfo(cont);
if (cont.hasRefManager()) {
copy_ref_manager<T>(this->refmanager, cont.getRefManager());
}
}
/* -------------------------------------------------------------------------- */
template <typename T> ContainerArray<T>::~ContainerArray() {
clear();
if (this->hasRefManager()) {
this->getRefManager()->removeSubSet(this->getID(), *this);
}
}
/* --------------------------------------------------------------------------
*/
template <class T> void ContainerArray<T>::sort() {
// std::sort(array.begin(),array.end());
LM_TOIMPLEMENT;
}
/* --------------------------------------------------------------------------
*/
template <class T> inline UInt ContainerArray<T>::size(DOFType dt) {
return array->size();
}
/* --------------------------------------------------------------------------
*/
template <class T> inline void ContainerArray<T>::clear() {
auto cols = array_storage.cols();
array_storage.resize(0, cols);
array =
std::make_unique<Eigen::Map<EigenArray>>(array_storage.data(), 0, cols);
}
/* --------------------------------------------------------------------------
*/
template <class T> inline void ContainerArray<T>::resize(UInt size) {
UInt ncols = array_storage.cols();
if (ncols == 0)
ncols = 1;
if (size % ncols != 0)
LM_FATAL("invalid size");
UInt nrows = size / ncols;
while (nrows > array_storage.rows()) {
array_storage.conservativeResize(1 + array_storage.rows() * 2, ncols);
}
array = std::make_unique<Eigen::Map<EigenArray>>(array_storage.data(), nrows,
ncols);
}
/* --------------------------------------------------------------------------
*/
template <class T> inline void ContainerArray<T>::assign(UInt size, T val) {
this->resize(size);
*array = val;
}
/* --------------------------------------------------------------------------
*/
template <class T> inline void ContainerArray<T>::push_back(const T &el) {
auto row = array->rows();
this->resize(row + 1);
array->row(row) = el;
}
/* --------------------------------------------------------------------------
*/
template <class T> inline T &ContainerArray<T>::get(UInt index) {
LM_ASSERT(index < size(),
"out of range access : " << index << " over " << size());
using EigenArray1 = Eigen::Array<T, Eigen::Dynamic, 1u>;
Eigen::Map<EigenArray1> view(array->data(), this->size());
return view(index);
}
/* --------------------------------------------------------------------------
*/
template <class T> inline T &ContainerArray<T>::operator[](UInt index) {
LM_ASSERT(index < size(),
"out of range access : " << index << " over " << size());
return this->get(index);
}
/* --------------------------------------------------------------------------
*/
template <class T> UInt ContainerArray<T>::search(T &el) {
for (UInt i = 0; i < size(); ++i) {
T &e = this->get(i);
if (el == e)
return i;
}
return UINT_MAX;
}
/* --------------------------------------------------------------------------
*/
template <class T>
typename ContainerArray<T>::iterator ContainerArray<T>::begin(DOFType dt) {
return iterator(array->data());
}
/* --------------------------------------------------------------------------
*/
template <class T>
typename ContainerArray<T>::iterator ContainerArray<T>::end(DOFType dt) {
return iterator(array->data() + this->size());
}
/* --------------------------------------------------------------------------
*/
// template <class T> inline void ContainerArray<T>::addInSorted(T &el) {
// this->push_back(el);
// UInt N = array->size();
// UInt low = 0;
// UInt high = N - 1;
// UInt mid = 0;
// UInt i = 0;
// if (N == 0) {
// this->push_back(el);
// return;
// }
// while (low <= high) {
// mid = (low + high) / 2;
// if ((*array)(mid) > el) {
// if (mid == 0)
// break;
// else
// high = mid - 1;
// } else if ((*array)[mid] < el) {
// low = mid + 1;
// } else
// return; // such element as already been inserted
// }
// mid = (low + high) / 2;
// if ((*array)[mid] < el)
// ++mid;
// /* DUMP("low = " << low << " high = " << high << " mid = " <<
// * mid,DBG_MESSAGE); */
// // shift all elements to insert at the right place the element we want
// this->push_back((*array)[N - 1]);
// for (i = 0; i < N - mid; ++i)
// (*array)[N - i] = (*array)[N - 1 - i];
// // for (i = N-1; i >= mid ; --i)
// // array[i+1] = array[i];
// /* DUMP("last decal : " << i << " -> " << i+1,DBG_MESSAGE); */
// /* if (mid == 0){ */
// /* DUMP("inserting " << el << " before " << array[mid+1] << "-" <<
// * mid,DBG_MESSAGE); */
// /* } */
// /* else if (mid == N){ */
// /* DUMP("inserting " << el << " after " << array[mid] << "-" <<
// * mid,DBG_MESSAGE); */
// /* } */
// /* else */
// /* DUMP("inserting " << el << " between " << array[mid-1] << " and "
// <<
// * array[mid+1] << "-" << mid,DBG_MESSAGE); */
// (*array)[mid] = el;
// /* DUMP("now list look like",DBG_MESSAGE); */
// /* for (UInt i = 0 ; i < size() ; ++i) */
// /* { */
// /* DUMP("array[" << i << "]=" << array[i],DBG_MESSAGE); */
// /* } */
// }
// /* --------------------------------------------------------------------------
// */
// template <class T> UInt ContainerArray<T>::searchInSorted(T &el) {
// UInt N = array->size();
// UInt low = 0;
// UInt high = N - 1;
// UInt mid = 0;
// while (low <= high && high != UINT_MAX) {
// mid = (low + high) / 2;
// if ((*this)[mid] > el)
// high = mid - 1;
// else if ((*this)[mid] < el)
// low = mid + 1;
// else
// return mid; // found
// }
// return UINT_MAX; // not found
// }
/* --------------------------------------------------------------------------
*/
__END_LIBMULTISCALE__
#endif /* __LIBMULTISCALE_CONTAINER_ARRAY_HH__ */

Event Timeline