Page MenuHomec4science

lm_types.hh
No OneTemporary

File Metadata

Created
Thu, May 9, 21:22

lm_types.hh

/**
* @file lm_types.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Jaehyun Cho <jaehyun.cho@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
* @author Moseley Philip Arthur <philip.moseley@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This where the global types and enums of LibMultiScale are defined
*
* @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_LM_TYPES_HH__
#define __LIBMULTISCALE_LM_TYPES_HH__
/* -------------------------------------------------------------------------- */
#include "lm_macros.hh"
#include <Eigen/Dense>
#include <aka_iterators.hh>
#include <array>
#include <exception>
#include <memory>
#include <ostream>
#include <vector>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
using akantu::enumerate;
using akantu::zip;
// error management
/* -------------------------------------------------------------------------- */
#define LM_EXIT_FAILURE 1
#define LM_EXIT_SUCCESS 0
/* -------------------------------------------------------------------------- */
// TYPEDEFS
/* -------------------------------------------------------------------------- */
using UInt = unsigned int;
using Real = double;
/* -------------------------------------------------------------------------- */
// ENUMS
/* -------------------------------------------------------------------------- */
enum DOFType {
dt_master = 1,
dt_slave = 2,
dt_pbc_master = 4,
dt_pbc_slave = 8,
dt_all = 255
};
/* -------------------------------------------------------------------------- */
enum GeomType {
BALL = 1,
CUBE = 2,
INTER = 3,
SUB = 4,
ELLIPSOID = 5,
UNION = 6,
CYLINDER = 7,
CHAUDRON = 8,
CUBE_SURFACE = 9
};
/* -------------------------------------------------------------------------- */
enum COutputType { OUTPUT_REF = 1, OUTPUT_REAL = 2, OUTPUT_NULL = 32767 };
/* -------------------------------------------------------------------------- */
enum CouplingStage {
COUPLING_STEP1 = 1,
COUPLING_STEP2 = 2,
COUPLING_STEP3 = 4,
COUPLING_STEP4 = 8,
COUPLING_STEP5 = 16,
COUPLING_STEP6 = 32,
COUPLING_STEP7 = 64
};
/* -------------------------------------------------------------------------- */
enum Operator {
OP_NONE = 0,
OP_AVERAGE = 1,
OP_DENSITY = 2,
OP_DEVIATION = 4,
OP_MAX = 8,
OP_MIN = 16,
OP_SUM = 64
};
/* -------------------------------------------------------------------------- */
enum ActionType {
at_stimulator = 0,
at_dumper = 1,
at_filter = 2,
at_compute = 4,
at_uninitialised = 32767
};
/* -------------------------------------------------------------------------- */
enum LatticeType { _not_defined, mono_atom_1d, hex_2d, hex_2d_radial, fcc_3d };
template <LatticeType type> struct LatticeDim { static const UInt value; };
template <> struct LatticeDim<mono_atom_1d> { static const UInt value = 1; };
template <> struct LatticeDim<hex_2d> { static const UInt value = 2; };
template <> struct LatticeDim<hex_2d_radial> { static const UInt value = 2; };
template <> struct LatticeDim<fcc_3d> { static const UInt value = 3; };
/* -------------------------------------------------------------------------- */
enum IntegrationSchemeStage {
NONE_STEP = 0,
PRE_DUMP = 1,
PRE_STEP1 = 2,
PRE_STEP2 = 4,
PRE_STEP3 = 8,
PRE_STEP4 = 16,
PRE_STEP5 = 32,
PRE_STEP6 = 64,
PRE_STEP7 = 128,
PRE_FATAL = 256, // This stage only exists if a FATAL is triggered
ALL_STEP = 65536
};
/* -------------------------------------------------------------------------- */
class IntegrationSchemeMask {
public:
IntegrationSchemeMask(UInt mask) { stage = mask; }
IntegrationSchemeMask(const IntegrationSchemeStage &s) { stage = s; }
IntegrationSchemeMask() { stage = NONE_STEP; };
virtual ~IntegrationSchemeMask(){};
bool operator&(const IntegrationSchemeStage &s) const { return (stage & s); };
IntegrationSchemeMask &operator=(const IntegrationSchemeStage &s) {
stage = s;
return (*this);
};
IntegrationSchemeMask operator|=(const IntegrationSchemeStage &s) {
stage |= s;
return (*this);
};
IntegrationSchemeMask operator|=(const IntegrationSchemeMask &m) {
stage |= m.stage;
return (*this);
};
bool isNone() { return (stage == NONE_STEP); }
virtual void printself(std::ostream &stream) const {
stream << "NONE_STEP";
if ((*this) & PRE_DUMP)
stream << "|PRE_DUMP";
if ((*this) & PRE_STEP1)
stream << "|PRE_STEP1";
if ((*this) & PRE_STEP2)
stream << "|PRE_STEP2";
if ((*this) & PRE_STEP3)
stream << "|PRE_STEP3";
if ((*this) & PRE_STEP4)
stream << "|PRE_STEP4";
if ((*this) & PRE_STEP5)
stream << "|PRE_STEP5";
if ((*this) & PRE_STEP6)
stream << "|PRE_STEP6";
if ((*this) & PRE_STEP7)
stream << "|PRE_STEP7";
if ((*this) & PRE_FATAL)
stream << "|PRE_FATAL";
if ((*this) & ALL_STEP)
stream << "|ALL_STEP";
};
private:
UInt stage;
};
inline std::ostream &operator<<(std::ostream &stream,
const IntegrationSchemeMask &_this) {
_this.printself(stream);
return stream;
}
inline std::ostream &operator<<(std::ostream &stream,
const IntegrationSchemeStage &_this) {
switch (_this) {
case NONE_STEP:
stream << "NONESTEP";
break;
case PRE_DUMP:
stream << "PRE_DUMP";
break;
case PRE_STEP1:
stream << "PRE_STEP1";
break;
case PRE_STEP2:
stream << "PRE_STEP2";
break;
case PRE_STEP3:
stream << "PRE_STEP3";
break;
case PRE_STEP4:
stream << "PRE_STEP4";
break;
case PRE_STEP5:
stream << "PRE_STEP5";
break;
case PRE_STEP6:
stream << "PRE_STEP6";
break;
case PRE_STEP7:
stream << "PRE_STEP7";
break;
case PRE_FATAL:
stream << "PRE_FATAL";
break;
case ALL_STEP:
stream << "ALL_STEP";
break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
enum PhysicalQuantity {
// physical quantities
Length,
Mass,
Energy,
Time,
MassDensity,
Force,
Pressure,
Temperature
};
/* -------------------------------------------------------------------------- */
// enum DDModelType {
// _DD2D,
// _PARADIS,
// };
/* -------------------------------------------------------------------------- */
/* describes the orientation of the edge dislo by indication which
* quadrant is shifted towards x=0*/
enum dislo_orientation {
TOP_RIGHT = 0,
TOP_LEFT = 1,
BOTTOM_RIGHT = 2,
BOTTOM_LEFT = 3
};
/* -------------------------------------------------------------------------- */
// operator definitions
#define _DEF_SCAL_OPERATOR(T, Dim, op) \
auto &operator op##=(const T &val) { \
for (UInt i = 0; i < Dim; ++i) { \
(*this)[i] op## = val; \
} \
return *this; \
} \
\
auto operator op(const T &val) const { \
Vector<Dim, T> result; \
for (UInt i = 0; i < Dim; ++i) { \
result[i] = (*this)[i] op val; \
} \
return result; \
}
#define _DEF_VEC_OPERATOR(T, Dim, op, Vec) \
template <typename _T> auto &operator op##=(const Vec<Dim, _T> &v) { \
for (UInt i = 0; i < Dim; ++i) { \
(*this)[i] op## = v[i]; \
} \
return *this; \
} \
\
template <typename _T> auto operator op(const Vec<Dim, _T> &v) const { \
Vector<Dim, T> result; \
for (UInt i = 0; i < Dim; ++i) { \
result[i] = (*this)[i] op v[i]; \
} \
return result; \
}
/* -------------------------------------------------------------------------- */
template <UInt Dim, typename T> struct VectorProxy;
// template <UInt Dim, typename T=Real> using Vector = Eigen::Matrix<T, Dim,
// 1u>;
template <UInt Dim, typename T = Real>
struct Vector : public Eigen::Matrix<T, Dim, 1u> {
using Eigen::Matrix<T, Dim, 1u>::Matrix;
using Eigen::Matrix<T, Dim, 1u>::operator-=;
using Eigen::Matrix<T, Dim, 1u>::operator+=;
using Eigen::Matrix<T, Dim, 1u>::operator/=;
using Eigen::Matrix<T, Dim, 1u>::operator*=;
using Eigen::Matrix<T, Dim, 1u>::operator-;
using Eigen::Matrix<T, Dim, 1u>::operator+;
using Eigen::Matrix<T, Dim, 1u>::operator/;
using Eigen::Matrix<T, Dim, 1u>::operator*;
Vector &operator=(T v[Dim]) {
for (UInt i = 0; i < Dim; ++i)
(*this)[i] = v[i];
return *this;
}
Vector &operator=(const std::vector<T> &vec) {
this->setZero();
UInt sz = std::min(UInt(vec.size()), Dim);
for (UInt i = 0; i < sz; ++i) {
(*this)[i] = vec[i];
}
return *this;
}
_DEF_SCAL_OPERATOR(T, Dim, +)
_DEF_SCAL_OPERATOR(T, Dim, -)
_DEF_SCAL_OPERATOR(T, Dim, *)
_DEF_SCAL_OPERATOR(T, Dim, /)
_DEF_VEC_OPERATOR(T, Dim, +, VectorProxy)
_DEF_VEC_OPERATOR(T, Dim, -, VectorProxy)
};
template <typename T> struct Vector<1, T> : public Eigen::Matrix<T, 1, 1u> {
using Eigen::Matrix<T, 1, 1u>::Matrix;
Vector<1, T>(const T &val) : Eigen::Matrix<T, 1, 1u>::Matrix() {
(*this)[0] = val;
}
Vector(const Vector<1, T> &vec) : Eigen::Matrix<T, 1, 1u>::Matrix() {
this->assign(vec);
}
explicit Vector(const std::vector<T> &vec) { this->assign(vec); }
explicit Vector(std::vector<T> &&vec) { this->assign(vec); }
Vector &operator=(std::vector<T> &&vec) { return this->assign(vec); }
Vector &operator=(const std::vector<T> &vec) { return this->assign(vec); }
Vector &operator=(const Vector<1, T> &vec) { return this->assign(vec); }
// operator T() const { return (*this)[0]; }
using Eigen::Matrix<T, 1u, 1u>::operator=;
using Eigen::Matrix<T, 1u, 1u>::operator+;
using Eigen::Matrix<T, 1u, 1u>::operator-;
using Eigen::Matrix<T, 1u, 1u>::operator/;
private:
template <typename V> Vector &assign(V &&vec) {
(*this)[0] = vec[0];
return *this;
}
};
// template <UInt Dim> using Array1D = Eigen::Array<Real, Dim, 1u>;
template <UInt Dim> struct Array1D : public Eigen::Array<Real, Dim, 1u> {
using Eigen::Array<Real, Dim, 1u>::Array;
using Eigen::Array<Real, Dim, 1u>::operator=;
};
// template <UInt Dim> using ArrayView1D = Eigen::Map<Eigen::Array<Real, Dim,
// 1u>>;
template <UInt Dim>
struct ArrayView1D : public Eigen::Map<Eigen::Array<Real, Dim, 1u>> {
using Eigen::Map<Eigen::Array<Real, Dim, 1u>>::Map;
using Eigen::Map<Eigen::Array<Real, Dim, 1u>>::operator=;
};
// template <UInt Dim> using Matrix = Eigen::Matrix<Real, Dim, Dim>;
template <UInt Dim> struct Matrix : public Eigen::Matrix<Real, Dim, Dim> {
using Eigen::Matrix<Real, Dim, Dim>::Matrix;
using Eigen::Matrix<Real, Dim, Dim>::operator=;
};
// template <UInt Dim> using VectorView = Eigen::Map<Eigen::Matrix<Real, Dim,
// 1u>>;
template <UInt Dim, typename T = Real>
struct VectorView : public Eigen::Map<Eigen::Matrix<T, Dim, 1u>> {
using Eigen::Map<Eigen::Matrix<T, Dim, 1u>>::Map;
using Eigen::Map<Eigen::Matrix<T, Dim, 1u>>::Map::operator=;
using Eigen::Map<Eigen::Matrix<T, Dim, 1u>>::Map::operator+;
using Eigen::Map<Eigen::Matrix<T, Dim, 1u>>::Map::operator-;
using Eigen::Map<Eigen::Matrix<T, Dim, 1u>>::Map::operator/;
_DEF_SCAL_OPERATOR(T, Dim, +)
_DEF_SCAL_OPERATOR(T, Dim, -)
_DEF_SCAL_OPERATOR(T, Dim, *)
_DEF_SCAL_OPERATOR(T, Dim, /)
_DEF_VEC_OPERATOR(T, Dim, +, VectorProxy)
_DEF_VEC_OPERATOR(T, Dim, -, VectorProxy)
_DEF_VEC_OPERATOR(T, Dim, +, Vector)
_DEF_VEC_OPERATOR(T, Dim, -, Vector)
};
// template <UInt Dim> using MatrixView = Eigen::Map<Eigen::Matrix<Real, Dim,
// Dim>>;
template <UInt Dim, typename T = Real>
struct MatrixView : public Eigen::Map<Eigen::Matrix<T, Dim, Dim>> {
using Eigen::Map<Eigen::Matrix<T, Dim, Dim>>::Map;
using Eigen::Map<Eigen::Matrix<T, Dim, Dim>>::operator=;
using Eigen::Map<Eigen::Matrix<T, Dim, Dim>>::operator+;
using Eigen::Map<Eigen::Matrix<T, Dim, Dim>>::operator-;
using Eigen::Map<Eigen::Matrix<T, Dim, Dim>>::operator/;
};
template <typename T> bool isNaN(T t) {
Eigen::ArrayXd a(t);
return a.isNaN().any();
}
template <typename T> bool isInf(T t) {
Eigen::ArrayXd a(t);
return a.isInf().any();
}
enum FieldType {
_position0 = 0,
_position = 1,
_displacement = 2,
_velocity = 3,
_force = 4,
_stress = 5,
_temperature = 6,
_grouprank = 7,
_strain = 8,
_epot = 9,
_applied_force = 10,
_mass = 11,
_tag = 12,
_id = 13,
_proc = 14,
_charge = 15,
_burgers = 16,
_normal = 17,
_acceleration = 18,
_boundary = 19,
_internal_force = 20,
_external_force = 21,
_angular_velocity = 22,
_angular_acceleration = 23,
_torque = 24,
_radius = 25,
ft_uninitialised = 32767
};
template <FieldType... types> struct field_list {
template <typename Func> static void foreach (Func &&f) {
(f(std::integral_constant<FieldType, types>()), ...);
}
};
template <UInt Dim, FieldType ft> struct FieldTraits {
using TensorType = Vector<Dim>;
using TensorViewType = VectorView<Dim>;
};
template <UInt Dim> struct FieldTraits<Dim, _mass> {
using TensorType = Vector<1>;
using TensorViewType = VectorView<1>;
};
/* -------------------------------------------------------------------------- */
// VectorProxy set of classes
// helpful to wrap n variables (of the same type)
// and manipulate them/convert them as an Eigen::vector
template <PhysicalQuantity, UInt Dim, typename T> struct Quantity;
template <UInt Dim, typename T> struct VectorProxy;
template <typename T, typename T1>
std::enable_if_t<not std::is_same_v<T1, VectorProxy<3, Real>>>
init_array(UInt index, T &var, T1 &arg) {
var[index] = &arg;
}
template <typename T, typename T1, typename... Args>
std::enable_if_t<not std::is_same_v<T1, VectorProxy<3, Real>>>
init_array(UInt index, T &var, T1 &arg, Args &... args) {
var[index] = &arg;
init_array(index + 1, var, args...);
}
template <UInt Dim, typename T = Real> struct VectorProxy {
T squaredNorm() {
T res = 0.;
for (UInt i = 0; i < Dim; ++i) {
const auto &val = *this->tup[i];
res += val * val;
}
return res;
};
T norm() {
T res = squaredNorm();
return std::sqrt(res);
}
VectorProxy(VectorProxy &v) { tup = v.tup; };
VectorProxy(VectorProxy &&v) { tup = std::move(v.tup); };
VectorProxy &operator=(VectorProxy v) {
for (UInt i = 0; i < Dim; ++i)
*this->tup[i] = v[i];
return *this;
}
VectorProxy &operator=(Vector<Dim, T> &v) {
for (UInt i = 0; i < Dim; ++i)
*this->tup[i] = v[i];
return *this;
}
VectorProxy &operator=(Vector<Dim, T> &&v) {
for (UInt i = 0; i < Dim; ++i)
*this->tup[i] = v[i];
return *this;
}
template <PhysicalQuantity q> VectorProxy &operator=(Quantity<q, Dim, T> &v) {
for (UInt i = 0; i < Dim; ++i)
*this->tup[i] = v[i];
return *this;
}
VectorProxy &operator=(T v[Dim]) {
for (UInt i = 0; i < Dim; ++i)
*this->tup[i] = v[i];
return *this;
}
template <typename... Args> VectorProxy(std::tuple<Args &...> arg_tuple) {
std::apply([&](auto &&... args) { init_array(0u, tup, args...); },
arg_tuple);
}
auto &operator[](UInt i) { return *tup[i]; }
const auto &operator[](UInt i) const { return *tup[i]; }
auto &operator()(UInt i) { return *tup[i]; }
const auto &operator()(UInt i) const { return *tup[i]; }
inline T *data() {
for (UInt i = 0; i < Dim; ++i)
_data[i] = *tup[i];
return _data.data();
};
_DEF_SCAL_OPERATOR(T, Dim, +)
_DEF_SCAL_OPERATOR(T, Dim, -)
_DEF_SCAL_OPERATOR(T, Dim, *)
_DEF_SCAL_OPERATOR(T, Dim, /)
_DEF_VEC_OPERATOR(T, Dim, +, VectorProxy)
_DEF_VEC_OPERATOR(T, Dim, -, VectorProxy)
_DEF_VEC_OPERATOR(T, Dim, +, Vector)
_DEF_VEC_OPERATOR(T, Dim, -, Vector)
_DEF_VEC_OPERATOR(T, Dim, +, VectorView)
_DEF_VEC_OPERATOR(T, Dim, -, VectorView)
operator Eigen::Matrix<T, Dim, 1u>() {
Eigen::Matrix<T, Dim, 1u> res;
for (UInt i = 0; i < Dim; ++i)
res[i] = (*this)[i];
return res;
}
operator Vector<Dim, T>() const {
Vector<Dim, T> res;
for (UInt i = 0; i < Dim; ++i)
res[i] = (*this)[i];
return res;
}
UInt size() const { return Dim; };
std::array<T *, Dim> tup;
std::array<T, Dim> _data;
};
template <UInt Dim, typename T>
inline std::ostream &operator<<(std::ostream &os, VectorProxy<Dim, T> v) {
Vector<Dim, T> v2 = v;
os << v2;
return os;
}
/* ------------------------------------------------------------------------*/
using Array =
Eigen::Array<Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
using ArrayView = Eigen::Map<Array>;
__END_LIBMULTISCALE__
/* --------------------------------------------------------------------------
*/
#endif /* __LIBMULTISCALE_LM_TYPES_HH__ */

Event Timeline