diff --git a/src/common/aka_array_printer.hh b/src/common/aka_array_printer.hh
index e0949fb8b..f66bb7040 100644
--- a/src/common/aka_array_printer.hh
+++ b/src/common/aka_array_printer.hh
@@ -1,101 +1,101 @@
/**
* @file aka_array_printer.hh
*
* @author Nicolas Richart
*
* @date creation mer jun 19 2019
*
* @brief A Documented file.
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_ARRAY_PRINTER_HH__
#define __AKANTU_AKA_ARRAY_PRINTER_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
template class ArrayPrinter {
public:
ArrayPrinter(const container & cont) : cont(cont) {}
void printself(std::ostream & stream, int indent = 0) const {
std::string space(indent, AKANTU_INDENT);
stream << space << "{";
for (UInt i = 0; i < this->cont.size(); ++i) {
stream << this->cont[i];
if (i != this->cont.size() - 1)
stream << ", ";
}
- stream << "}" << std::endl;
+ stream << "}";
}
private:
const container & cont;
};
/* -------------------------------------------------------------------------- */
template class ArrayPrinter> {
public:
ArrayPrinter(const Array & cont) : cont(cont) {}
void printself(std::ostream & stream, int indent = 0) const {
std::string space(indent, AKANTU_INDENT);
stream << space << "{";
for (UInt i = 0; i < this->cont.size(); ++i) {
stream << "{";
for (UInt j = 0; j < this->cont.getNbComponent(); ++j) {
stream << this->cont(i, j);
if (j != this->cont.getNbComponent() - 1)
stream << ", ";
}
stream << "}";
if (i != this->cont.size() - 1)
stream << ", ";
}
- stream << "}" << std::endl;
+ stream << "}";
}
private:
const Array & cont;
};
template
decltype(auto) make_printer(const container & array) {
return ArrayPrinter(array);
}
/* -------------------------------------------------------------------------- */
template
inline std::ostream & operator<<(std::ostream & stream,
const ArrayPrinter & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AKANTU_AKA_ARRAY_PRINTER_HH__ */
diff --git a/src/common/aka_compatibilty_with_cpp_standard.hh b/src/common/aka_compatibilty_with_cpp_standard.hh
index 3afb2ecad..2bcd70e4c 100644
--- a/src/common/aka_compatibilty_with_cpp_standard.hh
+++ b/src/common/aka_compatibilty_with_cpp_standard.hh
@@ -1,156 +1,173 @@
/**
* @file aka_compatibilty_with_cpp_standard.hh
*
* @author Nicolas Richart
*
* @date creation: Fri Jun 18 2010
* @date last modification: Wed Jan 10 2018
*
* @brief The content of this file is taken from the possible implementations
* on
* http://en.cppreference.com
*
* @section LICENSE
*
* Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_static_if.hh"
/* -------------------------------------------------------------------------- */
#include
#include
#include
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH__
#define __AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH__
namespace aka {
// Part taken from C++14
#if __cplusplus < 201402L
template
using enable_if_t = typename enable_if::type;
#else
template using enable_if_t = std::enable_if_t;
#endif
// Part taken from C++17
#if __cplusplus < 201703L
// bool_constant
template using bool_constant = std::integral_constant;
namespace {
template constexpr bool bool_constant_v = bool_constant::value;
}
/* -------------------------------------------------------------------------- */
// conjunction
template struct conjunction : std::true_type {};
template struct conjunction : B1 {};
template
struct conjunction
: std::conditional_t, B1> {};
// disjunction
template struct disjunction : std::false_type {};
template struct disjunction : B1 {};
template
struct disjunction
: std::conditional_t> {};
/* -------------------------------------------------------------------------- */
// negations
template struct negation : bool_constant {};
/* -------------------------------------------------------------------------- */
namespace detail {
template struct is_reference_wrapper : std::false_type {};
template
struct is_reference_wrapper> : std::true_type {};
// template
// constexpr bool is_reference_wrapper_v = is_reference_wrapper::value;
// template
// decltype(auto) INVOKE(Type T::*f, T1 && t1, Args &&... args) {
// static_assert(std::is_member_function_pointer{} and
// std::is_base_of>{},
// "Does not know what to do with this types");
// return (std::forward(t1).*f)(std::forward(args)...);
// }
template
decltype(auto) INVOKE(Type T::*f, T1 && t1, Args &&... args) {
static_if(std::is_member_function_pointer{})
.then_([&](auto && f) {
static_if(std::is_base_of>{})
.then_([&](auto && f) {
return (std::forward(t1).*f)(std::forward(args)...);
})
.elseif(is_reference_wrapper>{})([&](auto && f) {
return (t1.get().*f)(std::forward(args)...);
})
.else_([&](auto && f) {
return ((*std::forward(t1)).*
f)(std::forward(args)...);
})(std::forward(f));
})
.else_([&](auto && f) {
static_assert(std::is_member_object_pointer::value,
"f is not a member object");
static_assert(sizeof...(args) == 0, "f takes arguments");
static_if(std::is_base_of>{})
.then_([&](auto && f) { return std::forward(t1).*f; })
.elseif(std::is_base_of>{})(
[&](auto && f) { return t1.get().*f; })
.else_([&](auto && f) { return (*std::forward(t1)).*f; })(
std::forward(f));
})(std::forward(f));
}
template
decltype(auto) INVOKE(F && f, Args &&... args) {
return std::forward(f)(std::forward(args)...);
}
} // namespace detail
template
decltype(auto) invoke(F && f, Args &&... args) {
return detail::INVOKE(std::forward(f), std::forward(args)...);
}
namespace detail {
template
constexpr decltype(auto) apply_impl(F && f, Tuple && t,
std::index_sequence) {
return invoke(std::forward(f), std::get(std::forward(t))...);
}
} // namespace detail
+/* -------------------------------------------------------------------------- */
template
constexpr decltype(auto) apply(F && f, Tuple && t) {
return detail::apply_impl(
std::forward(f), std::forward(t),
std::make_index_sequence>::value>{});
}
+/* -------------------------------------------------------------------------- */
+
+template
+typename std::iterator_traits::difference_type
+count_if(InputIt first, InputIt last, UnaryPredicate p) {
+ typename std::iterator_traits::difference_type ret = 0;
+ for (; first != last; ++first) {
+ if (p(*first)) {
+ ret++;
+ }
+ }
+ return ret;
+}
+#else
+using apply = std::apply;
+using count_if = std::count_if;
#endif
} // namespace aka
#endif /* __AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH__ */
diff --git a/src/common/aka_error.hh b/src/common/aka_error.hh
index 9dc9e316f..b889408a5 100644
--- a/src/common/aka_error.hh
+++ b/src/common/aka_error.hh
@@ -1,384 +1,389 @@
/**
* @file aka_error.hh
*
* @author Nicolas Richart
*
* @date creation: Mon Jun 14 2010
* @date last modification: Tue Feb 20 2018
*
* @brief error management and internal exceptions
*
* @section LICENSE
*
* Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include
#include
#include
#include
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ERROR_HH__
#define __AKANTU_ERROR_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
enum DebugLevel {
dbl0 = 0,
dblError = 0,
dblAssert = 0,
dbl1 = 1,
dblException = 1,
dblCritical = 1,
dbl2 = 2,
dblMajor = 2,
dbl3 = 3,
dblCall = 3,
dblSecondary = 3,
dblHead = 3,
dbl4 = 4,
dblWarning = 4,
dbl5 = 5,
dblInfo = 5,
dbl6 = 6,
dblIn = 6,
dblOut = 6,
dbl7 = 7,
dbl8 = 8,
dblTrace = 8,
dbl9 = 9,
dblAccessory = 9,
dbl10 = 10,
dblDebug = 42,
dbl100 = 100,
dblDump = 100,
dblTest = 1337
};
/* -------------------------------------------------------------------------- */
#define AKANTU_LOCATION \
"(" << __func__ << "(): " << __FILE__ << ":" << __LINE__ << ")"
/* -------------------------------------------------------------------------- */
namespace debug {
void setDebugLevel(const DebugLevel & level);
const DebugLevel & getDebugLevel();
void initSignalHandler();
std::string demangle(const char * symbol);
template std::string demangle() {
return demangle(typeid(T).name());
}
- std::string exec(const std::string & cmd);
+
+ template std::string demangle(const T & t) {
+ return demangle(typeid(t).name());
+ }
+
+std::string exec(const std::string & cmd);
void printBacktrace(int sig);
void exit(int status) __attribute__((noreturn));
/* ------------------------------------------------------------------------ */
/// exception class that can be thrown by akantu
class Exception : public std::exception {
/* ---------------------------------------------------------------------- */
/* Constructors/Destructors */
/* ---------------------------------------------------------------------- */
protected:
explicit Exception(std::string info = "")
: _info(std::move(info)), _file("") {}
public:
//! full constructor
Exception(std::string info, std::string file, unsigned int line)
: _info(std::move(info)), _file(std::move(file)), _line(line) {}
//! destructor
~Exception() noexcept override = default;
/* ---------------------------------------------------------------------- */
/* Methods */
/* ---------------------------------------------------------------------- */
public:
const char * what() const noexcept override { return _info.c_str(); }
virtual const std::string info() const noexcept {
std::stringstream stream;
stream << debug::demangle(typeid(*this).name()) << " : " << _info << " ["
<< _file << ":" << _line << "]";
return stream.str();
}
public:
void setInfo(const std::string & info) { _info = info; }
void setFile(const std::string & file) { _file = file; }
void setLine(unsigned int line) { _line = line; }
void setModule(const std::string & module) { _module = module; }
/* ---------------------------------------------------------------------- */
/* Class Members */
/* ---------------------------------------------------------------------- */
protected:
/// exception description and additionals
std::string _info;
private:
/// file it is thrown from
std::string _file;
/// line it is thrown from
unsigned int _line{0};
/// module in which exception was raised
std::string _module{"core"};
};
class CriticalError : public Exception {};
class AssertException : public Exception {};
class NotImplementedException : public Exception {};
/// standard output stream operator
inline std::ostream & operator<<(std::ostream & stream,
const Exception & _this) {
stream << _this.what();
return stream;
}
/* --------------------------------------------------------------------------
*/
class Debugger {
public:
Debugger();
virtual ~Debugger();
Debugger(const Debugger &) = default;
Debugger & operator=(const Debugger &) = default;
void exit(int status) __attribute__((noreturn));
void throwException(const std::string & info, const std::string & file,
unsigned int line, bool, const std::string &,
const std::string & module) const noexcept(false)
__attribute__((noreturn));
/*----------------------------------------------------------------------- */
template
void throwCustomException(const Except & ex, const std::string & info,
const std::string & file, unsigned int line,
const std::string & module) const noexcept(false)
__attribute__((noreturn));
/*----------------------------------------------------------------------- */
template
void throwCustomException(const Except & ex, const std::string & file,
unsigned int line,
const std::string & module) const noexcept(false)
__attribute__((noreturn));
void printMessage(const std::string & prefix, const DebugLevel & level,
const std::string & info,
const std::string & module) const;
void setOutStream(std::ostream & out) { cout = &out; }
std::ostream & getOutStream() { return *cout; }
public:
void setParallelContext(int rank, int size);
void setDebugLevel(const DebugLevel & level);
const DebugLevel & getDebugLevel() const;
void setLogFile(const std::string & filename);
std::ostream & getOutputStream();
inline bool testLevel(const DebugLevel & level,
const std::string & module = "core") const {
auto level_reached = (this->level >= (level));
auto correct_module =
(level <= dblCritical) or (modules_to_debug.size() == 0) or
(modules_to_debug.find(module) != modules_to_debug.end());
return level_reached and correct_module;
}
void printBacktrace(bool on_off) { this->print_backtrace = on_off; }
bool printBacktrace() { return this->print_backtrace; }
void addModuleToDebug(const std::string & id) {
modules_to_debug.insert(id);
}
void removeModuleToDebug(const std::string & id) {
auto it = modules_to_debug.find(id);
if (it != modules_to_debug.end())
modules_to_debug.erase(it);
}
void listModules() {
for (auto & module_ : modules_to_debug) {
(*cout) << module_ << std::endl;
}
}
private:
std::string parallel_context;
std::ostream * cout;
bool file_open;
DebugLevel level;
bool print_backtrace;
std::set modules_to_debug;
};
extern Debugger debugger;
} // namespace debug
/* -------------------------------------------------------------------------- */
#define AKANTU_STRINGIZE_(str) #str
#define AKANTU_STRINGIZE(str) AKANTU_STRINGIZE_(str)
/* -------------------------------------------------------------------------- */
#define AKANTU_DEBUG_MODULE AKANTU_STRINGIZE(AKANTU_MODULE)
/* -------------------------------------------------------------------------- */
#define AKANTU_STRINGSTREAM_IN(_str, _sstr) \
; \
do { \
std::stringstream _dbg_s_info; \
_dbg_s_info << _sstr; \
_str = _dbg_s_info.str(); \
} while (false)
/* -------------------------------------------------------------------------- */
#define AKANTU_EXCEPTION(info) AKANTU_EXCEPTION_(info, false)
#define AKANTU_SILENT_EXCEPTION(info) AKANTU_EXCEPTION_(info, true)
#define AKANTU_EXCEPTION_(info, silent) \
do { \
std::stringstream _dbg_str; \
_dbg_str << info; \
std::stringstream _dbg_loc; \
_dbg_loc << AKANTU_LOCATION; \
::akantu::debug::debugger.throwException(_dbg_str.str(), __FILE__, \
__LINE__, silent, _dbg_loc.str(), \
AKANTU_DEBUG_MODULE); \
} while (false)
#define AKANTU_CUSTOM_EXCEPTION_INFO(ex, info) \
do { \
std::stringstream _dbg_str; \
_dbg_str << info; \
::akantu::debug::debugger.throwCustomException( \
ex, _dbg_str.str(), __FILE__, __LINE__, AKANTU_DEBUG_MODULE); \
} while (false)
#define AKANTU_CUSTOM_EXCEPTION(ex) \
do { \
::akantu::debug::debugger.throwCustomException(ex, __FILE__, __LINE__, \
AKANTU_DEBUG_MODULE); \
} while (false)
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_NDEBUG
#define AKANTU_DEBUG_TEST(level) (false)
#define AKANTU_DEBUG_LEVEL_IS_TEST() \
(::akantu::debug::debugger.testLevel(dblTest, AKANTU_DEBUG_MODULE))
#define AKANTU_DEBUG(level, info)
#define AKANTU_DEBUG_(pref, level, info)
#define AKANTU_DEBUG_IN()
#define AKANTU_DEBUG_OUT()
#define AKANTU_DEBUG_INFO(info)
#define AKANTU_DEBUG_WARNING(info)
#define AKANTU_DEBUG_TRACE(info)
#define AKANTU_DEBUG_ASSERT(test, info)
#define AKANTU_ERROR(info) \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::CriticalError(), info)
/* -------------------------------------------------------------------------- */
#else
#define AKANTU_DEBUG(level, info) AKANTU_DEBUG_(" ", level, info)
#define AKANTU_DEBUG_(pref, level, info) \
do { \
std::string _dbg_str; \
AKANTU_STRINGSTREAM_IN(_dbg_str, info << " " << AKANTU_LOCATION); \
::akantu::debug::debugger.printMessage(pref, level, _dbg_str, \
AKANTU_DEBUG_MODULE); \
} while (false)
#define AKANTU_DEBUG_TEST(level) \
(::akantu::debug::debugger.testLevel(level, AKANTU_DEBUG_MODULE))
#define AKANTU_DEBUG_LEVEL_IS_TEST() \
(::akantu::debug::debugger.testLevel(dblTest))
#define AKANTU_DEBUG_IN() \
AKANTU_DEBUG_("==>", ::akantu::dblIn, __func__ << "()")
#define AKANTU_DEBUG_OUT() \
AKANTU_DEBUG_("<==", ::akantu::dblOut, __func__ << "()")
#define AKANTU_DEBUG_INFO(info) AKANTU_DEBUG_("---", ::akantu::dblInfo, info)
#define AKANTU_DEBUG_WARNING(info) \
AKANTU_DEBUG_("/!\\", ::akantu::dblWarning, info)
#define AKANTU_DEBUG_TRACE(info) AKANTU_DEBUG_(">>>", ::akantu::dblTrace, info)
#define AKANTU_DEBUG_ASSERT(test, info) \
do { \
if (not(test)) \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::AssertException(), \
"assert [" << #test << "] " << info); \
} while (false)
#define AKANTU_ERROR(info) \
do { \
AKANTU_DEBUG_("!!! ", ::akantu::dblError, info); \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::CriticalError(), info); \
} while (false)
#endif // AKANTU_NDEBUG
#define AKANTU_TO_IMPLEMENT() \
AKANTU_CUSTOM_EXCEPTION_INFO(::akantu::debug::NotImplementedException(), \
__func__ << " : not implemented yet !")
/* -------------------------------------------------------------------------- */
namespace debug {
/* ------------------------------------------------------------------------ */
template
void
Debugger::throwCustomException(const Except & ex, const std::string & info,
const std::string & file, unsigned int line,
const std::string & module) const
noexcept(false) {
auto & nc_ex = const_cast(ex);
nc_ex.setInfo(info);
nc_ex.setFile(file);
nc_ex.setLine(line);
nc_ex.setModule(module);
throw ex;
}
/* ------------------------------------------------------------------------ */
template
void Debugger::throwCustomException(const Except & ex,
const std::string & file,
unsigned int line,
const std::string & module) const
noexcept(false) {
auto & nc_ex = const_cast(ex);
nc_ex.setFile(file);
nc_ex.setLine(line);
nc_ex.setModule(module);
throw ex;
}
} // namespace debug
} // namespace akantu
#endif /* __AKANTU_ERROR_HH__ */
diff --git a/src/common/aka_random_generator.hh b/src/common/aka_random_generator.hh
index 3d22a4777..41bdf1afc 100644
--- a/src/common/aka_random_generator.hh
+++ b/src/common/aka_random_generator.hh
@@ -1,271 +1,267 @@
/**
* @file aka_random_generator.hh
*
* @author Nicolas Richart
*
* @date creation: Thu Feb 21 2013
* @date last modification: Wed Nov 08 2017
*
* @brief generic random generator
*
* @section LICENSE
*
* Copyright (©) 2014-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
/* -------------------------------------------------------------------------- */
#include
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_RANDOM_GENERATOR_HH__
#define __AKANTU_AKA_RANDOM_GENERATOR_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
/* List of available distributions */
/* -------------------------------------------------------------------------- */
// clang-format off
#define AKANTU_RANDOM_DISTRIBUTION_TYPES \
((uniform , std::uniform_real_distribution )) \
((exponential , std::exponential_distribution )) \
((gamma , std::gamma_distribution )) \
((weibull , std::weibull_distribution )) \
((extreme_value, std::extreme_value_distribution)) \
((normal , std::normal_distribution )) \
((lognormal , std::lognormal_distribution )) \
((chi_squared , std::chi_squared_distribution )) \
((cauchy , std::cauchy_distribution )) \
((fisher_f , std::fisher_f_distribution )) \
((student_t , std::student_t_distribution ))
// clang-format on
#define AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_rdt_, elem)
#define AKANTU_RANDOM_DISTRIBUTION_PREFIX(s, data, elem) \
AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))
enum RandomDistributionType {
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_RANDOM_DISTRIBUTION_PREFIX, _,
AKANTU_RANDOM_DISTRIBUTION_TYPES)),
_rdt_not_defined
};
/* -------------------------------------------------------------------------- */
/* Generator */
/* -------------------------------------------------------------------------- */
template class RandomGenerator {
/* ------------------------------------------------------------------------ */
+private:
+ static long int _seed;
+ static std::default_random_engine generator;
+ /* ------------------------------------------------------------------------ */
public:
inline T operator()() { return generator(); }
/// function to print the contain of the class
- virtual void printself(std::ostream & stream, int) const {
+ void printself(std::ostream & stream, int) const {
stream << "RandGenerator [seed=" << _seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
static void seed(long int s) {
_seed = s;
generator.seed(_seed);
}
static long int seed() { return _seed; }
static constexpr T min() { return generator.min(); }
static constexpr T max() { return generator.max(); }
-
- /* ------------------------------------------------------------------------ */
-private:
- static long int _seed;
- static std::default_random_engine generator;
};
-// template
-// long int RandomGenerator::_seed = 0;
-
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#undef AKANTU_RANDOM_DISTRIBUTION_PREFIX
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE(r, data, elem) \
case AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX( \
BOOST_PP_TUPLE_ELEM(2, 0, elem)): { \
stream << BOOST_PP_STRINGIZE(AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX( \
BOOST_PP_TUPLE_ELEM(2, 0, elem))); \
break; \
}
inline std::ostream & operator<<(std::ostream & stream,
RandomDistributionType type) {
switch (type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE, _,
AKANTU_RANDOM_DISTRIBUTION_TYPES)
default:
stream << UInt(type) << " not a RandomDistributionType";
break;
}
return stream;
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE
/* -------------------------------------------------------------------------- */
/* Some Helper */
/* -------------------------------------------------------------------------- */
template class RandomDistributionTypeHelper {
enum { value = _rdt_not_defined };
};
/* -------------------------------------------------------------------------- */
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE(r, data, elem) \
template \
struct RandomDistributionTypeHelper> { \
enum { \
value = AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX( \
BOOST_PP_TUPLE_ELEM(2, 0, elem)) \
}; \
\
static void printself(std::ostream & stream) { \
stream << BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem)); \
} \
};
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE, _,
AKANTU_RANDOM_DISTRIBUTION_TYPES)
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE
/* -------------------------------------------------------------------------- */
template class RandomDistribution {
public:
virtual ~RandomDistribution() = default;
virtual T operator()(RandomGenerator & gen) = 0;
virtual std::unique_ptr> make_unique() const = 0;
virtual void printself(std::ostream & stream, int = 0) const = 0;
};
template
class RandomDistributionProxy : public RandomDistribution {
public:
explicit RandomDistributionProxy(Distribution dist)
: distribution(std::move(dist)) {}
T operator()(RandomGenerator & gen) override {
return distribution(gen);
}
std::unique_ptr> make_unique() const override {
return std::make_unique>(
distribution);
}
void printself(std::ostream & stream, int = 0) const override {
RandomDistributionTypeHelper::printself(stream);
stream << " [ " << distribution << " ]";
}
private:
Distribution distribution;
};
/* -------------------------------------------------------------------------- */
/* RandomParameter */
/* -------------------------------------------------------------------------- */
template class RandomParameter {
public:
template
explicit RandomParameter(T base_value, Distribution dist)
: base_value(base_value),
type(RandomDistributionType(
RandomDistributionTypeHelper::value)),
distribution_proxy(
std::make_unique>(
std::move(dist))) {}
explicit RandomParameter(T base_value)
: base_value(base_value),
type(RandomDistributionType(
RandomDistributionTypeHelper<
T, std::uniform_real_distribution>::value)),
distribution_proxy(
std::make_unique<
RandomDistributionProxy>>(
std::uniform_real_distribution(0., 0.))) {}
RandomParameter(const RandomParameter & other)
: base_value(other.base_value), type(other.type),
distribution_proxy(other.distribution_proxy->make_unique()) {}
RandomParameter & operator=(const RandomParameter & other) {
distribution_proxy = other.distribution_proxy->make_unique();
base_value = other.base_value;
type = other.type;
return *this;
}
virtual ~RandomParameter() = default;
inline void setBaseValue(const T & value) { this->base_value = value; }
inline T getBaseValue() const { return this->base_value; }
template class Generator, class iterator>
void setValues(iterator it, iterator end) {
RandomGenerator gen;
for (; it != end; ++it)
*it = this->base_value + (*distribution_proxy)(gen);
}
virtual void printself(std::ostream & stream,
__attribute__((unused)) int indent = 0) const {
stream << base_value;
stream << " + " << *distribution_proxy;
}
private:
/// Value with no random variations
T base_value;
/// Random distribution type
RandomDistributionType type;
/// Proxy to store a std random distribution
std::unique_ptr> distribution_proxy;
};
/* -------------------------------------------------------------------------- */
template
inline std::ostream & operator<<(std::ostream & stream,
RandomDistribution & _this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template
inline std::ostream & operator<<(std::ostream & stream,
RandomParameter & _this) {
_this.printself(stream);
return stream;
}
} // namespace akantu
#endif /* __AKANTU_AKA_RANDOM_GENERATOR_HH__ */
diff --git a/src/fe_engine/element.hh b/src/fe_engine/element.hh
index 4ae23a2cf..1dd218498 100644
--- a/src/fe_engine/element.hh
+++ b/src/fe_engine/element.hh
@@ -1,118 +1,128 @@
/**
* @file element.hh
*
* @author Nicolas Richart
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Jan 23 2018
*
* @brief Element helper class
*
* @section LICENSE
*
* Copyright (©) 2014-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_HH__
#define __AKANTU_ELEMENT_HH__
namespace akantu {
/* -------------------------------------------------------------------------- */
/* Element */
/* -------------------------------------------------------------------------- */
class Element {
public:
ElementType type;
UInt element;
GhostType ghost_type;
// ElementKind kind;
// ElementType type{_not_defined};
// UInt element{0};
// GhostType ghost_type{_not_ghost};
// ElementKind kind{_ek_regular};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline ElementKind kind() const;
inline bool operator==(const Element & elem) const {
return std::tie(type, element, ghost_type) ==
std::tie(elem.type, elem.element, elem.ghost_type);
}
inline bool operator!=(const Element & elem) const {
return std::tie(type, element, ghost_type) !=
std::tie(elem.type, elem.element, elem.ghost_type);
}
// inline bool operator==(const Element & elem) const {
// return ((element == elem.element) && (type == elem.type) &&
// (ghost_type == elem.ghost_type) && (kind == elem.kind));
// }
// inline bool operator!=(const Element & elem) const {
// return ((element != elem.element) || (type != elem.type) ||
// (ghost_type != elem.ghost_type) || (kind != elem.kind));
// }
inline bool operator<(const Element & rhs) const;
};
namespace {
const Element ElementNull{_not_defined, UInt(-1), _casper};
// Element{_not_defined, 0, _casper, _ek_not_defined};
} // namespace
/* -------------------------------------------------------------------------- */
inline bool Element::operator<(const Element & rhs) const {
// bool res =
// (rhs == ElementNull) ||
// ((this->kind < rhs.kind) ||
// ((this->kind == rhs.kind) &&
// ((this->ghost_type < rhs.ghost_type) ||
// ((this->ghost_type == rhs.ghost_type) &&
// ((this->type < rhs.type) ||
// ((this->type == rhs.type) && (this->element < rhs.element)))))));
return ((rhs == ElementNull) ||
std::tie(ghost_type, type, element) <
std::tie(rhs.ghost_type, rhs.type, rhs.element));
}
-/// standard output stream operator
-inline std::ostream & operator<<(std::ostream & stream, const Element & _this) {
- if (_this == ElementNull) {
- stream << "ElementNull";
- return stream;
+} // namespace akantu
+
+namespace std {
+inline string to_string(const akantu::Element & _this) {
+ if (_this == akantu::ElementNull) {
+ return "ElementNull";
}
- stream << "Element [" << _this.type << ", " << _this.element << ", "
- << _this.ghost_type << "]";
- return stream;
+ string str = "Element [" + to_string(_this.type) + ", " +
+ to_string(_this.element) + ", " + to_string(_this.ghost_type) +
+ "]";
+ return str;
}
+} // namespace std
+namespace akantu {
+
+/// standard output stream operator
+inline std::ostream & operator<<(std::ostream & stream, const Element & _this) {
+ stream << std::to_string(_this);
+ return stream;
+}
} // namespace akantu
#endif /* __AKANTU_ELEMENT_HH__ */
diff --git a/src/fe_engine/fe_engine_inline_impl.cc b/src/fe_engine/fe_engine_inline_impl.cc
index b3fec52b3..0d7ff04e4 100644
--- a/src/fe_engine/fe_engine_inline_impl.cc
+++ b/src/fe_engine/fe_engine_inline_impl.cc
@@ -1,199 +1,193 @@
/**
* @file fe_engine_inline_impl.cc
*
* @author Guillaume Anciaux
* @author Nicolas Richart
*
* @date creation: Tue Jul 20 2010
* @date last modification: Sun Aug 13 2017
*
* @brief Implementation of the inline functions of the FEEngine Class
*
* @section LICENSE
*
* Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "element_class.hh"
#include "fe_engine.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
#include "element_type_conversion.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FE_ENGINE_INLINE_IMPL_CC__
#define __AKANTU_FE_ENGINE_INLINE_IMPL_CC__
namespace akantu {
/* -------------------------------------------------------------------------- */
inline Real FEEngine::getElementInradius(const Matrix & coord,
const ElementType & type) {
- AKANTU_DEBUG_IN();
-
Real inradius = 0;
#define GET_INRADIUS(type) inradius = ElementClass::getInradius(coord);
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_INRADIUS);
#undef GET_INRADIUS
- AKANTU_DEBUG_OUT();
return inradius;
}
/* -------------------------------------------------------------------------- */
inline InterpolationType
FEEngine::getInterpolationType(const ElementType & type) {
return convertType(type);
}
/* -------------------------------------------------------------------------- */
/// @todo rewrite this function in order to get the cohesive element
/// type directly from the facet
#if defined(AKANTU_COHESIVE_ELEMENT)
inline ElementType FEEngine::getCohesiveElementType(const ElementType & type) {
- AKANTU_DEBUG_IN();
-
ElementType ctype;
#define GET_COHESIVE_TYPE(type) \
ctype = CohesiveFacetProperty::cohesive_type;
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_COHESIVE_TYPE);
#undef GET_COHESIVE_TYPE
- AKANTU_DEBUG_OUT();
return ctype;
}
#else
inline ElementType
FEEngine::getCohesiveElementType(__attribute__((unused))
const ElementType & type_facet) {
return _not_defined;
}
#endif
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
} // akantu
#include "igfem_helper.hh"
namespace akantu {
inline Vector
FEEngine::getIGFEMElementTypes(const ElementType & type) {
#define GET_IGFEM_ELEMENT_TYPES(type) \
return IGFEMHelper::getIGFEMElementTypes();
AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(GET_IGFEM_ELEMENT_TYPES);
#undef GET_IGFEM_ELEMENT_TYPES
}
#endif
/* -------------------------------------------------------------------------- */
template
void FEEngine::extractNodalToElementField(const Mesh & mesh,
const Array & nodal_f,
Array & elemental_f,
const ElementType & type,
const GhostType & ghost_type,
const Array & filter_elements) {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_degree_of_freedom = nodal_f.getNbComponent();
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
if (filter_elements != empty_filter) {
nb_element = filter_elements.size();
}
elemental_f.resize(nb_element);
T * nodal_f_val = nodal_f.storage();
T * f_val = elemental_f.storage();
UInt * el_conn;
for (UInt el = 0; el < nb_element; ++el) {
if (filter_elements != empty_filter)
el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
else
el_conn = conn_val + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = *(el_conn + n);
std::copy(nodal_f_val + node * nb_degree_of_freedom,
nodal_f_val + (node + 1) * nb_degree_of_freedom, f_val);
f_val += nb_degree_of_freedom;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template
void FEEngine::filterElementalData(const Mesh & mesh, const Array & elem_f,
Array & filtered_f,
const ElementType & type,
const GhostType & ghost_type,
const Array & filter_elements) {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (nb_element == 0) {
filtered_f.resize(0);
return;
}
UInt nb_degree_of_freedom = elem_f.getNbComponent();
UInt nb_data_per_element = elem_f.size() / nb_element;
if (filter_elements != empty_filter) {
nb_element = filter_elements.size();
}
filtered_f.resize(nb_element * nb_data_per_element);
T * elem_f_val = elem_f.storage();
T * f_val = filtered_f.storage();
UInt el_offset;
for (UInt el = 0; el < nb_element; ++el) {
if (filter_elements != empty_filter)
el_offset = filter_elements(el);
else
el_offset = el;
std::copy(elem_f_val +
el_offset * nb_data_per_element * nb_degree_of_freedom,
elem_f_val +
(el_offset + 1) * nb_data_per_element * nb_degree_of_freedom,
f_val);
f_val += nb_degree_of_freedom * nb_data_per_element;
}
AKANTU_DEBUG_OUT();
}
} // namespace akantu
#endif /* __AKANTU_FE_ENGINE_INLINE_IMPL_CC__ */
diff --git a/src/mesh_utils/global_ids_updater.cc b/src/mesh_utils/global_ids_updater.cc
index 834f272f8..b3f55fa96 100644
--- a/src/mesh_utils/global_ids_updater.cc
+++ b/src/mesh_utils/global_ids_updater.cc
@@ -1,134 +1,134 @@
/**
* @file global_ids_updater.cc
*
* @author Marco Vocialta
*
* @date creation: Fri Apr 13 2012
* @date last modification: Fri Dec 08 2017
*
* @brief Functions of the GlobalIdsUpdater
*
* @section LICENSE
*
* Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "global_ids_updater.hh"
#include "element_synchronizer.hh"
#include "mesh_accessor.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include
/* -------------------------------------------------------------------------- */
namespace akantu {
UInt GlobalIdsUpdater::updateGlobalIDs(UInt local_nb_new_nodes) {
if (mesh.getCommunicator().getNbProc() == 1)
return local_nb_new_nodes;
UInt total_nb_new_nodes = this->updateGlobalIDsLocally(local_nb_new_nodes);
if (mesh.isDistributed()) {
this->synchronizeGlobalIDs();
}
return total_nb_new_nodes;
}
UInt GlobalIdsUpdater::updateGlobalIDsLocally(UInt local_nb_new_nodes) {
const auto & comm = mesh.getCommunicator();
Int nb_proc = comm.getNbProc();
if (nb_proc == 1)
return local_nb_new_nodes;
/// resize global ids array
MeshAccessor mesh_accessor(mesh);
auto && nodes_global_ids = mesh_accessor.getNodesGlobalIds();
UInt old_nb_nodes = mesh.getNbNodes() - local_nb_new_nodes;
nodes_global_ids.resize(mesh.getNbNodes(), -1);
/// compute the number of global nodes based on the number of old nodes
Vector local_master_nodes(2, 0);
- for (UInt n = 0; n < old_nb_nodes; ++n)
- if (mesh.isLocalOrMasterNode(n))
- ++local_master_nodes(0);
+ auto range_old = arange(old_nb_nodes);
+ local_master_nodes(0) =
+ aka::count_if(range_old.begin(), range_old.end(),
+ [&](auto && n) { return mesh.isLocalOrMasterNode(n); });
/// compute amount of local or master doubled nodes
- for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n)
- if (mesh.isLocalOrMasterNode(n))
- ++local_master_nodes(1);
+ auto range_new = arange(old_nb_nodes, mesh.getNbNodes());
+ local_master_nodes(1) =
+ aka::count_if(range_new.begin(), range_new.end(),
+ [&](auto && n) { return mesh.isLocalOrMasterNode(n); });
auto starting_index = local_master_nodes(1);
comm.allReduce(local_master_nodes);
UInt old_global_nodes = local_master_nodes(0);
UInt total_nb_new_nodes = local_master_nodes(1);
if (total_nb_new_nodes == 0)
return 0;
/// set global ids of local and master nodes
comm.exclusiveScan(starting_index);
starting_index += old_global_nodes;
- for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n) {
+ for (auto n : range_new) {
if (mesh.isLocalOrMasterNode(n)) {
nodes_global_ids(n) = starting_index;
++starting_index;
- } else {
- nodes_global_ids(n) = -1;
}
}
mesh_accessor.setNbGlobalNodes(old_global_nodes + total_nb_new_nodes);
return total_nb_new_nodes;
}
void GlobalIdsUpdater::synchronizeGlobalIDs() {
this->reduce = true;
this->synchronizer.slaveReductionOnce(*this,
SynchronizationTag::_giu_global_conn);
#ifndef AKANTU_NDEBUG
for (auto node : nodes_flags) {
auto node_flag = mesh.getNodeFlag(node.first);
if (node_flag != NodeFlag::_pure_ghost)
continue;
auto n = 0u;
for (auto & pair : node.second) {
if (std::get<1>(pair) == NodeFlag::_pure_ghost)
++n;
}
if (n == node.second.size()) {
AKANTU_DEBUG_WARNING(
"The node " << n << "is ghost on all the neighboring processors");
}
}
#endif
this->reduce = false;
this->synchronizer.synchronizeOnce(*this,
SynchronizationTag::_giu_global_conn);
}
} // namespace akantu
diff --git a/src/synchronizer/element_synchronizer.cc b/src/synchronizer/element_synchronizer.cc
index 736037373..2af3e42db 100644
--- a/src/synchronizer/element_synchronizer.cc
+++ b/src/synchronizer/element_synchronizer.cc
@@ -1,277 +1,290 @@
/**
* @file element_synchronizer.cc
*
* @author Guillaume Anciaux
* @author Dana Christen
* @author Aurelia Isabel Cuba Ramos
* @author Nicolas Richart
* @author Marco Vocialta
*
* @date creation: Wed Sep 01 2010
* @date last modification: Tue Feb 20 2018
*
* @brief implementation of a communicator using a static_communicator for
* real
* send/receive
*
* @section LICENSE
*
* Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu 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.
*
* Akantu 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 Akantu. If not, see .
*
*/
/* -------------------------------------------------------------------------- */
#include "element_synchronizer.hh"
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_utils.hh"
/* -------------------------------------------------------------------------- */
#include
#include
#include