diff --git a/src/common/aka_error.cc b/src/common/aka_error.cc index 36b24bbce..cc2187e90 100644 --- a/src/common/aka_error.cc +++ b/src/common/aka_error.cc @@ -1,201 +1,201 @@ /** * @file aka_error.cc * @author Nicolas Richart * @date Sun Sep 5 21:03:37 2010 * * @brief * * @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_config.hh" #include "aka_error.hh" /* -------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ namespace debug { /* ------------------------------------------------------------------------ */ void initSignalHandler() { struct sigaction action; action.sa_handler = &printBacktrace; sigemptyset(&(action.sa_mask)); action.sa_flags = SA_RESETHAND; sigaction(SIGSEGV, &action, NULL); } /* ------------------------------------------------------------------------ */ std::string demangle(const char* symbol) { int status; std::string result; char * demangled_name; if ((demangled_name = abi::__cxa_demangle(symbol, NULL, 0, &status)) != NULL) { result = demangled_name; free(demangled_name); } else { result = symbol; } return result; //return symbol; } /* ------------------------------------------------------------------------ */ void printBacktrace(int sig) { AKANTU_DEBUG_INFO("Caught signal " << sig << "!"); // std::stringstream pidsstr; // pidsstr << getpid(); // char name_buf[512]; // name_buf[readlink("/proc/self/exe", name_buf, 511)]=0; // std::string execname(name_buf); // std::cout << "stack trace for " << execname << " pid=" << pidsstr.str() << std::endl; // std::string cmd; // cmd = "CMDFILE=$(mktemp); echo 'bt' > ${CMDFILE}; gdb --batch " + execname + " " + pidsstr.str() + " < ${CMDFILE};"; // int retval __attribute__((unused)) = system(("bash -c '" + cmd + "'").c_str()); const size_t max_depth = 100; size_t stack_depth; void *stack_addrs[max_depth]; char **stack_strings; size_t i; stack_depth = backtrace(stack_addrs, max_depth); stack_strings = backtrace_symbols(stack_addrs, stack_depth); std::cerr << "BACKTRACE : " << stack_depth << " stack frames." < " << std::flush; // int retval __attribute__((unused)) = system(syscom.str().c_str()); } else { std::cerr << bt_line << std::endl; } } free(stack_strings); std::cerr << "END BACKTRACE" << std::endl; } /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ Debugger::Debugger() { cout = &std::cerr; level = dblInfo; parallel_context = ""; file_open = false; } /* ------------------------------------------------------------------------ */ Debugger::~Debugger() { if(file_open) { dynamic_cast(cout)->close(); delete cout; } } /* ------------------------------------------------------------------------ */ void Debugger::throwException(const std::string & info) throw(akantu::debug::Exception) { AKANTU_DEBUG(akantu::dblWarning, "!!! " << info); ::akantu::debug::Exception ex(info, __FILE__, __LINE__ ); throw ex; } /* ------------------------------------------------------------------------ */ void Debugger::exit(int status) { int * a = NULL; *a = 1; if (status != EXIT_SUCCESS) akantu::debug::printBacktrace(15); #ifdef AKANTU_USE_MPI MPI_Abort(MPI_COMM_WORLD, MPI_ERR_UNKNOWN); #endif exit(status); // not called when compiled with MPI due to MPI_Abort, but // MPI_Abort does not have the noreturn attribute } /* ------------------------------------------------------------------------ */ void Debugger::setDebugLevel(const DebugLevel & level) { this->level = level; } /* ------------------------------------------------------------------------ */ const DebugLevel & Debugger::getDebugLevel() const { return level; } /* ------------------------------------------------------------------------ */ void Debugger::setLogFile(const std::string & filename) { if(file_open) { dynamic_cast(cout)->close(); delete cout; } std::ofstream * fileout = new std::ofstream(filename.c_str()); file_open = true; cout = fileout; } std::ostream & Debugger::getOutputStream() { return *cout; } /* ------------------------------------------------------------------------ */ void Debugger::setParallelContext(int rank, int size) { std::stringstream sstr; sstr << "[" << std::setfill(' ') << std::right << std::setw(3) << (rank + 1) << "/" << size << "] "; parallel_context = sstr.str(); } void setDebugLevel(const DebugLevel & level) { debugger.setDebugLevel(level); } } __END_AKANTU__ diff --git a/src/common/aka_math.hh b/src/common/aka_math.hh index 73845924e..502430109 100644 --- a/src/common/aka_math.hh +++ b/src/common/aka_math.hh @@ -1,236 +1,240 @@ /** * @file aka_math.hh * @author Nicolas Richart * @date Wed Jul 28 11:51:56 2010 * * @brief mathematical operations * * @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 . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_AKA_MATH_H__ #define __AKANTU_AKA_MATH_H__ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ template class Vector; class Math { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Matrix algebra */ /* ------------------------------------------------------------------------ */ /// @f$ y = A*x @f$ static void matrix_vector(UInt m, UInt n, const Vector & A, const Vector & x, Vector & y, Real alpha = 1.); /// @f$ y = A*x @f$ static inline void matrix_vector(UInt m, UInt n, const Real * A, const Real * x, Real * y, Real alpha = 1.); /// @f$ y = A^t*x @f$ static inline void matrixt_vector(UInt m, UInt n, const Real * A, const Real * x, Real * y, Real alpha = 1.); /// @f$ C = A*B @f$ static void matrix_matrix(UInt m, UInt n, UInt k, const Vector & A, const Vector & B, Vector & C, Real alpha = 1.); /// @f$ C = A*B^t @f$ static void matrix_matrixt(UInt m, UInt n, UInt k, const Vector & A, const Vector & B, Vector & C, Real alpha = 1.); /// @f$ C = A*B @f$ static inline void matrix_matrix(UInt m, UInt n, UInt k, const Real * A, const Real * B, Real * C, Real alpha = 1.); /// @f$ C = A^t*B @f$ static inline void matrixt_matrix(UInt m, UInt n, UInt k, const Real * A, const Real * B, Real * C, Real alpha = 1.); /// @f$ C = A*B^t @f$ static inline void matrix_matrixt(UInt m, UInt n, UInt k, const Real * A, const Real * B, Real * C, Real alpha = 1.); /// @f$ C = A^t*B^t @f$ static inline void matrixt_matrixt(UInt m, UInt n, UInt k, const Real * A, const Real * B, Real * C, Real alpha = 1.); template static inline void matMul(UInt m, UInt n, UInt k, Real alpha, const Real * A, const Real * B, Real beta, Real * C); template static inline void matVectMul(UInt m, UInt n, Real alpha, const Real * A, const Real * x, Real beta, Real * y); static void matrix33_eigenvalues(Real * A, Real * Adiag); /// solve @f$ A x = \Lambda x @f$ and return d and V such as @f$ A V[i:] = D[i] V[i:]@f$ static void matrixEig(UInt n, Real * A, Real * d, Real * V); /// determinent of a 3x3 matrix static inline Real det3(const Real * mat); /// determinent of a 2x2 matrix static inline Real det2(const Real * mat); /// inverse a 3x3 matrix static inline void inv3(const Real * mat, Real * inv); /// inverse a 2x2 matrix static inline void inv2(const Real * mat, Real * inv); /* ------------------------------------------------------------------------ */ /* Vector algebra */ /* ------------------------------------------------------------------------ */ /// vector cross product static inline void vectorProduct3(const Real * v1, const Real * v2, Real * res); /// compute normal a normal to a vector static inline void normal2(const Real * v1, Real * res); /// compute normal a normal to a vector static inline void normal3(const Real * v1,const Real * v2, Real * res); /// normalize a vector static inline void normalize2(Real * v); /// normalize a vector static inline void normalize3(Real * v); /// return norm of a 2-vector static inline Real norm2(const Real * v); /// return norm of a 3-vector static inline Real norm3(const Real * v); /// return norm of a vector static inline Real norm(UInt n, const Real * v); /// return the dot product between 2 vectors in 2d static inline Real vectorDot2(const Real * v1, const Real * v2); /// return the dot product between 2 vectors in 3d static inline Real vectorDot3(const Real * v1, const Real * v2); /// return the dot product between 2 vectors static __aka_inline__ Real vectorDot(const Real * v1, const Real * v2, UInt n); /* ------------------------------------------------------------------------ */ /* Geometry */ /* ------------------------------------------------------------------------ */ /// distance in 2D between x and y static inline Real distance_2d(const Real * x, const Real * y); /// distance in 3D between x and y static inline Real distance_3d(const Real * x, const Real * y); /// radius of the in-circle of a triangle static inline Real triangle_inradius(const Real * coord1, const Real * coord2, const Real * coord3); /// radius of the in-circle of a tetrahedron static inline Real tetrahedron_inradius(const Real * coord1, const Real * coord2, const Real * coord3, const Real * coord4); /// volume of a tetrahedron static inline Real tetrahedron_volume(const Real * coord1, const Real * coord2, const Real * coord3, const Real * coord4); /// compute the barycenter of n points static inline void barycenter(const Real * coord, UInt nb_points, UInt spatial_dimension, Real * barycenter); /// vector between x and y static inline void vector_2d(const Real * x, const Real * y, Real * vec); /// vector pointing from x to y in 3 spatial dimension static inline void vector_3d(const Real * x, const Real * y, Real * vec); /// test if two scalar are equal within a given tolerance static inline bool are_float_equal(Real x, Real y); /// test if two vectors are equal within a given tolerance static inline bool are_vector_equal(UInt n, Real * x, Real * y); +#ifdef isnan +# error "You probably included which is incompatible with aka_math please use\ + or add a \"#undef isnan\" before akantu includes" +#endif /// test if a real is a NaN static inline bool isnan(Real x); /// test if the line x and y intersects each other static inline bool intersects(Real x_min, Real x_max, Real y_min, Real y_max); /// test if a is in the range [x_min, x_max] static inline bool is_in_range(Real a, Real x_min, Real x_max); static inline Real getTolerance() { return tolerance; }; static inline void setTolerance(Real tol) { tolerance = tol; }; private: /// tolerance for functions that need one static Real tolerance; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "aka_math_tmpl.hh" __END_AKANTU__ #endif /* __AKANTU_AKA_MATH_H__ */ diff --git a/src/common/aka_static_memory_tmpl.hh b/src/common/aka_static_memory_tmpl.hh index e941f36ae..0f11c2469 100644 --- a/src/common/aka_static_memory_tmpl.hh +++ b/src/common/aka_static_memory_tmpl.hh @@ -1,83 +1,83 @@ /** * @file aka_static_memory_tmpl.hh * @author Nicolas Richart * @date Fri Nov 25 13:53:08 2011 * * @brief template part of the StaticMemory * * @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 . * */ /* -------------------------------------------------------------------------- */ template Vector & StaticMemory::smalloc(const MemoryID & memory_id, const ID & name, UInt size, UInt nb_component) { AKANTU_DEBUG_IN(); MemoryMap::iterator memory_it; memory_it = memories.find(memory_id); if(memory_it == memories.end()){ memories[memory_id] = VectorMap(); memory_it = memories.find(memory_id); } if((memory_it->second).find(name) != (memory_it->second).end()) { AKANTU_DEBUG_ERROR("The vector \"" << name << "\" is already registred in the memory " << memory_id); } Vector * tmp_vect = new Vector(size, nb_component, name); - (memory_it->second)[name] = dynamic_cast(tmp_vect); + (memory_it->second)[name] = tmp_vect; AKANTU_DEBUG_OUT(); return *tmp_vect; } /* -------------------------------------------------------------------------- */ template Vector & StaticMemory::smalloc(const MemoryID & memory_id, const ID & name, UInt size, UInt nb_component, const T & init_value) { AKANTU_DEBUG_IN(); MemoryMap::iterator memory_it; memory_it = memories.find(memory_id); if(memory_it == memories.end()){ memories[memory_id] = VectorMap(); memory_it = memories.find(memory_id); } if((memory_it->second).find(name) != (memory_it->second).end()) { AKANTU_DEBUG_ERROR("The vector \"" << name << "\" is already registred in the memory " << memory_id); } Vector * tmp_vect = new Vector(size, nb_component, init_value, name); - (memory_it->second)[name] = dynamic_cast(tmp_vect); + (memory_it->second)[name] = tmp_vect; AKANTU_DEBUG_OUT(); return *tmp_vect; } /* -------------------------------------------------------------------------- */ diff --git a/src/common/aka_types.hh b/src/common/aka_types.hh index 4901a1cc3..8d3f6002c 100644 --- a/src/common/aka_types.hh +++ b/src/common/aka_types.hh @@ -1,476 +1,475 @@ /** * @file aka_types.hh * @author Nicolas Richart * @date Wed Feb 16 20:28:13 2011 * * @brief description of the "simple" types * * @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_error.hh" #include "aka_math.hh" #include "aka_vector.hh" /* -------------------------------------------------------------------------- */ #include #ifndef __INTEL_COMPILER #include #else #include #endif /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_AKA_TYPES_HH__ #define __AKANTU_AKA_TYPES_HH__ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /* maps */ /* -------------------------------------------------------------------------- */ #ifndef __INTEL_COMPILER template struct unordered_map { typedef typename std::tr1::unordered_map type; }; #else template struct unordered_map { typedef typename std::map type; }; #endif namespace types { class Matrix; /* ------------------------------------------------------------------------ */ /* Vector */ /* ------------------------------------------------------------------------ */ template class Vector { public: Vector() : n(0), values(NULL), wrapped(false) {} Vector(UInt n, T def = T()) : n(n), values(new T[n]), wrapped(false) { std::fill_n(values, n, def); } Vector(T* data, UInt n) : n(n), values(data), wrapped(true) {} Vector(const Vector & src) { wrapped = src.wrapped; n = src.n; if (src.wrapped) { values = src.values; } else { values = new T[n]; memcpy(this->values, src.values, n * sizeof(T)); } } virtual ~Vector() { if(!wrapped) delete [] values; }; /* ---------------------------------------------------------------------- */ UInt size() const { return n; } T * storage() const { return values; } /* ---------------------------------------------------------------------- */ void shallowCopy(const Vector & src) { if(!wrapped) delete [] values; this->n = src.n; this->wrapped = true; this->values = src.values; } /* ---------------------------------------------------------------------- */ inline T& operator()(UInt i) { return *(values + i); }; inline const T& operator()(UInt i) const { return *(values + i); }; inline T& operator[](UInt idx) { return *(values + idx); }; inline const T& operator[](UInt idx) const { return *(values + idx); }; /* ---------------------------------------------------------------------- */ inline Vector & operator=(const Vector & src) { if(this != &src) { if (wrapped) { AKANTU_DEBUG_ASSERT(n == src.n, "vectors of different size"); memcpy(this->values, src.values, n * sizeof(T)); } else { n = src.n; delete []values; values = new T[n]; memcpy(this->values, src.values, n * sizeof(T)); } } return *this; } /* ---------------------------------------------------------------------- */ inline Vector & operator+=(const Vector & vect) { T * a = this->storage(); T * b = vect.storage(); for (UInt i = 0; i < n; ++i) *(a++) += *(b++); return *this; } /* ---------------------------------------------------------------------- */ inline Vector & operator+=(const T & x) { T * a = this->values; for (UInt i = 0; i < n; ++i) *(a++) += x; return *this; } /* ---------------------------------------------------------------------- */ inline Vector & operator-=(const Vector & vect) { T * a = this->storage(); T * b = vect.storage(); for (UInt i = 0; i < n; ++i) *(a++) -= *(b++); return *this; } /* ---------------------------------------------------------------------- */ inline Vector & operator*=(const T & scalar) { T * a = this->storage(); for (UInt i = 0; i < n; ++i) *(a++) *= scalar; return *this; } /* -------------------------------------------------------------------------- */ inline Vector & operator=(T & scalar) { T * a = this->storage(); for (UInt i = 0; i < n; ++i) *(a++) = scalar; return *this; } /* ---------------------------------------------------------------------- */ inline Vector & operator/=(const T & x) { T * a = this->values; for (UInt i = 0; i < n; ++i) *(a++) /= x; return *this; } /* ---------------------------------------------------------------------- */ inline Real dot(const Vector & vect) { return Math::vectorDot(values, vect.storage(), n); } /* ---------------------------------------------------------------------- */ inline Vector & crossProduct(const Vector & v1, const Vector & v2) { AKANTU_DEBUG_ASSERT(n == 3, "crossProduct is only defined in 3D"); AKANTU_DEBUG_ASSERT(n == v1.n && n == v2.n, "crossProduct is not a valid operation non matching size vectors"); // for (UInt i = 0; i < n; ++i) { // values[i] = // v1((i+1) % n) * v2((i+2) % n) - // v1((i+2) % n) * v1((i+1) % n); // } Math::vectorProduct3(v1.values, v2.values, this->values); return *this; } /* ---------------------------------------------------------------------- */ inline void clear() { memset(values, 0, n * sizeof(T)); }; template inline void mul(const Matrix & A, const Vector & x, Real alpha = 1.0); /* ---------------------------------------------------------------------- */ inline Real norm() const { return Math::norm(this->n, this->values); } /* ---------------------------------------------------------------------- */ /// norm of (*this - x) inline Real distance(const Vector & y) const { Real * vx = values; Real * vy = y.storage(); Real sum_2 = 0; for (UInt i = 0; i < n; ++i, ++vx, ++vy) sum_2 += (*vx - *vy)*(*vx - *vy); return sqrt(sum_2); } /* ---------------------------------------------------------------------- */ /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "types::Vector<" << debug::demangle(typeid(T).name()) << "> [" << n <<"] :" << std::endl; stream << space << AKANTU_INDENT << "| "; for (UInt i = 0; i < n; ++i) { stream << values[i] << " "; } stream << "|" << std::endl; } friend class ::akantu::Vector; protected: UInt n; T * values; bool wrapped; }; typedef Vector RVector; // support operations for the creation of other vectors template Vector operator*(T scalar, const Vector& a); template Vector operator+(const Vector& a, const Vector& b); template Vector operator-(const Vector& a, const Vector& b); /* -------------------------------------------------------------------------- */ template Vector operator*(T scalar, const Vector& a) { Vector r = a; r *= scalar; return r; } template Vector operator+(const Vector& a, const Vector& b) { Vector r = a; r += b; return r; } template Vector operator-(const Vector& a, const Vector& b) { Vector r = a; r -= b; return r; } /* ------------------------------------------------------------------------ */ /* Matrix */ /* ------------------------------------------------------------------------ */ class Matrix { public: Matrix() : m(0), n(0), values(NULL), wrapped(true) {}; Matrix(UInt m, UInt n, Real def = 0) : m(m), n(n), values(new Real[n*m]), wrapped(false) { std::fill_n(values, n*m, def); }; Matrix(Real* data, UInt m, UInt n) : m(m), n(n), values(data), wrapped(true) {}; Matrix(const Matrix & src) { m = src.m; n = src.n; values = src.values; wrapped = src.wrapped; const_cast(src).wrapped = true; }; virtual ~Matrix() { if(!wrapped) delete [] values; }; /* ---------------------------------------------------------------------- */ UInt size() const { return n*m; }; UInt rows() const { return m; }; UInt cols() const { return n; }; Real * storage() const { return values; }; /* ---------------------------------------------------------------------- */ inline Real& operator()(UInt i, UInt j) { return *(values + i*n + j); }; inline const Real& operator()(UInt i, UInt j) const { return *(values + i*n + j); }; inline Real& operator[](UInt idx) { return *(values + idx); }; inline const Real& operator[](UInt idx) const { return *(values + idx); }; inline Matrix & operator=(const Matrix & mat) { if(this != &mat) { if(values != NULL) { memcpy(this->values, mat.values, m*n*sizeof(Real)); } else { this->m = mat.m; this->n = mat.n; this->values = mat.values; const_cast(mat).wrapped = true; this->wrapped = false; } } return *this; }; /* ---------------------------------------------------------------------- */ inline Matrix operator* (const Matrix & B) { Matrix C(this->m, B.n); - C.mul(*this, B); - + C.mul(*this, B); return C; }; /* -------------------------------------------------------------------------- */ inline Matrix & operator+= (const Matrix & B) { for (UInt i = 0; i < m*n; ++i) { values[i] += B[i]; } return *this; }; /* ---------------------------------------------------------------------- */ inline Matrix & operator+=(Real x) { Real * a = this->values; for (UInt i = 0; i < n*m; ++i) *(a++) += x; return *this; } /* ---------------------------------------------------------------------- */ inline Matrix & operator*=(Real x) { Real * a = this->storage(); for (UInt i = 0; i < n*m; ++i) *(a++) *= x; return *this; } /* ---------------------------------------------------------------------- */ inline Matrix & operator/=(Real x) { Real * a = this->values; for (UInt i = 0; i < n*m; ++i) *(a++) /= x; return *this; } /* ---------------------------------------------------------------------- */ template inline void mul(const Matrix & A, const Matrix & B, Real alpha = 1.0) { UInt k = A.n; if(tr_A) k = A.m; #ifndef AKANTU_NDEBUG if (tr_B){ AKANTU_DEBUG_ASSERT(k == B.n, "matrices to multiply have no fit dimensions"); AKANTU_DEBUG_ASSERT(n == B.m, "matrices to multiply have no fit dimensions"); } else { AKANTU_DEBUG_ASSERT(k == B.m, "matrices to multiply have no fit dimensions"); AKANTU_DEBUG_ASSERT(n == B.n, "matrices to multiply have no fit dimensions"); } if (tr_A){ AKANTU_DEBUG_ASSERT(m == A.n, "matrices to multiply have no fit dimensions"); } else{ AKANTU_DEBUG_ASSERT(m == A.m, "matrices to multiply have no fit dimensions"); } #endif //AKANTU_NDEBUG Math::matMul(m, n, k, alpha, A.storage(), B.storage(), 0., values); } /* ---------------------------------------------------------------------- */ inline void eig(types::Vector & eigenvalues, Matrix & eigenvectors) const { AKANTU_DEBUG_ASSERT(n == m, "eig is not a valid operation on a rectangular matrix"); Math::matrixEig(this->n, this->values, eigenvalues.storage(), eigenvectors.storage()); } /* ---------------------------------------------------------------------- */ inline void clear() { std::fill_n(values, m * n, 0); }; /* ---------------------------------------------------------------------- */ inline void copy(const Matrix & src) { memcpy(values, src.storage(), m * n * sizeof(Real)); } /* ---------------------------------------------------------------------- */ inline void eye(Real alpha = 1.) { AKANTU_DEBUG_ASSERT(n == m, "eye is not a valid operation on a rectangular matrix"); clear(); for (UInt i = 0; i < n; ++i) { values[i*n + i] = alpha; } } /* ---------------------------------------------------------------------- */ inline Real trace() const { AKANTU_DEBUG_ASSERT(n == m, "trace is not a valid operation on a rectangular matrix"); Real trace = 0.; for (UInt i = 0; i < n; ++i) trace += values[i*n + i]; return trace; } /* -------------------------------------------------------------------------- */ inline Real norm() const { return Math::norm(this->n*this->m, this->values); } /* ---------------------------------------------------------------------- */ inline Matrix transpose() const { Matrix tmp(m, n); for (UInt i = 0; i < n; ++i) { for (UInt j = 0; j < m; ++j) { tmp(j,i) = operator()(i,j); } } return tmp; } /* ---------------------------------------------------------------------- */ /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "types::Matrix" << " [" << n << "," << m <<"] :" << std::endl; for (UInt i = 0; i < m; ++i) { stream << space << AKANTU_INDENT << "| "; for (UInt j = 0; j < n; ++j) { stream << std::setw(10) << values[i*n +j] << " "; } stream << "|" << std::endl; } }; friend class ::akantu::Vector; protected: UInt m; UInt n; Real* values; bool wrapped; }; /* ------------------------------------------------------------------------ */ template template inline void Vector::mul(const Matrix & A, const Vector & x, Real alpha) { UInt n = x.n; Math::matVectMul(this->n, n, alpha, A.storage(), x.storage(), 0., values); } /* -------------------------------------------------------------------------- */ inline std::ostream & operator<<(std::ostream & stream, const Matrix & _this) { _this.printself(stream); return stream; } /* -------------------------------------------------------------------------- */ template inline std::ostream & operator<<(std::ostream & stream, const Vector & _this) { _this.printself(stream); return stream; } } __END_AKANTU__ #endif /* __AKANTU_AKA_TYPES_HH__ */ diff --git a/src/common/aka_types_expression.hh b/src/common/aka_types_expression.hh deleted file mode 100644 index ed209f0a7..000000000 --- a/src/common/aka_types_expression.hh +++ /dev/null @@ -1,255 +0,0 @@ -/** - * @file aka_types_expression.hh - * @author Nicolas Richart - * @date Sat Mar 26 22:20:09 2011 - * - * @brief expressions template for types operations, inspired from a work of - * Alejandro Aragón - * - * @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_math.hh" -#include "aka_types.hh" - -#ifndef __AKANTU_AKA_TYPES_EXPRESSION_HH__ -#define __AKANTU_AKA_TYPES_EXPRESSION_HH__ - -__BEGIN_AKANTU__ - -//namespace types { - - /* ------------------------------------------------------------------------ */ - template struct ResultType; - - /* ------------------------------------------------------------------------ */ - template - class Expression { - public: - typedef A Type; - typedef typename A::Return Return; - typedef typename A::LeftVal LeftVal; - typedef typename A::RightVal RightVal; - - Expression(const A & a) : exp(a) { }; - - Return operator() () { return exp; }; - LeftVal left() const { return exp.left(); }; - RightVal right() const { return exp.right(); }; - - - private: - A & exp; - }; - - template - class BinaryOperation { - public: - typedef const L & LeftVal; - typedef const R & RightVal; - typedef typename ResultType > >::Type Return; - typedef Op Operator; - - BinaryOperation(LeftVal a, RightVal b) : _left(a), _right(b) {}; - BinaryOperation(L & a, RightVal b) : _left(a), _right(b) {}; - - LeftVal left() const { return _left; }; - RightVal right() const { return _right; }; - - inline Return operator() () const { - return Operator::apply(_left, _right); - } - - private: - LeftVal _left; - RightVal _right; - }; - - /* ------------------------------------------------------------------------ */ - template - class UnaryOperation { - public: - typedef const R & RightVal; - typedef const R & LeftVal; - typedef typename ResultType > >::Type Return; - typedef Op Operator; - - UnaryOperation(RightVal b) : _right(b) {}; - UnaryOperation(R & b) : _right(b) {}; - - RightVal right() const { return _right; }; - - inline Return operator() () const { - return Operator::apply(_right); - } - - private: - RightVal _right; - }; - - /* ------------------------------------------------------------------------ */ - class MultiplyOp; - class TransposeOp; - -typedef types::Matrix Mat; -typedef types::Vector Vect; - typedef Expression > MatxMat; - typedef Expression > SxMat; - typedef Expression > TrMat; - typedef Expression > TrVect; - - template <> struct ResultType > > { typedef Matrix Type; }; - - template <> struct ResultType > > { typedef Matrix Type; }; - template <> struct ResultType > > { typedef Matrix Type; }; - template <> struct ResultType > > { typedef Matrix Type; }; - - template <> struct ResultType > > { typedef Matrix Type; }; - template <> struct ResultType > > { typedef Matrix Type; }; - template <> struct ResultType > > { typedef Matrix Type; }; - - template <> struct ResultType > > { typedef Matrix Type; }; - template <> struct ResultType > > { typedef Matrix Type; }; - template <> struct ResultType > > { typedef Vect Type; }; - - template <> struct ResultType > > { typedef Matrix Type; }; - - template <> struct ResultType > > { typedef Vect Type; }; - template <> struct ResultType > > { typedef Mat Type; }; - template <> struct ResultType > > { typedef Mat Type; }; - template <> struct ResultType > > { typedef Mat Type; }; - - - /* ------------------------------------------------------------------------ */ - class TransposeOp { - public: - TransposeOp() {}; - }; - - /* ------------------------------------------------------------------------ */ - class MultiplyOp { - public: - MultiplyOp() {}; - - template - static inline typename ResultType > >::Type apply(const L & a, const R & b) { - return apply(a, b); - } - - - /* ---------------------------------------------------------------------- */ - /* Blas 2 */ - /* ---------------------------------------------------------------------- */ - /// @f[ y = A * x @f] - static inline Vect apply(const Mat & a, const Vect & x) { - Vect y(x.size()); - Math::matVectMul(a.rows(), a.cols(), - 1., a.storage(), x.storage(), - 0., y.storage()); - return y; - } - - /// @f[ y = A^t * x @f] - static inline Vect apply(const TrMat & at, const Vect & x) { - const Mat & a = at.right(); - Vect y(x.size()); - Math::matVectMul(a.rows(), a.cols(), - 1., a.storage(), x.storage(), - 0., y.storage()); - return y; - } - - /* ---------------------------------------------------------------------- */ - /* Blas 3 */ - /* ---------------------------------------------------------------------- */ - /// @f[ C = A * x^t @f] - static inline Mat apply(const Vect & x, const TrVect & yt) { - const Vect & y = yt.right(); - Mat c(x.size(), y.size()); - Math::matMul(x.size(), y.size(), 1, - 1., x.storage(), y.storage(), - 0., c.storage()); - return c; - } - - /// @f[ y = A^t * x^t @f] - static inline Mat apply(const TrVect & xt, const Vect & y) { - const Vect & x = xt.right(); - Mat c(y.size(), x.size()); - Math::matMul(y.size(), x.size(), 1, - 1., x.storage(), y.storage(), - 0., c.storage()); - return c; - } - - - /// @f[ C = A * B @f] - static inline Mat apply(const Mat & a, const Mat & b) { - Mat c(a.rows(), b.cols()); - Math::matMul(a.rows(), b.cols(), a.cols(), - 1., a.storage(), b.storage(), - 0., c.storage()); - return c; - } - - /// @f[ C = A^t * B @f] - static inline Mat apply(const TrMat & at, const Mat & b) { - const Mat & a = at.right(); - Mat c(a.rows(), b.cols()); - Math::matMul(a.rows(), b.cols(), a.cols(), - 1., a.storage(), b.storage(), - 0., c.storage()); - return c; - } - - /// @f[ C = A * B^t @f] - static inline Mat apply(const Mat & a, const TrMat & bt) { - const Mat & b = bt.right(); - Mat c(a.rows(), b.cols()); - Math::matMul(a.rows(), b.cols(), a.cols(), - 1., a.storage(), b.storage(), - 0., c.storage()); - return c; - } - - /// @f[ C = A^t * B^t @f] - static inline Mat apply(const TrMat & at, const TrMat & bt) { - const Mat & a = at.right(); - const Mat & b = bt.right(); - Mat c(a.rows(), b.cols()); - Math::matMul(a.rows(), b.cols(), a.cols(), - 1., a.storage(), b.storage(), - 0., c.storage()); - return c; - } - }; - - template - inline typename ResultType > >::Type - operator* (const A & a, const A & b) { - return Expression >(BinaryOperation(a,b)); - } - -//} // namespace types - -__END_AKANTU__ - -#endif /* __AKANTU_AKA_TYPES_EXPRESSION_HH__ */ diff --git a/src/model/integration_scheme/integration_scheme_1st_order.hh b/src/model/integration_scheme/integration_scheme_1st_order.hh index eae670fc5..b82471023 100644 --- a/src/model/integration_scheme/integration_scheme_1st_order.hh +++ b/src/model/integration_scheme/integration_scheme_1st_order.hh @@ -1,88 +1,89 @@ /** * @file integration_scheme_1st_order.hh * @author Nicolas Richart * @date Thu Jun 30 16:28:13 2011 * * @brief Interface of the time integrator of first order * * @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_common.hh" #ifndef __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__ #define __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__ __BEGIN_AKANTU__ class IntegrationScheme1stOrder { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: enum IntegrationSchemeCorrectorType { _temperature_corrector, _temperature_rate_corrector }; virtual ~IntegrationScheme1stOrder() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: virtual void integrationSchemePred(Real delta_t, Vector & u, Vector & u_dot, Vector & boundary) = 0; virtual void integrationSchemeCorrTemp(Real delta_t, Vector & u, Vector & u_dot, Vector & boundary, Vector & delta) = 0; virtual void integrationSchemeCorrTempRate(Real delta_t, Vector & u, Vector & u_dot, Vector & boundary, Vector & delta) = 0; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: }; __END_AKANTU__ #include "generalized_trapezoidal.hh" #endif /* __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__ */ diff --git a/src/model/parser.hh b/src/model/parser.hh index 18000783a..76c8b914b 100644 --- a/src/model/parser.hh +++ b/src/model/parser.hh @@ -1,99 +1,100 @@ /** * @file material_parser.hh * @author Guillaume ANCIAUX * @date Thu Nov 25 11:43:48 2010 * * @brief * * @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 . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_PARSER_HH__ #define __AKANTU_MATERIAL_PARSER_HH__ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ class Parser { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: Parser() : current_line(0) {}; virtual ~Parser(){ infile.close(); }; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// open a file to parse void open(const std::string & filename); /// read the file and return the next material type std::string getNextSection(const std::string & obj_type); /// read properties and instanciate a given material object template void readSection(M & model); - template - Obj * readSection(Model & model, std::string & obj_name); + + template + Obj * readSection(M & model, std::string & obj_name); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: inline void my_getline(); /// number of the current line UInt current_line; /// material file std::ifstream infile; /// current read line std::string line; }; #include "parser_tmpl.hh" #if defined (AKANTU_INCLUDE_INLINE_IMPL) # include "parser_inline_impl.cc" #endif __END_AKANTU__ #endif diff --git a/src/model/parser_tmpl.hh b/src/model/parser_tmpl.hh index 46ca5ee9b..c4426cf48 100644 --- a/src/model/parser_tmpl.hh +++ b/src/model/parser_tmpl.hh @@ -1,86 +1,86 @@ /** * @file parser_tmpl.hh * @author Nicolas Richart * @date Thu Nov 24 08:44:22 2011 * * @brief Template part of the parser * * @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 . * */ /* -------------------------------------------------------------------------- */ template inline void Parser::readSection(M & model){ std::string keyword; std::string value; my_getline(); while(line[0] != ']') { size_t pos = line.find("="); if(pos == std::string::npos) AKANTU_DEBUG_ERROR("Malformed material file : line must be \"key = value\" at line" << current_line); keyword = line.substr(0, pos); trim(keyword); value = line.substr(pos + 1); trim(value); if(!model.setParam(keyword, value)) { AKANTU_DEBUG_ERROR("Malformed material file : error in setParam at line " << current_line <<"." << " Parameter (" << keyword << ") is not recognized!"); } my_getline(); } } /* -------------------------------------------------------------------------- */ -template -inline Obj * Parser::readSection(Model & model,std::string & obj_name){ +template +inline Obj * Parser::readSection(ParentType & parent, std::string & obj_name){ std::string keyword; std::string value; /// instanciate the material object - Obj * obj = new Obj(model, obj_name); + Obj * obj = new Obj(parent, obj_name); /// read the material properties my_getline(); while(line[0] != ']') { size_t pos = line.find("="); if(pos == std::string::npos) AKANTU_DEBUG_ERROR("Malformed material file : line must be \"key = value\" at line" << current_line); keyword = line.substr(0, pos); trim(keyword); value = line.substr(pos + 1); trim(value); try { obj->setParam(keyword, value, obj_name); } catch (debug::Exception ex) { AKANTU_DEBUG_ERROR("Malformed material file : error in setParam \"" << ex.info() << "\" at line " << current_line); } my_getline(); } return obj; } diff --git a/src/model/solid_mechanics/material.cc b/src/model/solid_mechanics/material.cc index dd0e56350..413282243 100644 --- a/src/model/solid_mechanics/material.cc +++ b/src/model/solid_mechanics/material.cc @@ -1,533 +1,536 @@ /** * @file material.cc * @author Nicolas Richart * @date Tue Jul 27 11:43:41 2010 * * @brief Implementation of the common part of the material class * * @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 "material.hh" #include "solid_mechanics_model.hh" #include "sparse_matrix.hh" #include "dof_synchronizer.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -Material::Material(Model & model, const ID & id) : +Material::Material(SolidMechanicsModel & model, const ID & id) : Memory(model.getMemoryID()), id(id), name(""), + model(&model), stress("stress", id), strain("strain", id), element_filter("element_filter", id), // potential_energy_vector(false), potential_energy("potential_energy", id), - is_init(false), - is_non_local(false) { + is_non_local(false), is_init(false) { + AKANTU_DEBUG_IN(); rho = 0; - this->model = dynamic_cast(&model); AKANTU_DEBUG_ASSERT(this->model,"model has wrong type: cannot proceed"); spatial_dimension = this->model->getSpatialDimension(); /// allocate strain stress for local elements initInternalVector(strain, spatial_dimension * spatial_dimension); initInternalVector(stress, spatial_dimension * spatial_dimension); /// for each connectivity types allocate the element filer array of the material initInternalVector(element_filter, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Material::~Material() { AKANTU_DEBUG_IN(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ bool Material::setParam(const std::string & key, const std::string & value, __attribute__ ((unused)) const ID & id) { std::stringstream sstr(value); if(key == "name") name = std::string(value); else if(key == "rho") { sstr >> rho; } else return false; return true; } /* -------------------------------------------------------------------------- */ void Material::initMaterial() { AKANTU_DEBUG_IN(); resizeInternalVector(stress); resizeInternalVector(strain); + is_init = true; + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::initInternalVector(ByElementTypeVector & vect, UInt nb_component, ElementKind element_kind) const { AKANTU_DEBUG_IN(); model->getFEM().getMesh().initByElementTypeVector(vect, nb_component, spatial_dimension, false, element_kind); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::resizeInternalVector(ByElementTypeVector & by_el_type_vect, ElementKind element_kind) const { AKANTU_DEBUG_IN(); FEM * fem = & model->getFEM(); if (element_kind == _ek_cohesive) fem = & model->getFEM("CohesiveFEM"); const Mesh & mesh = fem->getMesh(); for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, element_kind); Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt, element_kind); for(; it != end; ++it) { const Vector & elem_filter = element_filter(*it, gt); UInt nb_element = elem_filter.getSize(); UInt nb_quadrature_points = fem->getNbQuadraturePoints(*it, gt); UInt new_size = nb_element * nb_quadrature_points; Vector & vect = by_el_type_vect(*it, gt); UInt size = vect.getSize(); UInt nb_component = vect.getNbComponent(); vect.resize(new_size); memset(vect.storage() + size * nb_component, 0, (new_size - size) * nb_component * sizeof(T)); } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the residual by assembling @f$\int_{e} \sigma_e \frac{\partial * \varphi}{\partial X} dX @f$ * * @param[in] displacements nodes displacements * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void Material::updateResidual(Vector & displacement, GhostType ghost_type) { AKANTU_DEBUG_IN(); computeStress(displacement, ghost_type); assembleResidual(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::assembleResidual(GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); Vector & residual = const_cast &>(model->getResidual()); Mesh & mesh = model->getFEM().getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { const Vector & shapes_derivatives = model->getFEM().getShapesDerivatives(*it, ghost_type); Vector & elem_filter = element_filter(*it, ghost_type); - - UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it); UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(*it, ghost_type); UInt nb_element = elem_filter.getSize(); /// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by @f$\mathbf{B}^t \mathbf{\sigma}_q@f$ Vector * sigma_dphi_dx = new Vector(nb_element*nb_quadrature_points, size_of_shapes_derivatives, "sigma_x_dphi_/_dX"); Real * shapesd = shapes_derivatives.storage(); Real * shapesd_val; UInt * elem_filter_val = elem_filter.storage(); Vector * shapesd_filtered = new Vector(nb_element*nb_quadrature_points, size_of_shapes_derivatives, "filtered shapesd"); Real * shapesd_filtered_val = shapesd_filtered->values; for (UInt el = 0; el < nb_element; ++el) { shapesd_val = shapesd + elem_filter_val[el] * size_of_shapes_derivatives * nb_quadrature_points; memcpy(shapesd_filtered_val, shapesd_val, size_of_shapes_derivatives * nb_quadrature_points * sizeof(Real)); shapesd_filtered_val += size_of_shapes_derivatives * nb_quadrature_points; } Vector & stress_vect = stress(*it, ghost_type); // Vector::iterator sigma = stress_vect.begin(spatial_dimension, spatial_dimension); // Vector::iterator sigma_end = stress_vect.end(spatial_dimension, spatial_dimension); // Vector::iterator nabla_B = shapesd_filtered->begin(nb_nodes_per_element, spatial_dimension); // Vector::iterator sigma_dphi_dx_it = sigma_dphi_dx->begin(nb_nodes_per_element, spatial_dimension); // for (; sigma != sigma_end; ++sigma, ++nabla_B, ++sigma_dphi_dx_it) { // sigma_dphi_dx_it->mul(*nabla_B, *sigma); // } Math::matrix_matrixt(nb_nodes_per_element, spatial_dimension, spatial_dimension, *shapesd_filtered, stress_vect, *sigma_dphi_dx); delete shapesd_filtered; /** * compute @f$\int \sigma * \frac{\partial \varphi}{\partial X}dX@f$ by @f$ \sum_q \mathbf{B}^t * \mathbf{\sigma}_q \overline w_q J_q@f$ */ Vector * int_sigma_dphi_dx = new Vector(nb_element, nb_nodes_per_element * spatial_dimension, "int_sigma_x_dphi_/_dX"); model->getFEM().integrate(*sigma_dphi_dx, *int_sigma_dphi_dx, size_of_shapes_derivatives, *it, ghost_type, &elem_filter); delete sigma_dphi_dx; /// assemble model->getFEM().assembleVector(*int_sigma_dphi_dx, residual, model->getDOFSynchronizer().getLocalDOFEquationNumbers(), residual.getNbComponent(), *it, ghost_type, &elem_filter, -1); delete int_sigma_dphi_dx; } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the stress from the strain * * @param[in] current_position nodes postition + displacements * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void Material::computeStress(Vector & displacement, GhostType ghost_type) { AKANTU_DEBUG_IN(); + resizeInternalVector(stress); + resizeInternalVector(strain); + UInt spatial_dimension = model->getSpatialDimension(); Mesh::type_iterator it = model->getFEM().getMesh().firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = model->getFEM().getMesh().lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { Vector & elem_filter = element_filter(*it, ghost_type); Vector & strain_vect = strain(*it, ghost_type); UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(*it, ghost_type); UInt nb_element = elem_filter.getSize(); strain_vect.resize(nb_quadrature_points * nb_element); /// compute @f$\nabla u@f$ model->getFEM().gradientOnQuadraturePoints(displacement, strain_vect, spatial_dimension, *it, ghost_type, &elem_filter); /// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$ computeStress(*it, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the stiffness matrix by assembling @f$\int_{\omega} B^t \times D * \times B d\omega @f$ * * @param[in] current_position nodes postition + displacements * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void Material::assembleStiffnessMatrix(Vector & current_position, GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); Mesh & mesh = model->getFEM().getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { switch(spatial_dimension) { case 1: { assembleStiffnessMatrix<1>(current_position, *it, ghost_type); break; } case 2: { assembleStiffnessMatrix<2>(current_position, *it, ghost_type); break; } case 3: { assembleStiffnessMatrix<3>(current_position, *it, ghost_type); break; } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::assembleStiffnessMatrix(Vector & current_position, const ElementType & type, GhostType ghost_type) { AKANTU_DEBUG_IN(); SparseMatrix & K = const_cast(model->getStiffnessMatrix()); const Vector & shapes_derivatives = model->getFEM().getShapesDerivatives(type,ghost_type); Vector & elem_filter = element_filter(type, ghost_type); Vector & strain_vect = strain(type, ghost_type); UInt * elem_filter_val = elem_filter.storage(); UInt nb_element = elem_filter.getSize(); UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(type, ghost_type); strain_vect.resize(nb_quadrature_points * nb_element); model->getFEM().gradientOnQuadraturePoints(current_position, strain_vect, dim, type, ghost_type, &elem_filter); UInt tangent_size = getTangentStiffnessVoigtSize(dim); Vector * tangent_stiffness_matrix = new Vector(nb_element*nb_quadrature_points, tangent_size * tangent_size, "tangent_stiffness_matrix"); computeTangentStiffness(type, *tangent_stiffness_matrix, ghost_type); /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ UInt bt_d_b_size = dim * nb_nodes_per_element; Vector * bt_d_b = new Vector(nb_element * nb_quadrature_points, bt_d_b_size * bt_d_b_size, "B^t*D*B"); UInt size_of_b = tangent_size * bt_d_b_size; Real * B = new Real[size_of_b]; Real * Bt_D = new Real[size_of_b]; Real * Bt_D_B = bt_d_b->storage(); Real * D = tangent_stiffness_matrix->storage(); UInt offset_bt_d_b = bt_d_b_size * bt_d_b_size; UInt offset_d = tangent_size * tangent_size; for (UInt e = 0; e < nb_element; ++e) { Real * shapes_derivatives_val = shapes_derivatives.values + elem_filter_val[e]*size_of_shapes_derivatives*nb_quadrature_points; for (UInt q = 0; q < nb_quadrature_points; ++q) { transferBMatrixToSymVoigtBMatrix(shapes_derivatives_val, B, nb_nodes_per_element); Math::matrixt_matrix(bt_d_b_size, tangent_size, tangent_size, B, D, Bt_D); Math::matrix_matrix(bt_d_b_size, bt_d_b_size, tangent_size, Bt_D, B, Bt_D_B); shapes_derivatives_val += size_of_shapes_derivatives; D += offset_d; Bt_D_B += offset_bt_d_b; } } delete [] B; delete [] Bt_D; delete tangent_stiffness_matrix; /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ Vector * K_e = new Vector(nb_element, bt_d_b_size * bt_d_b_size, "K_e"); model->getFEM().integrate(*bt_d_b, *K_e, bt_d_b_size * bt_d_b_size, type, ghost_type, &elem_filter); delete bt_d_b; model->getFEM().assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, &elem_filter); delete K_e; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::computePotentialEnergy(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); if(ghost_type != _not_ghost) return; Real * epot = potential_energy(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; computePotentialEnergy(strain_val, stress_val, epot); epot++; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::computePotentialEnergyByElement() { AKANTU_DEBUG_IN(); Mesh & mesh = model->getFEM().getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension); for(; it != last_type; ++it) { if(!potential_energy.exists(*it, _not_ghost)) { UInt nb_element = element_filter(*it, _not_ghost).getSize(); UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(*it, _not_ghost); potential_energy.alloc(nb_element * nb_quadrature_points, 1, *it, _not_ghost); } computePotentialEnergy(*it); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Real Material::getPotentialEnergy() { AKANTU_DEBUG_IN(); Real epot = 0.; computePotentialEnergyByElement(); /// integrate the potential energy for each type of elements Mesh & mesh = model->getFEM().getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension); for(; it != last_type; ++it) { epot += model->getFEM().integrate(potential_energy(*it, _not_ghost), *it, _not_ghost, &element_filter(*it, _not_ghost)); } AKANTU_DEBUG_OUT(); return epot; } /* -------------------------------------------------------------------------- */ void Material::computeQuadraturePointsCoordinates(ByElementTypeReal & quadrature_points_coordinates) const { AKANTU_DEBUG_IN(); const Mesh & mesh = model->getFEM().getMesh(); mesh.initByElementTypeVector(quadrature_points_coordinates, spatial_dimension, 0); Vector nodes_coordinates(mesh.getNodes(), true); nodes_coordinates += model->getDisplacement(); for(UInt gt = (UInt) _not_ghost; gt < (UInt) _casper; ++gt) { GhostType ghost_type = (GhostType) gt; Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { const Vector & elem_filter = element_filter(*it, ghost_type); UInt nb_element = elem_filter.getSize(); UInt nb_tot_quad = model->getFEM().getNbQuadraturePoints(*it, ghost_type) * nb_element; Vector & quads = quadrature_points_coordinates(*it, ghost_type); quads.resize(nb_tot_quad); model->getFEM().interpolateOnQuadraturePoints(nodes_coordinates, quads, spatial_dimension, *it, ghost_type, &elem_filter); } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material [" << std::endl; stream << space << " + id : " << id << std::endl; stream << space << " + name : " << name << std::endl; stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ template void Material::initInternalVector(ByElementTypeVector & vect, UInt nb_component, ElementKind element_kind) const; template void Material::initInternalVector(ByElementTypeVector & vect, UInt nb_component, ElementKind element_kind) const; template void Material::initInternalVector(ByElementTypeVector & vect, UInt nb_component, ElementKind element_kind) const; template void Material::resizeInternalVector(ByElementTypeVector & vect, ElementKind element_kind) const; template void Material::resizeInternalVector(ByElementTypeVector & vect, ElementKind element_kind) const; template void Material::resizeInternalVector(ByElementTypeVector & vect, ElementKind element_kind) const; __END_AKANTU__ diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh index 6b5d2d2e0..816378f89 100644 --- a/src/model/solid_mechanics/material.hh +++ b/src/model/solid_mechanics/material.hh @@ -1,425 +1,432 @@ /** * @file material.hh * @author Nicolas Richart * @date Fri Jul 23 09:06:29 2010 * * @brief Mother class for all materials * * @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_common.hh" #include "aka_memory.hh" //#include "fem.hh" //#include "mesh.hh" #include "data_accessor.hh" //#include "static_communicator.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_HH__ #define __AKANTU_MATERIAL_HH__ /* -------------------------------------------------------------------------- */ namespace akantu { class Model; class SolidMechanicsModel; class CommunicationBuffer; } __BEGIN_AKANTU__ /** * Interface of all materials * Prerequisites for a new material * - inherit from this class * - implement the following methods: * \code * virtual Real getStableTimeStep(Real h, const Element & element = ElementNull); * * virtual void computeStress(ElementType el_type, * GhostType ghost_type = _not_ghost); * * virtual void computeTangentStiffness(const ElementType & el_type, * Vector & tangent_matrix, * GhostType ghost_type = _not_ghost); * \endcode * */ class Material : protected Memory, public DataAccessor { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - Material(Model & model, const ID & id = ""); + Material(SolidMechanicsModel & model, const ID & id = ""); virtual ~Material(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// read properties virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// initialize the material computed parameter virtual void initMaterial(); /// compute the residual for this material virtual void updateResidual(Vector & displacement, GhostType ghost_type = _not_ghost); void assembleResidual(GhostType ghost_type); /// compute the residual for this material virtual void computeStress(Vector & current_position, GhostType ghost_type = _not_ghost); /// compute the stiffness matrix void assembleStiffnessMatrix(Vector & current_position, GhostType ghost_type); /// compute the stable time step for an element of size h virtual Real getStableTimeStep(Real h, const Element & element = ElementNull) = 0; /// compute the p-wave speed in the material virtual Real getPushWaveSpeed() { AKANTU_DEBUG_TO_IMPLEMENT(); }; /// compute the s-wave speed in the material virtual Real getShearWaveSpeed() { AKANTU_DEBUG_TO_IMPLEMENT(); }; /// add an element to the local mesh filter inline UInt addElement(const ElementType & type, UInt element, const GhostType & ghost_type); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost) = 0; // /// constitutive law // virtual void computeNonLocalStress(ElementType el_type, // GhostType ghost_type = _not_ghost) { // AKANTU_DEBUG_TO_IMPLEMENT(); // }; /// compute the tangent stiffness matrix virtual void computeTangentStiffness(const ElementType & el_type, Vector & tangent_matrix, GhostType ghost_type = _not_ghost) = 0; /// compute the potential energy virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost); template void assembleStiffnessMatrix(Vector & current_position, const ElementType & type, GhostType ghost_type); /// transfer the B matrix to a Voigt notation B matrix template inline void transferBMatrixToSymVoigtBMatrix(Real * B, Real * Bvoigt, UInt nb_nodes_per_element) const; inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const; /// compute the potential energy by element void computePotentialEnergyByElement(); void computeQuadraturePointsCoordinates(ByElementTypeReal & quadrature_points_coordinates) const; /* ------------------------------------------------------------------------ */ /* Function for all materials */ /* ------------------------------------------------------------------------ */ protected: /// compute the potential energy for on element inline void computePotentialEnergy(Real * F, Real * sigma, Real * epot); public: /// allocate an internal vector template void initInternalVector(ByElementTypeVector & vect, UInt nb_component, ElementKind element_kind = _ek_regular) const; /// resize an internal vector template void resizeInternalVector(ByElementTypeVector & vect, ElementKind element_kind = _ek_regular) const; /* ------------------------------------------------------------------------ */ /* DataAccessor inherited members */ /* ------------------------------------------------------------------------ */ public: virtual inline UInt getNbDataToPack(__attribute__((unused)) const Element & element, __attribute__((unused)) SynchronizationTag tag) const { return 0; } virtual inline UInt getNbDataToUnpack(__attribute__((unused)) const Element & element, __attribute__((unused)) SynchronizationTag tag) const { return 0; } virtual UInt getNbDataToPack(__attribute__((unused)) SynchronizationTag tag) const { return 0; } virtual UInt getNbDataToUnpack(__attribute__((unused)) SynchronizationTag tag) const { return 0; } virtual inline void packData(__attribute__((unused)) CommunicationBuffer & buffer, __attribute__((unused)) const Element & element, __attribute__((unused)) SynchronizationTag tag) const { } virtual void packData(__attribute__((unused)) CommunicationBuffer & buffer, __attribute__((unused)) const UInt index, - __attribute__((unused)) SynchronizationTag tag) const { + __attribute__((unused)) SynchronizationTag tag) const { } virtual inline void unpackData(__attribute__((unused)) CommunicationBuffer & buffer, __attribute__((unused)) const Element & element, __attribute__((unused)) SynchronizationTag tag) { } virtual void unpackData(__attribute__((unused)) CommunicationBuffer & buffer, __attribute__((unused)) const UInt index, __attribute__((unused)) SynchronizationTag tag) { } /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO(Model, *model, const SolidMechanicsModel &) AKANTU_GET_MACRO(ID, id, const ID &); AKANTU_GET_MACRO(Rho, rho, Real); AKANTU_SET_MACRO(Rho, rho, Real); Real getPotentialEnergy(); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Strain, strain, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy, Real); +protected: + + bool isInit() const { return is_init; } + /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// id of the material ID id; - /// spatial dimension - UInt spatial_dimension; - /// material name std::string name; /// The model to witch the material belong SolidMechanicsModel * model; /// density : rho Real rho; /// stresses arrays ordered by element types ByElementTypeReal stress; /// strains arrays ordered by element types ByElementTypeReal strain; /// list of element handled by the material ByElementTypeUInt element_filter; /// is the vector for potential energy initialized // bool potential_energy_vector; /// potential energy by element ByElementTypeReal potential_energy; - /// boolean to know if the material has been initialized - bool is_init; - /// tell if using in non local mode or not bool is_non_local; + /// spatial dimension + UInt spatial_dimension; + +private: + /// boolean to know if the material has been initialized + bool is_init; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #if defined (AKANTU_INCLUDE_INLINE_IMPL) # include "material_inline_impl.cc" #endif /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const Material & _this) { _this.printself(stream); return stream; } __END_AKANTU__ /* -------------------------------------------------------------------------- */ /* Auto loop */ /* -------------------------------------------------------------------------- */ -#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN \ - UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(el_type, ghost_type); \ - UInt size_strain = spatial_dimension * spatial_dimension; \ - \ - UInt nb_element = element_filter(el_type, ghost_type).getSize(); \ - if (nb_element == 0) return; \ +#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN \ + UInt nb_quadrature_points = this->model->getFEM().getNbQuadraturePoints(el_type, ghost_type); \ + UInt size_strain = spatial_dimension * spatial_dimension; \ \ - Vector & stress_tmp = stress(el_type, ghost_type); \ - stress_tmp.resize(nb_element*nb_quadrature_points); \ - Vector & strain_tmp = strain(el_type, ghost_type); \ - \ - Real * strain_val = strain_tmp.storage(); \ - Real * stress_val = stress_tmp.storage(); \ - \ - for (UInt el = 0; el < nb_element; ++el) { \ - for (UInt q = 0; q < nb_quadrature_points; ++q) { \ - - -#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \ - strain_val += size_strain; \ - stress_val += size_strain; \ - } \ - } \ - - -#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent) \ - UInt nb_quadrature_points = \ - model->getFEM().getNbQuadraturePoints(el_type, ghost_type); \ - UInt size_strain = spatial_dimension * spatial_dimension; \ + UInt nb_element = this->element_filter(el_type, ghost_type).getSize(); \ + if (nb_element == 0) return; \ \ - UInt nb_element = element_filter(el_type, ghost_type).getSize(); \ - if (nb_element == 0) return; \ + Vector & stress_tmp = this->stress(el_type, ghost_type); \ + stress_tmp.resize(nb_element*nb_quadrature_points); \ + Vector & strain_tmp = this->strain(el_type, ghost_type); \ \ - Vector & strain_tmp = strain(el_type, ghost_type); \ - \ - Real * strain_val = strain_tmp.storage(); \ + Real * strain_val = strain_tmp.storage(); \ + Real * stress_val = stress_tmp.storage(); \ \ - Real * tangent_val = tangent.values; \ - UInt size_tangent = getTangentStiffnessVoigtSize(spatial_dimension); \ - size_tangent *= size_tangent; \ - \ - \ - for (UInt el = 0; el < nb_element; ++el) { \ - for (UInt q = 0; q < nb_quadrature_points; ++q) { \ + for (UInt el = 0; el < nb_element; ++el) { \ + for (UInt q = 0; q < nb_quadrature_points; ++q) { \ + + +#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \ + strain_val += size_strain; \ + stress_val += size_strain; \ + } \ + } \ + + +#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent) \ + UInt nb_quadrature_points = \ + this->model->getFEM().getNbQuadraturePoints(el_type, ghost_type); \ + UInt size_strain = spatial_dimension * spatial_dimension; \ + \ + UInt nb_element = this->element_filter(el_type, ghost_type).getSize(); \ + if (nb_element == 0) return; \ + \ + Vector & strain_tmp = this->strain(el_type, ghost_type); \ + \ + Real * strain_val = strain_tmp.storage(); \ + \ + Real * tangent_val = tangent.values; \ + UInt size_tangent = this->getTangentStiffnessVoigtSize(spatial_dimension); \ + size_tangent *= size_tangent; \ + \ + for (UInt el = 0; el < nb_element; ++el) { \ + for (UInt q = 0; q < nb_quadrature_points; ++q) { \ // Vector * stress_tmp = stress(el_type, ghost_type); // stress_tmp->resize(nb_element*nb_quadrature_points); // Real * stress_val = stress_tmp->values; -#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \ - strain_val += size_strain; \ - tangent_val += size_tangent; \ - } \ - } \ - +#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \ + strain_val += size_strain; \ + tangent_val += size_tangent; \ + } \ + } /* -------------------------------------------------------------------------- */ /* Material list */ /* -------------------------------------------------------------------------- */ #define AKANTU_MATERIAL_LIST \ ((elastic , MaterialElastic )) \ ((elastic_orthotropic , MaterialElasticOrthotropic )) \ ((viscoelastic , MaterialViscoElastic )) \ ((elastic_caughey , MaterialElasticCaughey )) \ ((neohookean , MaterialNeohookean )) \ ((damage_linear , MaterialDamageLinear )) \ ((marigo , MaterialMarigo )) \ ((mazars , MaterialMazars )) \ ((vreepeerlings , MaterialVreePeerlings )) \ ((marigo_non_local , MaterialMarigoNonLocal )) \ ((mazars_non_local , MaterialMazarsNonLocal )) \ ((vreepeerlings_non_local, MaterialVreePeerlingsNonLocal)) \ ((cohesive_bilinear , MaterialCohesiveBilinear )) \ ((cohesive_linear , MaterialCohesiveLinear )) \ ((cohesive_linear_extrinsic, MaterialCohesiveLinearExtrinsic )) \ ((cohesive_linear_exponential_extrinsic, MaterialCohesiveLinearExponentialExtrinsic )) +#define INSTANSIATE_MATERIAL(mat_name) \ + template class mat_name<1>; \ + template class mat_name<2>; \ + template class mat_name<3>; + #if defined(__INTEL_COMPILER) #pragma warning ( push ) /* warning #654: overloaded virtual function "akantu::Material::computeStress" is only partially overridden in class "akantu::Material*" */ #pragma warning ( disable : 654 ) #endif //defined(__INTEL_COMPILER) /* -------------------------------------------------------------------------- */ // elastic materials #include "material_elastic.hh" #include "material_elastic_caughey.hh" #include "material_viscoelastic.hh" #include "material_neohookean.hh" #include "material_elastic_orthotropic.hh" // damage materials #include "material_damage.hh" #include "material_marigo.hh" #include "material_mazars.hh" #include "material_damage_linear.hh" #include "material_vreepeerlings.hh" #include "material_marigo_non_local.hh" #include "material_mazars_non_local.hh" #include "material_vreepeerlings_non_local.hh" // cohesive materials #include "material_cohesive.hh" #include "material_cohesive_linear.hh" #include "material_cohesive_bilinear.hh" #include "material_cohesive_linear_extrinsic.hh" #include "material_cohesive_linear_exponential_extrinsic.hh" #if defined(__INTEL_COMPILER) #pragma warning ( pop ) #endif //defined(__INTEL_COMPILER) #endif /* __AKANTU_MATERIAL_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc index a217191e6..12dd847cd 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc @@ -1,128 +1,139 @@ /** * @file material_cohesive_bilinear.cc * @author Marco Vocialta * @date Thu Feb 16 16:44:28 2012 * * @brief Bilinear cohesive constitutive law * * @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 "material_cohesive_bilinear.hh" #include "solid_mechanics_model_cohesive.hh" #include "sparse_matrix.hh" #include "dof_synchronizer.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialCohesiveBilinear::MaterialCohesiveBilinear(Model & model, const ID & id) : - MaterialCohesiveLinear(model,id) { +template +MaterialCohesiveBilinear::MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id) : + MaterialCohesiveLinear(model,id) { AKANTU_DEBUG_IN(); delta_0 = 0; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -MaterialCohesiveBilinear::~MaterialCohesiveBilinear() { +template +MaterialCohesiveBilinear::~MaterialCohesiveBilinear() { AKANTU_DEBUG_IN(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveBilinear::initMaterial() { +template +void MaterialCohesiveBilinear::initMaterial() { AKANTU_DEBUG_IN(); - MaterialCohesiveLinear::initMaterial(); + MaterialCohesiveLinear::initMaterial(); /** * Recompute sigma_c as * @f$ {\sigma_c}_\textup{new} = * \frac{{\sigma_c}_\textup{old} \delta_c} {\delta_c - \delta_0} @f$ */ - AKANTU_DEBUG_ASSERT(delta_c != delta_0, "Check your material.dat"); + AKANTU_DEBUG_ASSERT(this->delta_c != delta_0, "Check your material.dat"); - sigma_c *= delta_c / (delta_c - delta_0); + this->sigma_c *= this->delta_c / (this->delta_c - delta_0); updateDeltaMax(_ghost); updateDeltaMax(_not_ghost); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveBilinear::resizeCohesiveVectors() { - MaterialCohesiveLinear::resizeCohesiveVectors(); +template +void MaterialCohesiveBilinear::resizeCohesiveVectors() { + MaterialCohesiveLinear::resizeCohesiveVectors(); updateDeltaMax(_ghost); updateDeltaMax(_not_ghost); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveBilinear::updateDeltaMax(GhostType ghost_type) { +template +void MaterialCohesiveBilinear::updateDeltaMax(GhostType ghost_type) { AKANTU_DEBUG_IN(); - const Mesh & mesh = model->getFEM("CohesiveFEM").getMesh(); + const Mesh & mesh = this->model->getFEM("CohesiveFEM").getMesh(); + Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive); for(; it != last_type; ++it) { Vector::iteratordelta_max_it = - delta_max(*it, ghost_type).begin(); + this->delta_max(*it, ghost_type).begin(); Vector::iteratordelta_max_end = - delta_max(*it, ghost_type).end(); + this->delta_max(*it, ghost_type).end(); for (; delta_max_it != delta_max_end; ++delta_max_it) { *delta_max_it = delta_0; } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialCohesiveBilinear::setParam(const std::string & key, +template +bool MaterialCohesiveBilinear::setParam(const std::string & key, const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "delta_0") { sstr >> delta_0; } - else { return MaterialCohesiveLinear::setParam(key, value, id); } + else { return MaterialCohesiveLinear::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveBilinear::printself(std::ostream & stream, int indent) const { +template +void MaterialCohesiveBilinear::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_cohesive_bilinear> [" << std::endl; stream << space << " + delta_0 : " << delta_0 << std::endl; - MaterialCohesiveLinear::printself(stream, indent + 1); + MaterialCohesiveLinear::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialCohesiveBilinear); + + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh index 985bfa50c..84b6526ca 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh @@ -1,109 +1,102 @@ /** * @file material_cohesive_bilinear.hh * @author Marco Vocialta * @date Thu Feb 16 14:14:34 2012 * * @brief Bilinear cohesive constitutive law * * @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 . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__ #define __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__ /* -------------------------------------------------------------------------- */ #include "material_cohesive_linear.hh" #include "aka_common.hh" __BEGIN_AKANTU__ /** * Cohesive material bilinear * * parameters in the material files : * - delta_0 : elastic limit displacement (default: 0) */ - -class MaterialCohesiveBilinear : public MaterialCohesiveLinear { +template +class MaterialCohesiveBilinear : public MaterialCohesiveLinear { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialCohesiveBilinear(Model & model, const ID & id = ""); + MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialCohesiveBilinear(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// set patameters virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; /// initialize the material computed parameter virtual void initMaterial(); /// update delta_max values with delta_0 virtual void updateDeltaMax(GhostType ghost_type); /// resize vectors for new cohesive elements virtual void resizeCohesiveVectors(); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// elastic limit displacement Real delta_0; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_cohesive_elastic_inline_impl.cc" -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialCohesiveBilinear & _this) -{ - _this.printself(stream); - return stream; -} - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_COHESIVE_ELASTIC_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc index c13392d79..8c5ce353c 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc @@ -1,195 +1,203 @@ /** * @file material_cohesive_linear.cc * @author Marco Vocialta * @date Mon Feb 20 12:14:16 2012 * * @brief Linear irreversible cohesive law of mixed mode loading * * @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 "material_cohesive_linear.hh" #include "solid_mechanics_model.hh" #include "sparse_matrix.hh" #include "dof_synchronizer.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialCohesiveLinear::MaterialCohesiveLinear(Model & model, const ID & id) : +template +MaterialCohesiveLinear::MaterialCohesiveLinear(SolidMechanicsModel & model, + const ID & id) : MaterialCohesive(model,id), delta_max("delta max",id) { AKANTU_DEBUG_IN(); beta = 0; G_cI = 0; G_cII = 0; initInternalVector(delta_max, 1, _ek_cohesive); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -MaterialCohesiveLinear::~MaterialCohesiveLinear() { +template +MaterialCohesiveLinear::~MaterialCohesiveLinear() { AKANTU_DEBUG_IN(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinear::initMaterial() { +template +void MaterialCohesiveLinear::initMaterial() { AKANTU_DEBUG_IN(); MaterialCohesive::initMaterial(); kappa = G_cII / G_cI; delta_c = 2 * G_cI / sigma_c; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinear::resizeCohesiveVectors() { +template +void MaterialCohesiveLinear::resizeCohesiveVectors() { MaterialCohesive::resizeCohesiveVectors(); resizeInternalVector(delta_max, _ek_cohesive); } /* -------------------------------------------------------------------------- */ -bool MaterialCohesiveLinear::setParam(const std::string & key, - const std::string & value, - const ID & id) { +template +bool MaterialCohesiveLinear::setParam(const std::string & key, + const std::string & value, + const ID & id) { std::stringstream sstr(value); if(key == "sigma_c") { sstr >> sigma_c; } else if(key == "beta") { sstr >> beta; } else if(key == "G_cI") { sstr >> G_cI; } else if(key == "G_cII") { sstr >> G_cII; } else { return Material::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinear::computeTraction(const Vector & normal, - ElementType el_type, - GhostType ghost_type) { +template +void MaterialCohesiveLinear::computeTraction(const Vector & normal, + ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); /// define iterators Vector::iterator traction_it = tractions(el_type, ghost_type).begin(spatial_dimension); Vector::iterator opening_it = opening(el_type, ghost_type).begin(spatial_dimension); Vector::const_iterator normal_it = normal.begin(spatial_dimension); Vector::iteratortraction_end = tractions(el_type, ghost_type).end(spatial_dimension); Vector::iteratordelta_max_it = delta_max(el_type, ghost_type).begin(); /// compute scalars Real beta2_kappa2 = beta*beta/kappa/kappa; Real beta2_kappa = beta*beta/kappa; /// loop on each quadrature point for (; traction_it != traction_end; ++traction_it, ++opening_it, ++normal_it, ++delta_max_it) { /// compute normal and tangential opening vectors Real normal_opening_norm = opening_it->dot(*normal_it); types::Vector normal_opening(spatial_dimension); normal_opening = (*normal_it); normal_opening *= normal_opening_norm; types::Vector tangential_opening(spatial_dimension); tangential_opening = *opening_it; tangential_opening -= normal_opening; Real tangential_opening_norm = tangential_opening.norm(); /** * compute effective opening displacement * @f$ \delta = \sqrt{ * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$ */ Real delta = tangential_opening_norm; delta *= delta * beta2_kappa2; delta += normal_opening_norm * normal_opening_norm; delta = sqrt(delta); /// full damage case if (delta >= delta_c || delta == 0) { - /// set traction to zero (*traction_it).clear(); - } /// element not fully damaged else { - /** * Compute traction @f$ \mathbf{T} = \left( * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1- * \frac{\delta}{\delta_c} \right)@f$ */ *traction_it = tangential_opening; *traction_it *= beta2_kappa; *traction_it += normal_opening; /// update maximum displacement *delta_max_it = std::max(*delta_max_it, delta); Real k = sigma_c / *delta_max_it * (1. - *delta_max_it / delta_c); *traction_it *= k; } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinear::printself(std::ostream & stream, int indent) const { +template +void MaterialCohesiveLinear::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_cohesive_linear> [" << std::endl; stream << space << " + sigma_c : " << sigma_c << std::endl; stream << space << " + beta : " << beta << std::endl; stream << space << " + G_cI : " << G_cI << std::endl; stream << space << " + G_cII : " << G_cII << std::endl; - if(is_init) { + if(this->isInit()) { stream << space << " + kappa : " << kappa << std::endl; stream << space << " + delta_c : " << delta_c << std::endl; } MaterialCohesive::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialCohesiveLinear); + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh index 6db76e7ba..6b31cb24a 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh @@ -1,133 +1,126 @@ /** * @file material_cohesive_linear.hh * @author Marco Vocialta * @date Mon Feb 20 12:00:34 2012 * * @brief Linear irreversible cohesive law of mixed mode loading * * @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 "material_cohesive.hh" #include "aka_common.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__ #define __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__ /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /** * Cohesive material linear damage * * parameters in the material files : * - sigma_c : critical stress sigma_c (default: 0) * - beta : weighting parameter for sliding and normal opening (default: 0) * - G_cI : fracture energy for mode I (default: 0) * - G_cII : fracture energy for mode II (default: 0) */ - +template class MaterialCohesiveLinear : public MaterialCohesive { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - - MaterialCohesiveLinear(Model & model, const ID & id = ""); + + MaterialCohesiveLinear(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialCohesiveLinear(); - + /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// set patameters virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; /// initialize the material computed parameter virtual void initMaterial(); /// resize vectors for new cohesive elements virtual void resizeCohesiveVectors(); protected: /// constitutive law void computeTraction(const Vector & normal, ElementType el_type, GhostType ghost_type = _not_ghost); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: - + /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// beta parameter Real beta; /// mode I fracture energy Real G_cI; /// mode II fracture energy Real G_cII; /// kappa parameter Real kappa; /// maximum displacement ByElementTypeReal delta_max; /// critical displacement Real delta_c; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_cohesive_linear_inline_impl.cc" -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialCohesiveLinear & _this) -{ - _this.printself(stream); - return stream; -} - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.cc index 2eada6a4c..0d51d269a 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.cc +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.cc @@ -1,278 +1,287 @@ /** * @file material_cohesive_linear.cc * @author Marco Vocialta * @date Mon Feb 20 12:14:16 2012 * * @brief Linear irreversible cohesive law of mixed mode loading with * random stress definition for extrinsic type * * @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 "material_cohesive_linear_exponential_extrinsic.hh" #include "solid_mechanics_model_cohesive.hh" #include "sparse_matrix.hh" #include "dof_synchronizer.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialCohesiveLinearExponentialExtrinsic::MaterialCohesiveLinearExponentialExtrinsic(Model & model, const ID & id) : +template +MaterialCohesiveLinearExponentialExtrinsic::MaterialCohesiveLinearExponentialExtrinsic(SolidMechanicsModel & model, const ID & id) : MaterialCohesive(model,id), sigma_c_eff("sigma_c_eff",id), delta_max("delta max",id), sigma_actual("sigma actual",id) { AKANTU_DEBUG_IN(); sigma_max = 0; delta_0 = 0; beta = 0; G_cI = 0; G_cII = 0; initInternalVector(sigma_c_eff, 1, _ek_cohesive); initInternalVector(delta_max, 1, _ek_cohesive); initInternalVector(sigma_actual, 1, _ek_cohesive); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -MaterialCohesiveLinearExponentialExtrinsic::~MaterialCohesiveLinearExponentialExtrinsic() { +template +MaterialCohesiveLinearExponentialExtrinsic::~MaterialCohesiveLinearExponentialExtrinsic() { AKANTU_DEBUG_IN(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExponentialExtrinsic::initMaterial() { +template +void MaterialCohesiveLinearExponentialExtrinsic::initMaterial() { AKANTU_DEBUG_IN(); MaterialCohesive::initMaterial(); kappa = G_cII / G_cI; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExponentialExtrinsic::resizeCohesiveVectors() { +template +void MaterialCohesiveLinearExponentialExtrinsic::resizeCohesiveVectors() { MaterialCohesive::resizeCohesiveVectors(); resizeInternalVector(sigma_c_eff, _ek_cohesive); resizeInternalVector(delta_max, _ek_cohesive); resizeInternalVector(sigma_actual, _ek_cohesive); FEM & fem_cohesive = model->getFEM("CohesiveFEM"); const Mesh & mesh = fem_cohesive.getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive); for(; it != last_type; ++it) { const Vector & elem_filter = element_filter(*it, _not_ghost); UInt nb_element = elem_filter.getSize(); if (nb_element == 0) continue; UInt nb_quadrature_points = fem_cohesive.getNbQuadraturePoints(*it, _not_ghost); UInt nb_element_old = nb_element - sigma_insertion.getSize() / nb_quadrature_points; Vector & sigma_c_eff_vec = sigma_c_eff(*it, _not_ghost); Vector & sigma_actual_vec = sigma_actual(*it, _not_ghost); for (UInt el = nb_element_old; el < nb_element; ++el) { for (UInt q = 0; q < nb_quadrature_points; ++q) { Real new_sigma = sigma_insertion((el - nb_element_old)*nb_quadrature_points + q); sigma_c_eff_vec(el * nb_quadrature_points + q) = new_sigma; sigma_actual_vec(el * nb_quadrature_points + q) = new_sigma; } } } } /* -------------------------------------------------------------------------- */ -Real MaterialCohesiveLinearExponentialExtrinsic::computeEffectiveNorm(const types::Matrix & stress, const types::RVector & normal, const types::RVector & tangent) { +template +Real MaterialCohesiveLinearExponentialExtrinsic::computeEffectiveNorm(const types::Matrix & stress, const types::RVector & normal, const types::RVector & tangent) { AKANTU_DEBUG_IN(); Real normal_contrib, tangent_contrib; types::RVector normal_stress(spatial_dimension); types::RVector tangential_stress(spatial_dimension); normal_stress.mul(stress, normal); tangential_stress.mul(stress, tangent); normal_contrib = normal_stress.dot(normal); tangent_contrib = tangential_stress.dot(tangent); if (normal_contrib < 0) normal_contrib = 0; AKANTU_DEBUG_OUT(); if (beta == 0) return normal_contrib; else return std::sqrt(normal_contrib*normal_contrib + tangent_contrib*tangent_contrib/beta/beta); } /* -------------------------------------------------------------------------- */ -bool MaterialCohesiveLinearExponentialExtrinsic::setParam(const std::string & key, +template +bool MaterialCohesiveLinearExponentialExtrinsic::setParam(const std::string & key, const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "sigma_c") { sstr >> sigma_c; } else if(key == "beta") { sstr >> beta; } else if(key == "sigma_max") { sstr >> sigma_max; } else if(key == "delta_0") { sstr >> delta_0; } else if(key == "G_cI") { sstr >> G_cI; } else if(key == "G_cII") { sstr >> G_cII; } else if(key == "rand") { sstr >> rand; } else if(key == "gamma") { sstr >> gamma; } else if(key == "z_max") { sstr >> z_max; } else { return Material::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExponentialExtrinsic::computeTraction(const Vector & normal, +template +void MaterialCohesiveLinearExponentialExtrinsic::computeTraction(const Vector & normal, ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); /// define iterators Vector::iterator traction_it = tractions(el_type, ghost_type).begin(spatial_dimension); Vector::iterator opening_it = opening(el_type, ghost_type).begin(spatial_dimension); Vector::const_iterator normal_it = normal.begin(spatial_dimension); Vector::iteratortraction_end = tractions(el_type, ghost_type).end(spatial_dimension); Vector::iteratorsigma_c_it = sigma_c_eff(el_type, ghost_type).begin(); Vector::iteratordelta_max_it = delta_max(el_type, ghost_type).begin(); Vector::iteratorsigma_actual_it = sigma_actual(el_type, ghost_type).begin(); /// compute scalars Real beta2_kappa2 = beta*beta/kappa/kappa; Real beta2_kappa = beta*beta/kappa; /// loop on each quadrature point for (; traction_it != traction_end; ++traction_it, ++opening_it, ++normal_it, ++sigma_c_it, ++delta_max_it, ++sigma_actual_it) { /// compute normal and tangential opening vectors Real normal_opening_norm = opening_it->dot(*normal_it); types::Vector normal_opening(spatial_dimension); normal_opening = (*normal_it); normal_opening *= normal_opening_norm; types::Vector tangential_opening(spatial_dimension); tangential_opening = *opening_it; tangential_opening -= normal_opening; Real tangential_opening_norm = tangential_opening.norm(); /** * compute effective opening displacement * @f$ \delta = \sqrt{ * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$ */ Real delta = tangential_opening_norm; delta *= delta * beta2_kappa2; delta += normal_opening_norm * normal_opening_norm; delta = sqrt(delta); *traction_it = tangential_opening; *traction_it *= beta2_kappa; *traction_it += normal_opening; *traction_it /= delta; /// crack opening case if (delta == 0 || normal_opening_norm < 0) { (*traction_it).clear(); } else if (delta > *delta_max_it) { Real sigma; if (delta < delta_0) { sigma = *sigma_c_it + (sigma_max - *sigma_c_it) / delta_0 * delta; } else { Real z = -21.61440010 + 0.04166666667 * sqrt(2.69097e5 + 4.8e5 * delta); z = std::min(z, z_max); sigma = exp(-1*gamma*z) * (sigma_max - sigma_max / z_max * z); } *traction_it *= sigma; /// update maximum displacement and stress *delta_max_it = delta; *sigma_actual_it = sigma; } /// unloading-reloading case else { *traction_it *= *sigma_actual_it / *delta_max_it * delta; } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExponentialExtrinsic::printself(std::ostream & stream, int indent) const { +template +void MaterialCohesiveLinearExponentialExtrinsic::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_cohesive_linear> [" << std::endl; stream << space << " + sigma_c : " << sigma_c << std::endl; stream << space << " + beta : " << beta << std::endl; stream << space << " + G_cI : " << G_cI << std::endl; stream << space << " + G_cII : " << G_cII << std::endl; stream << space << " + rand : " << rand << std::endl; stream << space << " + gamma : " << gamma << std::endl; stream << space << " + delta_0 : " << delta_0 << std::endl; stream << space << " + z_max : " << z_max << std::endl; stream << space << " + sigma_max : " << sigma_max << std::endl; - if(is_init) { + if(this->isInit()) { stream << space << " + kappa : " << kappa << std::endl; } MaterialCohesive::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialCohesiveLinearExponentialExtrinsic); __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.hh index 2fc6a7ebb..fe95c989e 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.hh +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_exponential_extrinsic.hh @@ -1,158 +1,150 @@ /** * @file material_cohesive_linear.hh * @author Marco Vocialta * @date Mon Feb 20 12:00:34 2012 * * @brief Linear irreversible cohesive law of mixed mode loading with * random stress definition for extrinsic type * * @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 "material_cohesive.hh" #include "aka_common.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_EXPONENTIAL_EXTRINSIC_HH__ #define __AKANTU_MATERIAL_COHESIVE_LINEAR_EXPONENTIAL_EXTRINSIC_HH__ /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /** * Cohesive material linear damage for extrinsic case * * parameters in the material files : * - sigma_c : critical stress (default: 0) * - sigma_max : maximum stress (default: 0) * - delta_0 : delta 0 (default: 0) * - beta : weighting parameter for sliding and normal opening (default: 0) * - G_cI : fracture energy for mode I (default: 0) * - G_cII : fracture energy for mode II (default: 0) * - rand : randomness factor (default: 0) * - gamma : gamma factor (default: 0) * - z_max : z max (default: 0) */ - +template class MaterialCohesiveLinearExponentialExtrinsic : public MaterialCohesive { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialCohesiveLinearExponentialExtrinsic(Model & model, const ID & id = ""); + MaterialCohesiveLinearExponentialExtrinsic(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialCohesiveLinearExponentialExtrinsic(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// set patameters virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; /// initialize the material computed parameter virtual void initMaterial(); /// resize vectors for new cohesive elements virtual void resizeCohesiveVectors(); /// compute effective stress norm for insertion check virtual Real computeEffectiveNorm(const types::Matrix & stress, const types::RVector & normal, const types::RVector & tangent); protected: /// constitutive law void computeTraction(const Vector & normal, ElementType el_type, GhostType ghost_type = _not_ghost); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// maximum stress Real sigma_max; /// delta 0 Real delta_0; /// critical effective stress ByElementTypeReal sigma_c_eff; /// beta parameter Real beta; /// mode I fracture energy Real G_cI; /// mode II fracture energy Real G_cII; /// kappa parameter Real kappa; /// maximum displacement ByElementTypeReal delta_max; /// actual maximum sigma ByElementTypeReal sigma_actual; /// gamma factor Real gamma; /// z max Real z_max; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_cohesive_linear_inline_impl.cc" -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialCohesiveLinearExponentialExtrinsic & _this) -{ - _this.printself(stream); - return stream; -} - - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_EXPONENTIAL_EXTRINSIC_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.cc index 4d6c3edad..2598fc9db 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.cc +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.cc @@ -1,264 +1,276 @@ /** * @file material_cohesive_linear.cc * @author Marco Vocialta * @date Mon Feb 20 12:14:16 2012 * * @brief Linear irreversible cohesive law of mixed mode loading with * random stress definition for extrinsic type * * @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 "material_cohesive_linear_extrinsic.hh" #include "solid_mechanics_model_cohesive.hh" #include "sparse_matrix.hh" #include "dof_synchronizer.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialCohesiveLinearExtrinsic::MaterialCohesiveLinearExtrinsic(Model & model, const ID & id) : +template +MaterialCohesiveLinearExtrinsic::MaterialCohesiveLinearExtrinsic(SolidMechanicsModel & model, + const ID & id) : MaterialCohesive(model,id), sigma_c_eff("sigma_c_eff",id), delta_max("delta max",id), delta_c("delta_c",id) { AKANTU_DEBUG_IN(); sigma_c = 0; beta = 0; G_cI = 0; G_cII = 0; rand = 0; initInternalVector(sigma_c_eff, 1, _ek_cohesive); initInternalVector(delta_max, 1, _ek_cohesive); initInternalVector(delta_c, 1, _ek_cohesive); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -MaterialCohesiveLinearExtrinsic::~MaterialCohesiveLinearExtrinsic() { +template +MaterialCohesiveLinearExtrinsic::~MaterialCohesiveLinearExtrinsic() { AKANTU_DEBUG_IN(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExtrinsic::initMaterial() { +template +void MaterialCohesiveLinearExtrinsic::initMaterial() { AKANTU_DEBUG_IN(); MaterialCohesive::initMaterial(); kappa = G_cII / G_cI; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExtrinsic::resizeCohesiveVectors() { +template +void MaterialCohesiveLinearExtrinsic::resizeCohesiveVectors() { MaterialCohesive::resizeCohesiveVectors(); resizeInternalVector(sigma_c_eff, _ek_cohesive); resizeInternalVector(delta_max, _ek_cohesive); resizeInternalVector(delta_c, _ek_cohesive); FEM & fem_cohesive = model->getFEM("CohesiveFEM"); const Mesh & mesh = fem_cohesive.getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive); for(; it != last_type; ++it) { const Vector & elem_filter = element_filter(*it, _not_ghost); UInt nb_element = elem_filter.getSize(); if (nb_element == 0) continue; UInt nb_quadrature_points = fem_cohesive.getNbQuadraturePoints(*it, _not_ghost); UInt nb_element_old = nb_element - sigma_insertion.getSize() / nb_quadrature_points; Vector & sigma_c_eff_vec = sigma_c_eff(*it, _not_ghost); Vector & delta_c_vec = delta_c(*it, _not_ghost); for (UInt el = nb_element_old; el < nb_element; ++el) { for (UInt q = 0; q < nb_quadrature_points; ++q) { Real new_sigma = sigma_insertion((el - nb_element_old) * nb_quadrature_points+q); Real new_delta = 2 * G_cI / new_sigma; sigma_c_eff_vec(el * nb_quadrature_points + q) = new_sigma; delta_c_vec(el * nb_quadrature_points + q) = new_delta; } } } } /* -------------------------------------------------------------------------- */ -bool MaterialCohesiveLinearExtrinsic::setParam(const std::string & key, - const std::string & value, - const ID & id) { +template +bool MaterialCohesiveLinearExtrinsic::setParam(const std::string & key, + const std::string & value, + const ID & id) { std::stringstream sstr(value); if(key == "sigma_c") { sstr >> sigma_c; } else if(key == "beta") { sstr >> beta; } else if(key == "G_cI") { sstr >> G_cI; } else if(key == "G_cII") { sstr >> G_cII; } else if(key == "rand") { sstr >> rand; } else { return Material::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -Real MaterialCohesiveLinearExtrinsic::computeEffectiveNorm(const types::Matrix & stress, const types::RVector & normal, const types::RVector & tangent) { +template +Real MaterialCohesiveLinearExtrinsic::computeEffectiveNorm(const types::Matrix & stress, + const types::RVector & normal, + const types::RVector & tangent) { AKANTU_DEBUG_IN(); Real normal_contrib, tangent_contrib; types::RVector normal_stress(spatial_dimension); types::RVector tangential_stress(spatial_dimension); normal_stress.mul(stress, normal); tangential_stress.mul(stress, tangent); normal_contrib = normal_stress.dot(normal); tangent_contrib = tangential_stress.dot(tangent); if (normal_contrib < 0) normal_contrib = 0; AKANTU_DEBUG_OUT(); return std::sqrt(normal_contrib*normal_contrib + tangent_contrib*tangent_contrib/beta/beta); - } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExtrinsic::computeTraction(const Vector & normal, - ElementType el_type, - GhostType ghost_type) { +template +void MaterialCohesiveLinearExtrinsic::computeTraction(const Vector & normal, + ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); /// define iterators Vector::iterator traction_it = tractions(el_type, ghost_type).begin(spatial_dimension); Vector::iterator opening_it = opening(el_type, ghost_type).begin(spatial_dimension); Vector::const_iterator normal_it = normal.begin(spatial_dimension); Vector::iteratortraction_end = tractions(el_type, ghost_type).end(spatial_dimension); Vector::iteratorsigma_c_it = sigma_c_eff(el_type, ghost_type).begin(); Vector::iteratordelta_max_it = delta_max(el_type, ghost_type).begin(); Vector::iteratordelta_c_it = delta_c(el_type, ghost_type).begin(); /// compute scalars Real beta2_kappa2 = beta*beta/kappa/kappa; Real beta2_kappa = beta*beta/kappa; /// loop on each quadrature point for (; traction_it != traction_end; ++traction_it, ++opening_it, ++normal_it, ++sigma_c_it, ++delta_max_it, ++delta_c_it) { /// compute normal and tangential opening vectors Real normal_opening_norm = opening_it->dot(*normal_it); types::Vector normal_opening(spatial_dimension); normal_opening = (*normal_it); normal_opening *= normal_opening_norm; types::Vector tangential_opening(spatial_dimension); tangential_opening = *opening_it; tangential_opening -= normal_opening; Real tangential_opening_norm = tangential_opening.norm(); /** * compute effective opening displacement * @f$ \delta = \sqrt{ * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$ */ Real delta = tangential_opening_norm; delta *= delta * beta2_kappa2; delta += normal_opening_norm * normal_opening_norm; delta = sqrt(delta); /// full damage case if (delta >= *delta_c_it || delta == 0) { /// set traction to zero (*traction_it).clear(); } /// element not fully damaged else { /** * Compute traction @f$ \mathbf{T} = \left( * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1- * \frac{\delta}{\delta_c} \right)@f$ */ *traction_it = tangential_opening; *traction_it *= beta2_kappa; *traction_it += normal_opening; /// update maximum displacement *delta_max_it = std::max(*delta_max_it, delta); Real k = *sigma_c_it / *delta_max_it * (1. - *delta_max_it / *delta_c_it); *traction_it *= k; } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialCohesiveLinearExtrinsic::printself(std::ostream & stream, int indent) const { +template +void MaterialCohesiveLinearExtrinsic::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_cohesive_linear> [" << std::endl; stream << space << " + sigma_c : " << sigma_c << std::endl; stream << space << " + beta : " << beta << std::endl; stream << space << " + G_cI : " << G_cI << std::endl; stream << space << " + G_cII : " << G_cII << std::endl; stream << space << " + rand : " << rand << std::endl; - if(is_init) { + if(this->isInit()) { stream << space << " + kappa : " << kappa << std::endl; } MaterialCohesive::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialCohesiveLinearExtrinsic); __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.hh index 413a3de84..5b9480d04 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.hh +++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_extrinsic.hh @@ -1,142 +1,134 @@ /** * @file material_cohesive_linear.hh * @author Marco Vocialta * @date Mon Feb 20 12:00:34 2012 * * @brief Linear irreversible cohesive law of mixed mode loading with * random stress definition for extrinsic type * * @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 "material_cohesive.hh" #include "aka_common.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_EXTRINSIC_HH__ #define __AKANTU_MATERIAL_COHESIVE_LINEAR_EXTRINSIC_HH__ /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /** * Cohesive material linear damage for extrinsic case * * parameters in the material files : * - sigma_c : critical stress sigma_c (default: 0) * - beta : weighting parameter for sliding and normal opening (default: 0) * - G_cI : fracture energy for mode I (default: 0) * - G_cII : fracture energy for mode II (default: 0) * - rand : randomness factor (default: 0) */ - +template class MaterialCohesiveLinearExtrinsic : public MaterialCohesive { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialCohesiveLinearExtrinsic(Model & model, const ID & id = ""); + MaterialCohesiveLinearExtrinsic(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialCohesiveLinearExtrinsic(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// set patameters virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; /// initialize the material computed parameter virtual void initMaterial(); /// resize vectors for new cohesive elements virtual void resizeCohesiveVectors(); /// compute effective stress norm for insertion check virtual Real computeEffectiveNorm(const types::Matrix & stress, const types::RVector & normal, const types::RVector & tangent); protected: /// constitutive law void computeTraction(const Vector & normal, ElementType el_type, GhostType ghost_type = _not_ghost); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// critical effective stress ByElementTypeReal sigma_c_eff; /// beta parameter Real beta; /// mode I fracture energy Real G_cI; /// mode II fracture energy Real G_cII; /// kappa parameter Real kappa; /// maximum displacement ByElementTypeReal delta_max; /// critical displacement ByElementTypeReal delta_c; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_cohesive_linear_inline_impl.cc" -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialCohesiveLinearExtrinsic & _this) -{ - _this.printself(stream); - return stream; -} - - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_EXTRINSIC_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc index b6257410f..aea1b39df 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc +++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc @@ -1,562 +1,562 @@ /** * @file material_cohesive.cc * @author Marco Vocialta * @date Tue Feb 7 18:24:52 2012 * * @brief Specialization of the material class for cohesive elements * * @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 "material_cohesive.hh" #include "solid_mechanics_model_cohesive.hh" #include "sparse_matrix.hh" #include "dof_synchronizer.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialCohesive::MaterialCohesive(Model & model, const ID & id) : +MaterialCohesive::MaterialCohesive(SolidMechanicsModel & model, const ID & id) : Material(model,id), reversible_energy("reversible_energy", id), total_energy("total_energy", id), tractions_old("tractions (old)",id), opening_old("opening (old)",id), tractions("tractions",id), opening("opening",id) { AKANTU_DEBUG_IN(); this->model = dynamic_cast(&model); initInternalVector(reversible_energy, 1, _ek_cohesive); initInternalVector(total_energy, 1, _ek_cohesive); initInternalVector(tractions_old, spatial_dimension, _ek_cohesive); initInternalVector(tractions, spatial_dimension, _ek_cohesive); initInternalVector(opening_old, spatial_dimension, _ek_cohesive); initInternalVector(opening, spatial_dimension, _ek_cohesive); sigma_c = 0; rand = 0; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ MaterialCohesive::~MaterialCohesive() { AKANTU_DEBUG_IN(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ bool MaterialCohesive::setParam(const std::string & key, const std::string & value, const ID & id) { return Material::setParam(key,value,id); } /* -------------------------------------------------------------------------- */ void MaterialCohesive::initMaterial() { AKANTU_DEBUG_IN(); Material::initMaterial(); fem_cohesive = &(model->getFEMClass("CohesiveFEM")); Mesh & mesh = fem_cohesive->getMesh(); for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt, _ek_cohesive); for(; it != last_type; ++it) { ElementType type = *it; element_filter.alloc(0, 1, type); } } resizeCohesiveVectors(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void MaterialCohesive::resizeCohesiveVectors() { resizeInternalVector(reversible_energy, _ek_cohesive); resizeInternalVector(total_energy, _ek_cohesive); resizeInternalVector(tractions_old, _ek_cohesive); resizeInternalVector(tractions, _ek_cohesive); resizeInternalVector(opening_old, _ek_cohesive); resizeInternalVector(opening, _ek_cohesive); } /* -------------------------------------------------------------------------- */ void MaterialCohesive::checkInsertion(Vector & facet_insertion) { AKANTU_DEBUG_IN(); sigma_insertion.resize(0); const Mesh & mesh_facets = model->getMeshFacets(); const Mesh & mesh = model->getFEM("CohesiveFEM").getMesh(); ElementType type_facet = model->getFacetType(); const Vector & conn_facet = mesh_facets.getConnectivity(type_facet); Vector & facets_check = model->getFacetsCheck(); UInt nb_facet = facets_check.getSize(); UInt nb_quad_facet = model->getFEM("FacetsFEM").getNbQuadraturePoints(type_facet); const Vector & normals = model->getFEM("FacetsFEM").getNormalsOnQuadPoints(type_facet); const Vector > & element_to_facet = mesh_facets.getElementToSubelement(type_facet); types::RVector stresses(spatial_dimension); types::RVector stress_check(nb_quad_facet); Real coords[3]; coords[0] = -1./6. * 2.; coords[1] = (1./3. - 1./std::sqrt(3)) * 2.; coords[2] = (1./3. + 1./std::sqrt(3)) * 2.; Vector natural_coords(nb_quad_facet*spatial_dimension); const Vector & tangents = model->getTangents(); types::Matrix shapes(nb_quad_facet, 3); shapes.clear(); shapes += 1.; for (UInt f = 0; f < nb_facet; ++f) { if (facets_check(f) == true) { stress_check.clear(); for (UInt el = 0; el < 2; ++el) { UInt elem_nb = element_to_facet(f)(el).element; ElementType type_elem = element_to_facet(f)(el).type; UInt nb_quad_elem = model->getFEM().getNbQuadraturePoints(type_elem); UInt mat_index = model->getElementMaterial(type_elem)(elem_nb); const Vector & stress = model->getMaterial(mat_index).getStress(type_elem); UInt global_elem = model->getElementIndexByMaterial(type_elem)(elem_nb); if (type_elem == _triangle_6) { const Vector & conn_elem = mesh.getConnectivity(type_elem); UInt facet_index; for (UInt n = 0; n < 3; ++n) { UInt global_node = conn_elem(global_elem, n); if (global_node != conn_facet(f, 0) && global_node != conn_facet(f, 1)) { facet_index = n + 1; break; } } if (facet_index == 3) facet_index = 0; if (facet_index == 0) { natural_coords(0) = coords[1]; natural_coords(1) = coords[0]; natural_coords(2) = coords[2]; natural_coords(3) = coords[0]; } else if (facet_index == 1) { natural_coords(0) = coords[2]; natural_coords(1) = coords[1]; natural_coords(2) = coords[1]; natural_coords(3) = coords[2]; } else if (facet_index == 2) { natural_coords(0) = coords[0]; natural_coords(1) = coords[2]; natural_coords(2) = coords[0]; natural_coords(3) = coords[1]; } if (conn_elem(global_elem, 2) == conn_facet(f, 1)) { Real x = natural_coords(0); Real y = natural_coords(1); natural_coords(0) = natural_coords(2); natural_coords(1) = natural_coords(3); natural_coords(2) = x; natural_coords(3) = y; } ElementClass<_triangle_3>::computeShapes(natural_coords.storage(), nb_quad_facet, shapes.storage()); } types::Matrix stress_edge(spatial_dimension, spatial_dimension); types::Matrix stress_shape(spatial_dimension, spatial_dimension); for (UInt q = 0; q < nb_quad_facet; ++q) { stress_edge.clear(); for (UInt q_el = 0; q_el < nb_quad_elem; ++q_el) { types::Matrix stress_local(stress.storage() + global_elem*nb_quad_elem*spatial_dimension*spatial_dimension + q_el*spatial_dimension*spatial_dimension, spatial_dimension, spatial_dimension); stress_shape = stress_local; stress_shape *= shapes(q, q_el); stress_edge += stress_shape; } types::RVector normal(normals.storage() + f*nb_quad_facet*spatial_dimension, spatial_dimension); types::RVector tangent(tangents.storage() + f*nb_quad_facet*spatial_dimension, spatial_dimension); stress_check(q) = std::max(stress_check(q), computeEffectiveNorm(stress_edge, normal, tangent)); } } for (UInt q = 0; q < nb_quad_facet; ++q) { if (stress_check(q) > model->getSigmaLimit()(f)) { facet_insertion.push_back(f); for (UInt qs = 0; qs < nb_quad_facet; ++qs) sigma_insertion.push_back(stress_check(qs)); facets_check(f) = false; break; } } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the residual by assembling @f$\int_{e} t_e N_e dS @f$ * * @param[in] displacements nodes displacements * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void MaterialCohesive::updateResidual(__attribute__((unused)) Vector & displacement, GhostType ghost_type) { AKANTU_DEBUG_IN(); /// compute traction computeTraction(ghost_type); /// update and assemble residual assembleResidual(ghost_type); /// compute energies computeEnergies(); /// update old values Mesh & mesh = fem_cohesive->getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive); for(; it != last_type; ++it) { tractions_old(*it, ghost_type).copy(tractions(*it, ghost_type)); opening_old(*it, ghost_type).copy(opening(*it, ghost_type)); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void MaterialCohesive::assembleResidual(GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); Vector & residual = const_cast &>(model->getResidual()); Mesh & mesh = fem_cohesive->getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive); for(; it != last_type; ++it) { const Vector & shapes = fem_cohesive->getShapes(*it, ghost_type); Vector & elem_filter = element_filter(*it, ghost_type); Vector & traction = tractions(*it, ghost_type); UInt size_of_shapes = shapes.getNbComponent(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it); UInt nb_quadrature_points = fem_cohesive->getNbQuadraturePoints(*it, ghost_type); UInt nb_element = elem_filter.getSize(); /// compute @f$t_i N_a@f$ Real * shapes_val = shapes.storage(); UInt * elem_filter_val = elem_filter.storage(); Vector * shapes_filtered = new Vector(nb_element*nb_quadrature_points, size_of_shapes, "filtered shapes"); Real * shapes_filtered_val = shapes_filtered->values; for (UInt el = 0; el < nb_element; ++el) { shapes_val = shapes.storage() + elem_filter_val[el] * size_of_shapes * nb_quadrature_points; memcpy(shapes_filtered_val, shapes_val, size_of_shapes * nb_quadrature_points * sizeof(Real)); shapes_filtered_val += size_of_shapes * nb_quadrature_points; } shapes_filtered_val = shapes_filtered->values; // multiply traction by shapes Vector traction_cpy(traction); traction_cpy.extendComponentsInterlaced(size_of_shapes, spatial_dimension); Real * traction_cpy_val = traction_cpy.storage(); for (UInt el = 0; el < nb_element; ++el) { for (UInt q = 0; q < nb_quadrature_points; ++q) { for (UInt n = 0; n < size_of_shapes; ++n,++shapes_filtered_val) { for (UInt i = 0; i < spatial_dimension; ++i) { *traction_cpy_val++ *= *shapes_filtered_val; } } } } delete shapes_filtered; /** * compute @f$\int t \cdot N\, dS@f$ by @f$ \sum_q \mathbf{N}^t * \mathbf{t}_q \overline w_q J_q@f$ */ Vector int_t_N(nb_element, spatial_dimension*size_of_shapes, "int_t_N"); fem_cohesive->integrate(traction_cpy, int_t_N, spatial_dimension*size_of_shapes, *it, ghost_type, &elem_filter); int_t_N.extendComponents(2); Real * int_t_N_val = int_t_N.storage(); for (UInt el = 0; el < nb_element; ++el) { for (UInt n = 0; n < size_of_shapes*spatial_dimension; ++n) int_t_N_val[n] *= -1.; int_t_N_val += nb_nodes_per_element*spatial_dimension; } /// assemble model->getFEMBoundary().assembleVector(int_t_N, residual, model->getDOFSynchronizer().getLocalDOFEquationNumbers(), residual.getNbComponent(), *it, ghost_type, &elem_filter, 1); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute traction from displacements * * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void MaterialCohesive::computeTraction(GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); Mesh & mesh = fem_cohesive->getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive); for(; it != last_type; ++it) { Vector & elem_filter = element_filter(*it, ghost_type); UInt nb_element = elem_filter.getSize(); UInt nb_quadrature_points = nb_element*fem_cohesive->getNbQuadraturePoints(*it, ghost_type); Vector normal(nb_quadrature_points, spatial_dimension, "normal"); /// compute normals @f$\mathbf{n}@f$ computeNormal(model->getCurrentPosition(), normal, *it, ghost_type); /// compute openings @f$\mathbf{\delta}@f$ computeOpening(model->getDisplacement(), opening(*it, ghost_type), *it, ghost_type); /// compute traction @f$\mathbf{t}@f$ computeTraction(normal, *it, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void MaterialCohesive::computeNormal(const Vector & position, Vector & normal, ElementType type, GhostType ghost_type) { AKANTU_DEBUG_IN(); #define COMPUTE_NORMAL(type) \ fem_cohesive->getShapeFunctions(). \ computeNormalsOnControlPoints(position, \ normal, \ ghost_type, \ &(element_filter(type, ghost_type))) AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_NORMAL); #undef COMPUTE_NORMAL AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void MaterialCohesive::computeOpening(const Vector & displacement, Vector & opening, ElementType type, GhostType ghost_type) { AKANTU_DEBUG_IN(); #define COMPUTE_OPENING(type) \ fem_cohesive->getShapeFunctions(). \ interpolateOnControlPoints(displacement, \ opening, \ spatial_dimension, \ ghost_type, \ &(element_filter(type, ghost_type))) AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_OPENING); #undef COMPUTE_OPENING AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void MaterialCohesive::computeEnergies() { AKANTU_DEBUG_IN(); Mesh & mesh = fem_cohesive->getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive); for(; it != last_type; ++it) { Vector::iterator erev = reversible_energy(*it, _not_ghost).begin(); Vector::iterator etot = total_energy(*it, _not_ghost).begin(); Vector::iterator traction_it = tractions(*it, _not_ghost).begin(spatial_dimension); Vector::iterator traction_old_it = tractions_old(*it, _not_ghost).begin(spatial_dimension); Vector::iterator opening_it = opening(*it, _not_ghost).begin(spatial_dimension); Vector::iterator opening_old_it = opening_old(*it, _not_ghost).begin(spatial_dimension); Vector::iteratortraction_end = tractions(*it, _not_ghost).end(spatial_dimension); /// loop on each quadrature point for (; traction_it != traction_end; ++traction_it, ++traction_old_it, ++opening_it, ++opening_old_it, ++erev, ++etot) { /// trapezoidal integration types::RVector b(spatial_dimension); b = *opening_it; b -= *opening_old_it; types::RVector h(spatial_dimension); h = *traction_old_it; h += *traction_it; *etot += .5 * b.dot(h); *erev = .5 * traction_it->dot(*opening_it); } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Real MaterialCohesive::getReversibleEnergy() { AKANTU_DEBUG_IN(); Real erev = 0.; /// integrate the dissipated energy for each type of elements Mesh & mesh = fem_cohesive->getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive); for(; it != last_type; ++it) { erev += fem_cohesive->integrate(reversible_energy(*it, _not_ghost), *it, _not_ghost, &element_filter(*it, _not_ghost)); } AKANTU_DEBUG_OUT(); return erev; } /* -------------------------------------------------------------------------- */ Real MaterialCohesive::getDissipatedEnergy() { AKANTU_DEBUG_IN(); Real edis = 0.; /// integrate the dissipated energy for each type of elements Mesh & mesh = fem_cohesive->getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost, _ek_cohesive); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost, _ek_cohesive); for(; it != last_type; ++it) { Vector dissipated_energy(total_energy(*it, _not_ghost)); dissipated_energy -= reversible_energy(*it, _not_ghost); edis += fem_cohesive->integrate(dissipated_energy, *it, _not_ghost, &element_filter(*it, _not_ghost)); } AKANTU_DEBUG_OUT(); return edis; } /* -------------------------------------------------------------------------- */ void MaterialCohesive::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material Cohesive [" << std::endl; Material::printself(stream, indent + 1); stream << space << "]" << std::endl; } __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh index 1b641e16d..2791e6e6d 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh +++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh @@ -1,220 +1,214 @@ /** * @file material_cohesive.hh * @author Marco Vocialta * @date Tue Feb 7 17:50:23 2012 * * @brief Specialization of the material class for cohesive elements * * @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 "material.hh" #include "aka_common.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_COHESIVE_HH__ #define __AKANTU_MATERIAL_COHESIVE_HH__ /* -------------------------------------------------------------------------- */ namespace akantu { class SolidMechanicsModelCohesive; } __BEGIN_AKANTU__ class MaterialCohesive : public Material { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - typedef FEMTemplate< IntegratorCohesive, ShapeCohesive > MyFEMCohesiveType; + typedef FEMTemplate< IntegratorCohesive, + ShapeCohesive > MyFEMCohesiveType; public: - MaterialCohesive(Model & model, const ID & id = ""); + MaterialCohesive(SolidMechanicsModel& model, const ID & id = ""); virtual ~MaterialCohesive(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// read properties virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// initialize the material computed parameter virtual void initMaterial(); /// resize vectors for new cohesive elements virtual void resizeCohesiveVectors(); /// compute the residual for this material virtual void updateResidual(Vector & current_position, GhostType ghost_type = _not_ghost); /// compute the stable time step for an element of size h virtual Real getStableTimeStep(__attribute__((unused)) Real h, __attribute__((unused)) const Element & element = ElementNull) { AKANTU_DEBUG_TO_IMPLEMENT(); } // /// add an element to the local mesh filter // __aka_inline__ void addElement(const ElementType & type, // UInt element, // const GhostType & ghost_type); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; /// check stress for cohesive elements' insertion virtual void checkInsertion(Vector & facet_insertion); protected: /// constitutive law virtual void computeStress(__attribute__((unused)) ElementType el_type, __attribute__((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// compute the tangent stiffness matrix virtual void computeTangentStiffness(__attribute__((unused)) const ElementType & el_type, __attribute__((unused)) Vector & tangent_matrix, __attribute__((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); } void computeNormal(const Vector & position, Vector & normal, ElementType type, GhostType ghost_type); void computeOpening(const Vector & displacement, Vector & normal, ElementType type, GhostType ghost_type); template void computeNormal(const Vector & position, Vector & normal, GhostType ghost_type); /// assemble residual void assembleResidual(GhostType ghost_type = _not_ghost); /// compute tractions (including normals and openings) void computeTraction(GhostType ghost_type = _not_ghost); /// constitutive law virtual void computeTraction(const Vector & normal, ElementType el_type, GhostType ghost_type = _not_ghost) = 0; /// compute reversible and total energies by element void computeEnergies(); /// compute effective stress norm for insertion check virtual Real computeEffectiveNorm(const types::Matrix & stress, const types::RVector & normal, const types::RVector & tangent){ AKANTU_DEBUG_TO_IMPLEMENT(); }; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// compute reversible energy Real getReversibleEnergy(); /// compute dissipated energy Real getDissipatedEnergy(); /// get sigma_c AKANTU_GET_MACRO(SigmaC, sigma_c, Real); /// get rand AKANTU_GET_MACRO(RandFactor, rand, Real); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// reversible energy by quadrature point ByElementTypeReal reversible_energy; /// total energy by quadrature point ByElementTypeReal total_energy; /// traction in all elements and quadrature points (previous time step) ByElementTypeReal tractions_old; /// opening in all elements and quadrature points (previous time step) ByElementTypeReal opening_old; protected: /// traction in all elements and quadrature points ByElementTypeReal tractions; /// opening in all elements and quadrature points ByElementTypeReal opening; /// Link to the cohesive fem object in the model MyFEMCohesiveType * fem_cohesive; /// critical stress Real sigma_c; /// randomness factor Real rand; /// vector to store stresses on facets for element insertions Vector sigma_insertion; /// pointer to the solid mechanics model for cohesive elements SolidMechanicsModelCohesive * model; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "material_cohesive_inline_impl.cc" -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialCohesive & _this) -{ - _this.printself(stream); - return stream; -} - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_COHESIVE_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc index fd056169d..993ebfd5d 100644 --- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc @@ -1,34 +1,33 @@ /** * @file material_cohesive_inline_impl.cc * @author Nicolas Richart * @date Thu Feb 23 12:27:13 2012 * * @brief * * @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 . * */ /* -------------------------------------------------------------------------- */ - template void MaterialCohesive::computeNormal(const Vector & position, Vector & normal, GhostType ghost_type) { } diff --git a/src/model/solid_mechanics/materials/material_damage.cc b/src/model/solid_mechanics/materials/material_damage.cc index 9e30aeae8..f81c31c43 100644 --- a/src/model/solid_mechanics/materials/material_damage.cc +++ b/src/model/solid_mechanics/materials/material_damage.cc @@ -1,159 +1,170 @@ /** * @file material_damage.cc * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the damage material * * @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 "material_damage.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialDamage::MaterialDamage(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), +template +MaterialDamage::MaterialDamage(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), MaterialElastic(model, id), damage("damage", id), dissipated_energy("Dissipated Energy", id), strain_prev("Previous Strain", id), stress_prev("Previous Stress", id), int_sigma("Integral of sigma", id) { AKANTU_DEBUG_IN(); - is_non_local = false; + this->is_non_local = false; initInternalVector(this->damage, 1); initInternalVector(this->dissipated_energy, 1); initInternalVector(this->strain_prev, spatial_dimension * spatial_dimension); initInternalVector(this->stress_prev, spatial_dimension * spatial_dimension); initInternalVector(this->int_sigma, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialDamage::initMaterial() { +template +void MaterialDamage::initMaterial() { AKANTU_DEBUG_IN(); - MaterialElastic::initMaterial(); + MaterialElastic::initMaterial(); resizeInternalVector(this->damage); resizeInternalVector(this->dissipated_energy); resizeInternalVector(this->strain_prev); resizeInternalVector(this->stress_prev); resizeInternalVector(this->int_sigma); - is_init = true; - AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the dissipated energy in each element by a rectangular approximation * of * @f$ Ed = \int_0^{\epsilon}\sigma(\omega)d\omega - \frac{1}{2}\sigma:\epsilon@f$ */ -void MaterialDamage::updateDissipatedEnergy(GhostType ghost_type) { +template +void MaterialDamage::updateDissipatedEnergy(GhostType ghost_type) { // compute the dissipated energy per element - const Mesh & mesh = model->getFEM().getMesh(); + const Mesh & mesh = this->model->getFEM().getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type); for(; it != end; ++it) { ElementType el_type = *it; Vector::iterator sigma = - stress(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); + this->stress(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); Vector::iterator sigma_p = stress_prev(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); Vector::iterator epsilon = - strain(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); + this->strain(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); Vector::iterator epsilon_p = strain_prev(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); Vector::iterator ints = int_sigma(el_type, ghost_type).begin(); Vector::iterator ed = dissipated_energy(el_type, ghost_type).begin(); Vector::iterator ed_end = dissipated_energy(el_type, ghost_type).end(); for (; ed != ed_end; ++ed, ++ints, ++epsilon, ++sigma, ++epsilon_p, ++sigma_p) { Real epot = 0.; Real dint = 0.; for (UInt i = 0; i < spatial_dimension; ++i) { for (UInt j = 0; j < spatial_dimension; ++j) { epot += (*sigma)(i,j) * (*epsilon)(i,j); dint += .5 * ((*sigma_p)(i,j) + (*sigma)(i,j)) * ((*epsilon)(i,j) - (*epsilon_p)(i,j)); (*epsilon_p)(i,j) = (*epsilon)(i,j); (*sigma_p)(i,j) = (*sigma)(i,j); } } epot *= .5; *ints += dint; *ed = *ints - epot; } } } /* -------------------------------------------------------------------------- */ -Real MaterialDamage::getDissipatedEnergy() const { +template +Real MaterialDamage::getDissipatedEnergy() const { AKANTU_DEBUG_IN(); Real de = 0.; - const Mesh & mesh = model->getFEM().getMesh(); + const Mesh & mesh = this->model->getFEM().getMesh(); /// integrate the dissipated energy for each type of elements Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost); Mesh::type_iterator end = mesh.lastType(spatial_dimension, _not_ghost); for(; it != end; ++it) { - de += model->getFEM().integrate(dissipated_energy(*it, _not_ghost), *it, - _not_ghost, &element_filter(*it, _not_ghost)); + de += this->model->getFEM().integrate(dissipated_energy(*it, _not_ghost), *it, + _not_ghost, &this->element_filter(*it, _not_ghost)); } AKANTU_DEBUG_OUT(); return de; } /* -------------------------------------------------------------------------- */ -bool MaterialDamage::setParam(const std::string & key, const std::string & value, - const ID & id) { - return MaterialElastic::setParam(key, value, id); +template +bool MaterialDamage::setParam(const std::string & key, + const std::string & value, + const ID & id) { + return MaterialElastic::setParam(key, value, id); } /* -------------------------------------------------------------------------- */ -void MaterialDamage::printself(std::ostream & stream, int indent) const { +template +void MaterialDamage::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_damage> [" << std::endl; - MaterialElastic::printself(stream, indent + 1); + MaterialElastic::printself(stream, indent + 1); stream << space << "]" << std::endl; } + /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialDamage); + + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_damage.hh b/src/model/solid_mechanics/materials/material_damage.hh index 1e41c3110..20cb0de0f 100644 --- a/src/model/solid_mechanics/materials/material_damage.hh +++ b/src/model/solid_mechanics/materials/material_damage.hh @@ -1,114 +1,106 @@ /** * @file material_damage.hh * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Thu Jul 29 15:00:59 2010 * * @brief Material isotropic elastic * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_DAMAGE_HH__ #define __AKANTU_MATERIAL_DAMAGE_HH__ __BEGIN_AKANTU__ - -class MaterialDamage : public virtual MaterialElastic { +template +class MaterialDamage : public virtual MaterialElastic { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialDamage(Model & model, const ID & id = ""); + MaterialDamage(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialDamage() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); bool setParam(const std::string & key, const std::string & value, const ID & id); /// give the dissipated energy for the time step Real getDissipatedEnergy() const; /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// update the dissipated energy, must be called after the stress have been computed void updateDissipatedEnergy(GhostType ghost_type); /* ------------------------------------------------------------------------ */ /* DataAccessor inherited members */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// damage internal variable ByElementTypeReal damage; /// dissipated energy ByElementTypeReal dissipated_energy; /// previous strain used to compute the dissipated energy ByElementTypeReal strain_prev; /// previous strain used to compute the dissipated energy ByElementTypeReal stress_prev; /// contain the current value of @f$ \int_0^{\epsilon}\sigma(\omega)d\omega @f$ the dissipated energy ByElementTypeReal int_sigma; }; -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialDamage & _this) -{ - _this.printself(stream); - return stream; -} - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_DAMAGE_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_damage_linear.cc b/src/model/solid_mechanics/materials/material_damage_linear.cc index 331d62272..224d5ecae 100644 --- a/src/model/solid_mechanics/materials/material_damage_linear.cc +++ b/src/model/solid_mechanics/materials/material_damage_linear.cc @@ -1,128 +1,136 @@ /** * @file material_damage_linear.cc * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the damage material * * @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 "material_damage_linear.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialDamageLinear::MaterialDamageLinear(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), MaterialDamage(model, id) { +template +MaterialDamageLinear::MaterialDamageLinear(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), + MaterialElastic(model, id), + MaterialDamage(model, id) { AKANTU_DEBUG_IN(); Sigc = 1e5; Gc = 2; - is_non_local = false; - - initInternalVector(this->K, 1); + this->initInternalVector(this->K, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialDamageLinear::initMaterial() { +template +void MaterialDamageLinear::initMaterial() { AKANTU_DEBUG_IN(); - MaterialDamage::initMaterial(); - - resizeInternalVector(this->K); - Epsmin = Sigc / E; + MaterialDamage::initMaterial(); + this->resizeInternalVector(this->K); + Epsmin = Sigc / this->E; Epsmax = 2 * Gc/ Sigc + Epsmin; - const Mesh&mesh=model->getFEM().getMesh() ; + const Mesh & mesh = this->model->getFEM().getMesh() ; Mesh::type_iterator it = mesh.firstType(spatial_dimension); Mesh::type_iterator end = mesh.lastType(spatial_dimension); for(; it != end; ++it) { UInt nb_element = mesh.getNbElement(*it); - UInt nb_quad = model->getFEM().getNbQuadraturePoints(*it); + UInt nb_quad = this->model->getFEM().getNbQuadraturePoints(*it); Vector & K_vec = K(*it); std::fill_n(K_vec.storage(),nb_element*nb_quad,Epsmin); } - is_init = true; - AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialDamageLinear::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialDamageLinear::computeStress(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; - Real * dam = damage(el_type, ghost_type).storage(); - Real * K = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); + Real * K = this->K(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; - computeStress(F, sigma,*dam,*K); + this->computeStress(F, sigma,*dam, *K); ++dam; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialDamageLinear::setParam(const std::string & key, const std::string & value, +template +bool MaterialDamageLinear::setParam(const std::string & key, + const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "Sigc") { sstr >> Sigc; } else if(key == "Gc") { sstr >> Gc; } - else { return MaterialDamage::setParam(key, value, id); } + else { return MaterialDamage::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialDamageLinear::printself(std::ostream & stream, int indent) const { +template +void MaterialDamageLinear::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_damage_linear> [" << std::endl; stream << space << " + SigmaC : " << Sigc << std::endl; stream << space << " + GC : " << Gc << std::endl; - MaterialDamage::printself(stream, indent + 1); + MaterialDamage::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialDamageLinear); + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_damage_linear.hh b/src/model/solid_mechanics/materials/material_damage_linear.hh index 815ca3bbe..54e7ea672 100644 --- a/src/model/solid_mechanics/materials/material_damage_linear.hh +++ b/src/model/solid_mechanics/materials/material_damage_linear.hh @@ -1,116 +1,107 @@ /** * @file material_damage_linear.hh * @author Nicolas Richart * @author Marion Chambart * @date Thu Jul 29 15:00:59 2010 * * @brief Material isotropic elastic + linear softening * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_DAMAGE_LINEAR_HH__ #define __AKANTU_MATERIAL_DAMAGE_LINEAR_HH__ __BEGIN_AKANTU__ /** * Material liner damage * * parameters in the material files : * - Sigc : (default: 1e5) * - Gc : (default: 2) */ -class MaterialDamageLinear : public MaterialDamage { +template +class MaterialDamageLinear : public MaterialDamage { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialDamageLinear(Model & model, const ID & id = ""); + MaterialDamageLinear(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialDamageLinear() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma, Real & damage, Real &K); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// kind of toughness Real Gc; /// critical stress Real Sigc; /// damage internal variable ByElementTypeReal K; Real Epsmin, Epsmax; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "material_damage_linear_inline_impl.cc" -#endif - -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialDamageLinear & _this) -{ - _this.printself(stream); - return stream; -} +#include "material_damage_linear_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MATERIAL_DAMAGE_LINEAR_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_damage_linear_inline_impl.cc b/src/model/solid_mechanics/materials/material_damage_linear_inline_impl.cc index ad570b78a..21093b6eb 100644 --- a/src/model/solid_mechanics/materials/material_damage_linear_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_damage_linear_inline_impl.cc @@ -1,71 +1,69 @@ /** * @file material_damage_inline_impl.cc * @author Nicolas Richart * @author Marion Chambart * @date Tue Jul 27 11:57:43 2010 * * @brief Implementation of the inline functions of the material damage linear * * @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 . * */ /* -------------------------------------------------------------------------- */ - - -/* -------------------------------------------------------------------------- */ -inline void MaterialDamageLinear::computeStress(Real * F, Real * sigma, Real & dam, Real &K) { +template +inline void MaterialDamageLinear::computeStress(Real * F, Real * sigma, Real & dam, Real &K) { // Real trace = F[0] + F[4] + F[8]; // Real K = 1./3. * (E/(1. - 2.*nu)); // Real G = E / (2*(1 + nu)); // Real lambda = nu * E / ((1 + nu) * (1 - 2*nu)); Real Fdiag[3]; Real Fdiagp[3]; Math::matrix33_eigenvalues(F, Fdiag); Fdiagp[0] = std::max(0., Fdiag[0]); Fdiagp[1] = std::max(0., Fdiag[1]); Fdiagp[2] = std::max(0., Fdiag[2]); Real Ehat=sqrt(Fdiagp[0]*Fdiagp[0]+Fdiagp[1]*Fdiagp[1]+Fdiagp[2]*Fdiagp[2]); - MaterialElastic::computeStress(F, sigma); + MaterialElastic::computeStress(F, sigma); Real Fd = Ehat-K; if (Fd > 0) { dam = (Ehat - Epsmin) / (Epsmax-Epsmin)*(Ehat/Epsmax); dam = std::min(dam, 1.); K=Ehat; } sigma[0] *= 1-dam; sigma[4] *= 1-dam; sigma[8] *= 1-dam; sigma[1] *= 1-dam; sigma[3] *= 1-dam; sigma[2] *= 1-dam; sigma[6] *= 1-dam; sigma[5] *= 1-dam; sigma[7] *= 1-dam; } diff --git a/src/model/solid_mechanics/materials/material_elastic.cc b/src/model/solid_mechanics/materials/material_elastic.cc index a7c18eacc..9703abc2e 100644 --- a/src/model/solid_mechanics/materials/material_elastic.cc +++ b/src/model/solid_mechanics/materials/material_elastic.cc @@ -1,147 +1,166 @@ /** * @file material_elastic.cc * @author Nicolas Richart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the elastic material * * @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 "material_elastic.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialElastic::MaterialElastic(Model & model, const ID & id) : +template +MaterialElastic::MaterialElastic(SolidMechanicsModel & model, const ID & id) : Material(model, id) { AKANTU_DEBUG_IN(); E = 0; nu = 1./2.; plane_stress = false; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElastic::initMaterial() { +template +void MaterialElastic::initMaterial() { AKANTU_DEBUG_IN(); Material::initMaterial(); lambda = nu * E / ((1 + nu) * (1 - 2*nu)); mu = E / (2 * (1 + nu)); - if(plane_stress) - lambda = 2 * lambda * mu / (lambda + 2 * mu); + if(plane_stress) { + //lambda = 2 * lambda * mu / (lambda + 2 * mu); + lambda = nu * E / ((1 + nu)*(1 - nu)); + } kpa = lambda + 2./3. * mu; - - is_init = true; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElastic::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialElastic::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; // for (UInt i = 0; i < spatial_dimension; ++i) F[i*3 + i] -= 1; computeStress(F, sigma); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElastic::computeTangentStiffness(const ElementType & el_type, - Vector & tangent_matrix, - GhostType ghost_type) { - - switch(spatial_dimension) { - case 1: { computeTangentStiffnessByDim<1>(el_type, tangent_matrix, ghost_type); break; } - case 2: { computeTangentStiffnessByDim<2>(el_type, tangent_matrix, ghost_type); break; } - case 3: { computeTangentStiffnessByDim<3>(el_type, tangent_matrix, ghost_type); break; } +template +void MaterialElastic::computeTangentStiffness(const ElementType & el_type, + Vector & tangent_matrix, + GhostType ghost_type) { + AKANTU_DEBUG_IN(); + + Real * tangent_val = tangent_matrix.values; + UInt offset_tangent = tangent_matrix.getNbComponent(); + UInt nb_quads = tangent_matrix.getSize(); + + if (nb_quads == 0) return; + + memset(tangent_val, 0, offset_tangent * nb_quads * sizeof(Real)); + for (UInt q = 0; q < nb_quads; ++q, tangent_val += offset_tangent) { + computeTangentStiffness(tangent_val); } + + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialElastic::setParam(const std::string & key, const std::string & value, +template +bool MaterialElastic::setParam(const std::string & key, const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "E") { sstr >> E; } else if(key == "nu") { sstr >> nu; } else if(key == "Plane_Stress") { sstr >> plane_stress; } else { return Material::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -Real MaterialElastic::getPushWaveSpeed() { +template +Real MaterialElastic::getPushWaveSpeed() { return sqrt((lambda + 2*mu)/rho); } /* -------------------------------------------------------------------------- */ -Real MaterialElastic::getShearWaveSpeed() { +template +Real MaterialElastic::getShearWaveSpeed() { return sqrt(mu/rho); } /* -------------------------------------------------------------------------- */ -void MaterialElastic::printself(std::ostream & stream, int indent) const { +template +void MaterialElastic::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_elastic> [" << std::endl; if(!plane_stress) stream << space << " + Plane strain" << std::endl; else stream << space << " + Plane stress" << std::endl; stream << space << " + density : " << rho << std::endl; stream << space << " + Young's modulus : " << E << std::endl; stream << space << " + Poisson's ratio : " << nu << std::endl; - if(is_init) { + if(this->isInit()) { stream << space << " + First Lamé coefficient : " << lambda << std::endl; stream << space << " + Second Lamé coefficient : " << mu << std::endl; stream << space << " + Bulk coefficient : " << kpa << std::endl; } Material::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialElastic); + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_elastic.hh b/src/model/solid_mechanics/materials/material_elastic.hh index 30ac81271..e0715e546 100644 --- a/src/model/solid_mechanics/materials/material_elastic.hh +++ b/src/model/solid_mechanics/materials/material_elastic.hh @@ -1,153 +1,139 @@ /** * @file material_elastic.hh * @author Nicolas Richart * @date Thu Jul 29 15:00:59 2010 * * @brief Material isotropic elastic * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_ELASTIC_HH__ #define __AKANTU_MATERIAL_ELASTIC_HH__ __BEGIN_AKANTU__ /** * Material elastic isotropic * * parameters in the material files : * - rho : density (default: 0) * - E : Young's modulus (default: 0) * - nu : Poisson's ratio (default: 1/2) * - Plane_Stress : if 0: plane strain, else: plane stress (default: 0) */ +template class MaterialElastic : public virtual Material { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialElastic(Model & model, const ID & id = ""); + MaterialElastic(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialElastic() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: virtual void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// compute the tangent stiffness matrix for an element type void computeTangentStiffness(const ElementType & el_type, Vector & tangent_matrix, GhostType ghost_type = _not_ghost); /// compute the p-wave speed in the material virtual Real getPushWaveSpeed(); /// compute the s-wave speed in the material virtual Real getShearWaveSpeed(); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma); - // /// compute the tangent stiffness matrix for an element type - template - void computeTangentStiffnessByDim(akantu::ElementType, akantu::Vector& tangent_matrix, akantu::GhostType); - // /// compute the tangent stiffness matrix for an element - template void computeTangentStiffness(Real * tangent); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// get the stable time step inline Real getStableTimeStep(Real h, const Element & element); AKANTU_GET_MACRO(E, E, Real); AKANTU_GET_MACRO(Nu, nu, Real); AKANTU_GET_MACRO(Mu, mu, Real); AKANTU_GET_MACRO(Lambda, lambda, Real); AKANTU_SET_MACRO(E, E, Real); AKANTU_SET_MACRO(Nu, nu, Real); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// the young modulus Real E; /// Poisson coefficient Real nu; /// First Lamé coefficient Real lambda; /// Second Lamé coefficient (shear modulus) Real mu; /// Bulk modulus Real kpa; /// Plane stress or plane strain bool plane_stress; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "material_elastic_inline_impl.cc" -#endif - -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialElastic & _this) -{ - _this.printself(stream); - return stream; -} +#include "material_elastic_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MATERIAL_ELASTIC_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_elastic_caughey.cc b/src/model/solid_mechanics/materials/material_elastic_caughey.cc index 2dedc8499..9dc4ca9e5 100644 --- a/src/model/solid_mechanics/materials/material_elastic_caughey.cc +++ b/src/model/solid_mechanics/materials/material_elastic_caughey.cc @@ -1,164 +1,175 @@ /** * @file material_elastic_caughey.cc * @author David Kammer * @author Nicolas Richart * @date Wed May 4 15:25:52 2011 * * @brief Special. of the material class for the caughey viscoelastic material * * @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 "material_elastic_caughey.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialElasticCaughey::MaterialElasticCaughey(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), +template +MaterialElasticCaughey::MaterialElasticCaughey(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), MaterialElastic(model, id), stress_viscosity("stress_viscosity", id), stress_elastic("stress_elastic", id) { AKANTU_DEBUG_IN(); alpha = 0.; - UInt spatial_dimension = this->model->getSpatialDimension(); UInt stress_size = spatial_dimension * spatial_dimension; initInternalVector(this->stress_viscosity, stress_size); initInternalVector(this->stress_elastic , stress_size); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElasticCaughey::initMaterial() { +template +void MaterialElasticCaughey::initMaterial() { AKANTU_DEBUG_IN(); - MaterialElastic::initMaterial(); + MaterialElastic::initMaterial(); resizeInternalVector(this->stress_viscosity); resizeInternalVector(this->stress_elastic ); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElasticCaughey::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialElasticCaughey::computeStress(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); - UInt spatial_dimension = model->getSpatialDimension(); - - Vector & elem_filter = element_filter (el_type, ghost_type); + Vector & elem_filter = this->element_filter (el_type, ghost_type); Vector & stress_visc = stress_viscosity(el_type, ghost_type); Vector & stress_el = stress_elastic (el_type, ghost_type); - MaterialElastic::computeStress(el_type, ghost_type); + MaterialElastic::computeStress(el_type, ghost_type); - Vector & velocity = model->getVelocity(); - UInt nb_elem = element_filter(el_type, ghost_type).getSize(); + Vector & velocity = this->model->getVelocity(); + UInt nb_elem = this->element_filter(el_type, ghost_type).getSize(); UInt nb_quad_points_per_elem = - model->getFEM().getNbQuadraturePoints(el_type, ghost_type); + this->model->getFEM().getNbQuadraturePoints(el_type, ghost_type); UInt nb_quad_points = nb_quad_points_per_elem * nb_elem; Vector strain_rate(nb_quad_points, spatial_dimension * spatial_dimension, "strain_rate"); - model->getFEM().gradientOnQuadraturePoints(velocity, strain_rate, + this->model->getFEM().gradientOnQuadraturePoints(velocity, strain_rate, spatial_dimension, el_type, ghost_type, &elem_filter); Real F[3*3]; Real sigma[3*3]; Real * strain_rate_val = strain_rate.storage(); Real * stress_visc_val = stress_visc.storage(); Real * stress_el_val = stress_el.storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_rate_val[spatial_dimension * i + j]; - MaterialElastic::computeStress(F, sigma); + MaterialElastic::computeStress(F, sigma); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) { stress_visc_val[spatial_dimension * i + j] = alpha * sigma[3 * i + j]; stress_el_val [spatial_dimension * i + j] = stress_val[spatial_dimension*i + j]; stress_val [spatial_dimension * i + j] += stress_visc_val[spatial_dimension*i + j]; } strain_rate_val += spatial_dimension * spatial_dimension; stress_visc_val += spatial_dimension * spatial_dimension; stress_el_val += spatial_dimension * spatial_dimension; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElasticCaughey::computePotentialEnergy(ElementType el_type, GhostType ghost_type) { +template +void MaterialElasticCaughey::computePotentialEnergy(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); if(ghost_type != _not_ghost) return; Vector & stress_el = stress_elastic(el_type, ghost_type); Real * stress_el_val = stress_el.storage(); - Real * epot = potential_energy(el_type, ghost_type).storage(); + Real * epot = this->potential_energy(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; - MaterialElastic::computePotentialEnergy(strain_val, stress_el_val, epot); + MaterialElastic::computePotentialEnergy(strain_val, stress_el_val, epot); epot++; stress_el_val += spatial_dimension*spatial_dimension; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialElasticCaughey::setParam(const std::string & key, const std::string & value, +template +bool MaterialElasticCaughey::setParam(const std::string & key, + const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "alpha") { sstr >> alpha; } - else { return MaterialElastic::setParam(key, value, id); } + else { return MaterialElastic::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialElasticCaughey::printself(std::ostream & stream, int indent) const { +template +void MaterialElasticCaughey::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "MaterialElasticCaughey [" << std::endl; - MaterialElastic::printself(stream, indent + 1); + MaterialElastic::printself(stream, indent + 1); stream << space << " + artifical viscous ratio : " << alpha << std::endl; stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialElasticCaughey); + + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_elastic_caughey.hh b/src/model/solid_mechanics/materials/material_elastic_caughey.hh index 367b492a3..2ed74fc2e 100644 --- a/src/model/solid_mechanics/materials/material_elastic_caughey.hh +++ b/src/model/solid_mechanics/materials/material_elastic_caughey.hh @@ -1,126 +1,118 @@ /** * @file material_elastic_caughey.hh * @author David Kammer * @author Nicolas Richart * @date Wed May 4 15:16:59 2011 * * @brief Material isotropic viscoelastic (according to the Caughey condition) * * @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_common.hh" #include "material.hh" #include "material_elastic.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_ELASTIC_CAUGHEY_HH__ #define __AKANTU_MATERIAL_ELASTIC_CAUGHEY_HH__ __BEGIN_AKANTU__ /** * Material viscoelastic (caughey condition) isotropic * * parameters in the material files : * - rho : density (default: 0) * - E : Young's modulus (default: 0) * - nu : Poisson's ratio (default: 1/2) * - Plane_Stress : if 0: plane strain, else: plane stress (default: 0) * - alpha : viscous ratio */ -class MaterialElasticCaughey : public MaterialElastic { +template +class MaterialElasticCaughey : public MaterialElastic { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialElasticCaughey(Model & model, const ID & id = ""); + MaterialElasticCaughey(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialElasticCaughey() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// compute the potential energy for all elements virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point //inline void computeStress(Real * F, Real * sigma); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressViscosity, stress_viscosity, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressElastic, stress_elastic, Real); AKANTU_GET_MACRO(Alpha, alpha, Real); AKANTU_SET_MACRO(Alpha, alpha, Real); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// stress due to viscosity ByElementTypeReal stress_viscosity; /// stress due to elasticity ByElementTypeReal stress_elastic; /// viscous ratio Real alpha; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_elastic_caughey_inline_impl.cc" -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -/* -inline std::ostream & operator <<(std::ostream & stream, const MaterialElasticCaughey & _this) -{ - _this.printself(stream); - return stream; -} -*/ __END_AKANTU__ #endif /* __AKANTU_MATERIAL_ELASTIC_CAUGHEY_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc b/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc index 677e70896..d1e307db7 100644 --- a/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_elastic_inline_impl.cc @@ -1,106 +1,94 @@ /** * @file material_elastic_inline_impl.cc * @author Nicolas Richart * @date Tue Jul 27 11:57:43 2010 * * @brief Implementation of the inline functions of the material elastic * * @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 . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -inline void MaterialElastic::computeStress(Real * F, Real * sigma) { - Real trace = F[0] + F[4] + F[8]; /// \F_{11} + \F_{22} + \F_{33} +template +inline void MaterialElastic::computeStress(Real * F, Real * sigma) { + Real trace = F[0] + F[4] + F[8]; /// \F_{11} + \F_{22} + \F_{33} /// \sigma_{ij} = \lamda * \F_{kk} * \delta_{ij} + 2 * \mu * \F_{ij} sigma[0] = lambda * trace + 2*mu*F[0]; sigma[4] = lambda * trace + 2*mu*F[4]; - if(plane_stress) F[8] = (F[0] + F[4])*(nu/(nu-1.)); + // if(plane_stress) F[8] = (F[0] + F[4])*(nu/(nu-1.)); sigma[8] = lambda * trace + 2*mu*F[8]; sigma[1] = sigma[3] = mu * (F[1] + F[3]); sigma[2] = sigma[6] = mu * (F[2] + F[6]); sigma[5] = sigma[7] = mu * (F[5] + F[7]); } /* -------------------------------------------------------------------------- */ -template -void MaterialElastic::computeTangentStiffnessByDim(__attribute__((unused)) akantu::ElementType, - akantu::Vector& tangent_matrix, - __attribute__((unused)) akantu::GhostType) { - AKANTU_DEBUG_IN(); - - Real * tangent_val = tangent_matrix.values; - UInt offset_tangent = tangent_matrix.getNbComponent(); - UInt nb_quads = tangent_matrix.getSize(); - - if (nb_quads == 0) return; - - memset(tangent_val, 0, offset_tangent * nb_quads * sizeof(Real)); - for (UInt q = 0; q < nb_quads; ++q, tangent_val += offset_tangent) { - computeTangentStiffness(tangent_val); - } - - AKANTU_DEBUG_OUT(); +template<> +inline void MaterialElastic<1>::computeStress(Real * F, Real * sigma) { + sigma[0] = E * F[0]; } + /* -------------------------------------------------------------------------- */ -template -void MaterialElastic::computeTangentStiffness(Real * tangent) { +template +void MaterialElastic::computeTangentStiffness(Real * tangent) { - UInt n = (dim * (dim - 1) / 2 + dim); + UInt n = (spatial_dimension * (spatial_dimension - 1) / 2 + spatial_dimension); Real Ep = E/((1+nu)*(1-2*nu)); Real Miiii = Ep * (1-nu); Real Miijj = Ep * nu; Real Mijij = Ep * (1-2*nu) * .5; tangent[0 * n + 0] = Miiii; // test of dimension should by optimized out by the compiler due to the template - if(dim >= 2) { + if(spatial_dimension >= 2) { tangent[1 * n + 1] = Miiii; tangent[0 * n + 1] = Miijj; tangent[1 * n + 0] = Miijj; tangent[(n - 1) * n + (n - 1)] = Mijij; } - if(dim == 3) { + if(spatial_dimension == 3) { tangent[2 * n + 2] = Miiii; tangent[0 * n + 2] = Miijj; tangent[1 * n + 2] = Miijj; tangent[2 * n + 0] = Miijj; tangent[2 * n + 1] = Miijj; tangent[3 * n + 3] = Mijij; tangent[4 * n + 4] = Mijij; } } /* -------------------------------------------------------------------------- */ -inline Real MaterialElastic::getStableTimeStep(Real h, - __attribute__ ((unused)) const Element & element) { +template +inline Real MaterialElastic::getStableTimeStep(Real h, + __attribute__ ((unused)) const Element & element) { return (h/getPushWaveSpeed()); } diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc index a20c16a71..130d7f77c 100644 --- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc +++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc @@ -1,199 +1,223 @@ /** * @file material_elastic_orthotropic.cc * @author Marco Vocialta * @date Thu Apr 12 11:28:23 2012 * * @brief Orthotropic elastic material * * @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 "material_elastic_orthotropic.hh" #include "solid_mechanics_model.hh" #include __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialElasticOrthotropic::MaterialElasticOrthotropic(Model & model, const ID & id) : +template +MaterialElasticOrthotropic::MaterialElasticOrthotropic(SolidMechanicsModel & model, + const ID & id) : Material(model, id) { AKANTU_DEBUG_IN(); E1 = 0; E2 = 0; E3 = 0; nu12 = 0; nu13 = 0; nu23 = 0; G12 = 0; G13 = 0; G23 = 0; plane_stress = false; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -MaterialElasticOrthotropic::~MaterialElasticOrthotropic() { +template +MaterialElasticOrthotropic::~MaterialElasticOrthotropic() { delete[] S; } /* -------------------------------------------------------------------------- */ -void MaterialElasticOrthotropic::initMaterial() { +template +void MaterialElasticOrthotropic::initMaterial() { AKANTU_DEBUG_IN(); Material::initMaterial(); S = new Real[9]; Real Delta; Real nu21 = nu12 * E2 / E1; Real nu31 = nu13 * E3 / E1; Real nu32 = nu23 * E3 / E2; if(plane_stress) { Delta = 1 - nu12 * nu21; S[0] = E1 / Delta; S[1] = E2 / Delta; S[2] = 0; S[3] = E1 * nu21 / Delta; S[4] = E2 * nu12 / Delta; S[5] = 0; S[6] = G12; S[7] = 0; S[8] = 0; } else { Delta = 1 - nu12 * nu21 - nu23 * nu32 - nu31 * nu13 - 2 * nu21 * nu13 * nu32; S[0] = E1 * (1 - nu23 * nu32) / Delta; S[1] = E2 * (1 - nu31 * nu13) / Delta; S[2] = E3 * (1 - nu12 * nu21) / Delta; S[3] = E2 * (nu12 + nu32 * nu13) / Delta; S[4] = E1 * (nu31 + nu21 * nu32) / Delta; S[5] = E3 * (nu23 + nu21 * nu13) / Delta; S[6] = G12; S[7] = G13; S[8] = G23; } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElasticOrthotropic::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialElasticOrthotropic::computeStress(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; // for (UInt i = 0; i < spatial_dimension; ++i) F[i*3 + i] -= 1; computeStress(F, sigma); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialElasticOrthotropic::computeTangentStiffness(const ElementType & el_type, - Vector & tangent_matrix, - GhostType ghost_type) { - - switch(spatial_dimension) { - case 1: { computeTangentStiffnessByDim<1>(el_type, tangent_matrix, ghost_type); break; } - case 2: { computeTangentStiffnessByDim<2>(el_type, tangent_matrix, ghost_type); break; } - case 3: { computeTangentStiffnessByDim<3>(el_type, tangent_matrix, ghost_type); break; } +template +void MaterialElasticOrthotropic::computeTangentStiffness(const ElementType & el_type, + Vector & tangent_matrix, + GhostType ghost_type) { + AKANTU_DEBUG_IN(); + + Real * tangent_val = tangent_matrix.values; + UInt offset_tangent = tangent_matrix.getNbComponent(); + UInt nb_quads = tangent_matrix.getSize(); + + if (nb_quads == 0) return; + + memset(tangent_val, 0, offset_tangent * nb_quads * sizeof(Real)); + for (UInt q = 0; q < nb_quads; ++q, tangent_val += offset_tangent) { + computeTangentStiffness(tangent_val); } + + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialElasticOrthotropic::setParam(const std::string & key, const std::string & value, - const ID & id) { +template +bool MaterialElasticOrthotropic::setParam(const std::string & key, + const std::string & value, + const ID & id) { std::stringstream sstr(value); if(key == "E1") { sstr >> E1; } else if(key == "E2") { sstr >> E2; } else if(key == "E3") { sstr >> E3; } else if(key == "nu12") { sstr >> nu12; } else if(key == "nu13") { sstr >> nu13; } else if(key == "nu23") { sstr >> nu23; } else if(key == "G12") { sstr >> G12; } else if(key == "G13") { sstr >> G13; } else if(key == "G23") { sstr >> G23; } else if(key == "Plane_Stress") { sstr >> plane_stress; } else { return Material::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -Real MaterialElasticOrthotropic::getPushWaveSpeed() { +template +Real MaterialElasticOrthotropic::getPushWaveSpeed() { return sqrt( (*std::max_element(S, S+3)) /rho); } /* -------------------------------------------------------------------------- */ -Real MaterialElasticOrthotropic::getShearWaveSpeed() { +template +Real MaterialElasticOrthotropic::getShearWaveSpeed() { return sqrt( (*std::max_element(S+6, S+9)) /rho); } /* -------------------------------------------------------------------------- */ -void MaterialElasticOrthotropic::printself(std::ostream & stream, int indent) const { +template +void MaterialElasticOrthotropic::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_elastic<_orthotropic> [" << std::endl; if(!plane_stress) stream << space << " + Plane strain" << std::endl; else stream << space << " + Plane stress" << std::endl; stream << space << " + density : " << rho << std::endl; stream << space << " + Young's modulus (x) : " << E1 << std::endl; stream << space << " + Young's modulus (y) : " << E2 << std::endl; stream << space << " + Young's modulus (z) : " << E3 << std::endl; stream << space << " + Poisson's ratio (xy) : " << nu12 << std::endl; stream << space << " + Poisson's ratio (xz) : " << nu13 << std::endl; stream << space << " + Poisson's ratio (yz) : " << nu23 << std::endl; stream << space << " + Shear modulus (xy) : " << G12 << std::endl; stream << space << " + Shear modulus (xz) : " << G13 << std::endl; stream << space << " + Shear modulus (yz) : " << G23 << std::endl; Material::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialElasticOrthotropic); + + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh b/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh index 3c031c58b..1d491ebba 100644 --- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh +++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.hh @@ -1,181 +1,167 @@ /** * @file material_elastic_orthotropic.hh * @author Marco Vocialta * @date Thu Apr 12 10:57:52 2012 * * @brief Orthotropic elastic material * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__ #define __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__ __BEGIN_AKANTU__ /** * Orthotropic elastic material * * parameters in the material files : * - rho : density (default: 0) * - E1 : Young's modulus along x (default: 0) * - E2 : Young's modulus along y (default: 0) * - E3 : Young's modulus along z (default: 0) * - nu12 : Poisson's ratio along xy (default: 0) * - nu13 : Poisson's ratio along xz (default: 0) * - nu23 : Poisson's ratio along yz (default: 0) * - G12 : Shear modulus along xy (default: 0) * - G13 : Shear modulus along xz (default: 0) * - G23 : Shear modulus along yz (default: 0) * - Plane_Stress : if 0: plane strain, else: plane stress (default: 0) */ +template class MaterialElasticOrthotropic : public virtual Material { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialElasticOrthotropic(Model & model, const ID & id = ""); + MaterialElasticOrthotropic(SolidMechanicsModel & model, const ID & id = ""); ~MaterialElasticOrthotropic(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: virtual void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// compute the tangent stiffness matrix for an element type void computeTangentStiffness(const ElementType & el_type, Vector & tangent_matrix, GhostType ghost_type = _not_ghost); /// compute the p-wave speed in the material virtual Real getPushWaveSpeed(); /// compute the s-wave speed in the material virtual Real getShearWaveSpeed(); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma); - // /// compute the tangent stiffness matrix for an element type - template - void computeTangentStiffnessByDim(akantu::ElementType, akantu::Vector& tangent_matrix, akantu::GhostType); - - // /// compute the tangent stiffness matrix for an element - template + /// compute the tangent stiffness matrix for an element void computeTangentStiffness(Real * tangent); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// get the stable time step inline Real getStableTimeStep(Real h, const Element & element); AKANTU_GET_MACRO(E1, E1, Real); AKANTU_GET_MACRO(E2, E2, Real); AKANTU_GET_MACRO(E3, E3, Real); AKANTU_GET_MACRO(Nu12, nu12, Real); AKANTU_GET_MACRO(Nu13, nu13, Real); AKANTU_GET_MACRO(Nu23, nu23, Real); AKANTU_GET_MACRO(G12, G12, Real); AKANTU_GET_MACRO(G13, G13, Real); AKANTU_GET_MACRO(G23, G23, Real); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// the x young modulus Real E1; /// the y young modulus Real E2; /// the z young modulus Real E3; /// xy Poisson coefficient Real nu12; /// xz Poisson coefficient Real nu13; /// yz Poisson coefficient Real nu23; /// xy shear modulus Real G12; /// xz shear modulus Real G13; /// yz shear modulus Real G23; /// stiffness coefficients Real * S; /// Plane stress or plane strain bool plane_stress; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "material_elastic_orthotropic_inline_impl.cc" -#endif - -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialElasticOrthotropic & _this) -{ - _this.printself(stream); - return stream; -} +#include "material_elastic_orthotropic_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MATERIAL_ELASTIC_ORTHOTROPIC_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic_inline_impl.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic_inline_impl.cc index 61169d63e..1531d1581 100644 --- a/src/model/solid_mechanics/materials/material_elastic_orthotropic_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic_inline_impl.cc @@ -1,98 +1,79 @@ /** * @file material_elastic_orthotropic_inline_impl.cc * @author Marco Vocialta * @date Thu Apr 12 13:40:42 2012 * * @brief Implementation of the inline functions of the orthotropic * elastic material * * @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 . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -inline void MaterialElasticOrthotropic::computeStress(Real * F, Real * sigma) { +template +inline void MaterialElasticOrthotropic::computeStress(Real * F, Real * sigma) { /// \mathbf{\sigma} = \mathbf{S} \mathbf{F} sigma[0] = S[0] * F[0] + S[3] * F[4] + S[4] * F[8]; sigma[4] = S[3] * F[0] + S[1] * F[4] + S[5] * F[8]; sigma[8] = S[4] * F[0] + S[5] * F[4] + S[2] * F[8]; sigma[1] = sigma[3] = S[6] * (F[1] + F[3]) / 2; sigma[2] = sigma[6] = S[7] * (F[2] + F[6]) / 2; sigma[5] = sigma[7] = S[8] * (F[5] + F[7]) / 2; } /* -------------------------------------------------------------------------- */ template -void MaterialElasticOrthotropic::computeTangentStiffnessByDim(__attribute__((unused)) akantu::ElementType, - akantu::Vector& tangent_matrix, - __attribute__((unused)) akantu::GhostType) { - AKANTU_DEBUG_IN(); - - Real * tangent_val = tangent_matrix.values; - UInt offset_tangent = tangent_matrix.getNbComponent(); - UInt nb_quads = tangent_matrix.getSize(); - - if (nb_quads == 0) return; - - memset(tangent_val, 0, offset_tangent * nb_quads * sizeof(Real)); - for (UInt q = 0; q < nb_quads; ++q, tangent_val += offset_tangent) { - computeTangentStiffness(tangent_val); - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template -void MaterialElasticOrthotropic::computeTangentStiffness(Real * tangent) { +void MaterialElasticOrthotropic::computeTangentStiffness(Real * tangent) { UInt n = (dim * (dim - 1) / 2 + dim); tangent[0 * n + 0] = S[0]; // test of dimension should by optimized out by the compiler due to the template if(dim >= 2) { tangent[1 * n + 1] = S[1]; tangent[0 * n + 1] = S[3]; tangent[1 * n + 0] = S[3]; tangent[(n - 1) * n + (n - 1)] = S[6]; } if(dim == 3) { tangent[2 * n + 2] = S[2]; tangent[0 * n + 2] = S[4]; tangent[1 * n + 2] = S[5]; tangent[2 * n + 0] = S[4]; tangent[2 * n + 1] = S[5]; tangent[3 * n + 3] = S[7]; tangent[4 * n + 4] = S[8]; } } /* -------------------------------------------------------------------------- */ -inline Real MaterialElasticOrthotropic::getStableTimeStep(Real h, - __attribute__ ((unused)) const Element & element) { +template +inline Real MaterialElasticOrthotropic::getStableTimeStep(Real h, + __attribute__ ((unused)) const Element & element) { return (h/getPushWaveSpeed()); } diff --git a/src/model/solid_mechanics/materials/material_marigo.cc b/src/model/solid_mechanics/materials/material_marigo.cc index ff271d5c5..1b5c4be42 100644 --- a/src/model/solid_mechanics/materials/material_marigo.cc +++ b/src/model/solid_mechanics/materials/material_marigo.cc @@ -1,156 +1,167 @@ /** * @file material_marigo.cc * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the marigo material * * @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 "material_marigo.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialMarigo::MaterialMarigo(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), MaterialDamage(model, id), +template +MaterialMarigo::MaterialMarigo(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), + MaterialElastic(model, id), + MaterialDamage(model, id), Yd_rand("Yd_rand",id) { AKANTU_DEBUG_IN(); Yd = 50; Sd = 5000; Yd_randomness = 0; - is_non_local = false; epsilon_c = std::numeric_limits::max(); initInternalVector(this->Yd_rand, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMarigo::initMaterial() { +template +void MaterialMarigo::initMaterial() { AKANTU_DEBUG_IN(); - MaterialDamage::initMaterial(); + MaterialDamage::initMaterial(); if (std::abs(epsilon_c - std::numeric_limits::max()) < std::numeric_limits::epsilon()) Yc = std::numeric_limits::max(); else { - Yc = .5 * epsilon_c * E * epsilon_c; + Yc = .5 * epsilon_c * this->E * epsilon_c; } resizeInternalVector(this->Yd_rand); - const Mesh & mesh = model->getFEM().getMesh(); + const Mesh & mesh = this->model->getFEM().getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension); for(; it != last_type; ++it) { - UInt nb_element = element_filter(*it).getSize(); - UInt nb_quad = model->getFEM().getNbQuadraturePoints(*it); + UInt nb_element = this->element_filter(*it).getSize(); + UInt nb_quad = this->model->getFEM().getNbQuadraturePoints(*it); Vector & Yd_rand_vec = Yd_rand(*it); for(UInt e = 0; e < nb_element; ++e) { Real rand_part = (2 * drand48()-1) * Yd_randomness * Yd; for(UInt q = 0; q < nb_quad; ++q) Yd_rand_vec(nb_quad*e+q,0) = Yd + rand_part; } } - is_init = true; - AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMarigo::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialMarigo::computeStress(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; - Real * dam = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); Real * Ydq = Yd_rand(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; Real Y = 0; computeStress(F, sigma, *dam, Y, *Ydq); ++dam; ++Ydq; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; - if(!is_non_local) updateDissipatedEnergy(ghost_type); + if(!this->is_non_local) this->updateDissipatedEnergy(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialMarigo::setParam(const std::string & key, const std::string & value, +template +bool MaterialMarigo::setParam(const std::string & key, + const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "Yd") { sstr >> Yd; } else if(key == "Sd") { sstr >> Sd; } else if(key == "Yd_randomness") { sstr >> Yd_randomness; } else if(key == "epsilon_c") { sstr >> epsilon_c; } - else { return MaterialDamage::setParam(key, value, id); } + else { return MaterialDamage::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialMarigo::printself(std::ostream & stream, int indent) const { +template +void MaterialMarigo::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_marigo> [" << std::endl; stream << space << " + Yd : " << Yd << std::endl; stream << space << " + Sd : " << Sd << std::endl; stream << space << " + randomness : " << Yd_randomness << std::endl; if (std::abs(epsilon_c - std::numeric_limits::max()) > std::numeric_limits::epsilon()) { stream << space << " + epsilon_c : " << epsilon_c << std::endl; stream << space << " + Yc : " << Yc << std::endl; } - MaterialDamage::printself(stream, indent + 1); + MaterialDamage::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialMarigo); + + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_marigo.hh b/src/model/solid_mechanics/materials/material_marigo.hh index 4fbc602e8..56262e650 100644 --- a/src/model/solid_mechanics/materials/material_marigo.hh +++ b/src/model/solid_mechanics/materials/material_marigo.hh @@ -1,150 +1,141 @@ /** * @file material_marigo.hh * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Thu Jul 29 15:00:59 2010 * * @brief Material isotropic elastic * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_MARIGO_HH__ #define __AKANTU_MATERIAL_MARIGO_HH__ __BEGIN_AKANTU__ /** * Material marigo * * parameters in the material files : * - Yd : (default: 50) * - Sd : (default: 5000) * - Ydrandomness : (default:0) */ -class MaterialMarigo : public MaterialDamage { +template +class MaterialMarigo : public MaterialDamage { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialMarigo(Model & model, const ID & id = ""); + MaterialMarigo(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialMarigo() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma, Real & dam, Real & Y, Real & Ydq); inline void computeDamageAndStress(Real * sigma, Real & dam, Real & Y, Real & Ydq); /* ------------------------------------------------------------------------ */ /* DataAccessor inherited members */ /* ------------------------------------------------------------------------ */ public: inline virtual UInt getNbDataToPack(const Element & element, SynchronizationTag tag) const; inline virtual UInt getNbDataToUnpack(const Element & element, SynchronizationTag tag) const; inline virtual void packData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag) const; inline virtual void unpackData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// resistance to damage Real Yd; /// damage threshold Real Sd; /// randomness on Yd Real Yd_randomness; /// critical epsilon when the material is considered as broken Real epsilon_c; Real Yc; /// Yd random internal variable ByElementTypeReal Yd_rand; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "material_marigo_inline_impl.cc" -#endif - -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialMarigo & _this) -{ - _this.printself(stream); - return stream; -} +#include "material_marigo_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MATERIAL_MARIGO_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_marigo_inline_impl.cc b/src/model/solid_mechanics/materials/material_marigo_inline_impl.cc index 540d42b7d..49d791b43 100644 --- a/src/model/solid_mechanics/materials/material_marigo_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_marigo_inline_impl.cc @@ -1,131 +1,137 @@ /** * @file material_marigo_inline_impl.cc * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Tue Jul 27 11:57:43 2010 * * @brief Implementation of the inline functions of the material marigo * * @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 . * */ /* -------------------------------------------------------------------------- */ -inline void MaterialMarigo::computeDamageAndStress(Real * sigma, Real & dam, - Real & Y, Real &Ydq) { +template +inline void MaterialMarigo::computeDamageAndStress(Real * sigma, Real & dam, + Real & Y, Real &Ydq) { Real Fd = Y - Ydq - Sd * dam; if (Fd > 0) dam = (Y - Ydq) / Sd; dam = std::min(dam,1.); sigma[0] *= 1-dam; sigma[4] *= 1-dam; sigma[8] *= 1-dam; sigma[1] *= 1-dam; sigma[3] *= 1-dam; sigma[2] *= 1-dam; sigma[6] *= 1-dam; sigma[5] *= 1-dam; sigma[7] *= 1-dam; } /* -------------------------------------------------------------------------- */ -inline void MaterialMarigo::computeStress(Real * F, - Real * sigma, - Real & dam, - Real & Y, Real &Ydq) { - MaterialElastic::computeStress(F, sigma); +template +inline void MaterialMarigo::computeStress(Real * F, + Real * sigma, + Real & dam, + Real & Y, Real &Ydq) { + MaterialElastic::computeStress(F, sigma); Y = sigma[0]*F[0] + sigma[1]*F[1] + sigma[2]*F[2] + sigma[3]*F[3] + sigma[4]*F[4] + sigma[5]*F[5] + sigma[6]*F[6] + sigma[7]*F[7] + sigma[8]*F[8]; Y *= 0.5; //Y *= (1 - dam); //Y = std::min(Y, Yc); - if(!is_non_local) { + if(!this->is_non_local) { computeDamageAndStress(sigma, dam, Y, Ydq); } } /* -------------------------------------------------------------------------- */ -inline UInt MaterialMarigo::getNbDataToPack(const Element & element, - SynchronizationTag tag) const { +template +inline UInt MaterialMarigo::getNbDataToPack(const Element & element, + SynchronizationTag tag) const { AKANTU_DEBUG_IN(); UInt size = 0; if(tag == _gst_smm_init_mat) size += sizeof(Real); - size += MaterialDamage::getNbDataToPack(element, tag); + size += MaterialDamage::getNbDataToPack(element, tag); AKANTU_DEBUG_OUT(); return size; } /* -------------------------------------------------------------------------- */ -inline UInt MaterialMarigo::getNbDataToUnpack(const Element & element, - SynchronizationTag tag) const { +template +inline UInt MaterialMarigo::getNbDataToUnpack(const Element & element, + SynchronizationTag tag) const { AKANTU_DEBUG_IN(); UInt size = 0; if(tag == _gst_smm_init_mat) size += sizeof(Real); - size += MaterialDamage::getNbDataToPack(element, tag); + size += MaterialDamage::getNbDataToPack(element, tag); AKANTU_DEBUG_OUT(); return size; } /* -------------------------------------------------------------------------- */ -inline void MaterialMarigo::packData(CommunicationBuffer & buffer, - const Element & element, - SynchronizationTag tag) const { +template +inline void MaterialMarigo::packData(CommunicationBuffer & buffer, + const Element & element, + SynchronizationTag tag) const { AKANTU_DEBUG_IN(); if(tag == _gst_smm_init_mat) buffer << Yd_rand(element.type, _not_ghost)(element.element); - MaterialDamage::packData(buffer, element, tag); + MaterialDamage::packData(buffer, element, tag); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -inline void MaterialMarigo::unpackData(CommunicationBuffer & buffer, - const Element & element, - SynchronizationTag tag) { +template +inline void MaterialMarigo::unpackData(CommunicationBuffer & buffer, + const Element & element, + SynchronizationTag tag) { AKANTU_DEBUG_IN(); if(tag == _gst_smm_init_mat) buffer >> Yd_rand(element.type, _ghost)(element.element); - MaterialDamage::packData(buffer, element, tag); + MaterialDamage::packData(buffer, element, tag); AKANTU_DEBUG_OUT(); } diff --git a/src/model/solid_mechanics/materials/material_marigo_non_local.cc b/src/model/solid_mechanics/materials/material_marigo_non_local.cc index bacfe513c..48b869a24 100644 --- a/src/model/solid_mechanics/materials/material_marigo_non_local.cc +++ b/src/model/solid_mechanics/materials/material_marigo_non_local.cc @@ -1,190 +1,190 @@ /** * @file material_marigo.cc * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the marigo material * * @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 "material_marigo_non_local.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialMarigoNonLocal::MaterialMarigoNonLocal(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), - MaterialMarigo(model, id), MaterialNonLocalParent(model, id), +template +MaterialMarigoNonLocal::MaterialMarigoNonLocal(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), + MaterialElastic(model, id), + MaterialMarigo(model, id), + MaterialNonLocalParent(model, id), Y("Y", id) { AKANTU_DEBUG_IN(); - is_non_local = true; + this->is_non_local = true; - initInternalVector(this->Y, 1); + this->initInternalVector(this->Y, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMarigoNonLocal::initMaterial() { +template +void MaterialMarigoNonLocal::initMaterial() { AKANTU_DEBUG_IN(); - MaterialMarigo::initMaterial(); - - - if(StressBasedWeightFunction * wf = - dynamic_cast(weight_func)){ - wf->updatePrincipalStress(_not_ghost); - wf->updatePrincipalStress(_ghost); - } - + MaterialMarigo::initMaterial(); MaterialNonLocalParent::initMaterial(); - resizeInternalVector(this->Y); - - is_init = true; - + this->resizeInternalVector(this->Y); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMarigoNonLocal::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialMarigoNonLocal::computeStress(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; - Real * dam = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); Real * Yt = Y(el_type, ghost_type).storage(); - Real * Ydq = Yd_rand(el_type, ghost_type).storage(); + Real * Ydq = this->Yd_rand(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; - MaterialMarigo::computeStress(F, sigma, *dam, *Yt, *Ydq); + MaterialMarigo::computeStress(F, sigma, *dam, *Yt, *Ydq); ++dam; ++Yt; ++Ydq; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMarigoNonLocal::computeNonLocalStress(GhostType ghost_type) { +template +void MaterialMarigoNonLocal::computeNonLocalStress(GhostType ghost_type) { AKANTU_DEBUG_IN(); - ByElementTypeReal Ynl("Y non local", id); - initInternalVector(Ynl, 1); - resizeInternalVector(Ynl); + ByElementTypeReal Ynl("Y non local", this->id); + this->initInternalVector(Ynl, 1); + this->resizeInternalVector(Ynl); - weightedAvergageOnNeighbours(Y, Ynl, 1); + this->weightedAvergageOnNeighbours(Y, Ynl, 1); - UInt spatial_dimension = model->getSpatialDimension(); - - Mesh::type_iterator it = model->getFEM().getMesh().firstType(spatial_dimension, ghost_type); - Mesh::type_iterator last_type = model->getFEM().getMesh().lastType(spatial_dimension, ghost_type); + Mesh::type_iterator it = this->model->getFEM().getMesh().firstType(spatial_dimension, ghost_type); + Mesh::type_iterator last_type = this->model->getFEM().getMesh().lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { computeNonLocalStress(Ynl(*it, ghost_type), *it, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMarigoNonLocal::computeNonLocalStress(Vector & Ynl, - ElementType el_type, - GhostType ghost_type) { +template +void MaterialMarigoNonLocal::computeNonLocalStress(Vector & Ynl, + ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); - UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(el_type, ghost_type); - UInt nb_element = element_filter(el_type, ghost_type).getSize(); + UInt nb_quadrature_points = this->model->getFEM().getNbQuadraturePoints(el_type, ghost_type); + UInt nb_element = this->element_filter(el_type, ghost_type).getSize(); if (nb_element == 0) return; Vector::iterator stress_it = - stress(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); + this->stress(el_type, ghost_type).begin(spatial_dimension, spatial_dimension); - Real * dam = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); Real * Ynlt = Ynl.storage(); - Real * Ydq = Yd_rand(el_type, ghost_type).storage(); + Real * Ydq = this->Yd_rand(el_type, ghost_type).storage(); Real sigma[3*3]; for (UInt el = 0; el < nb_element; ++el) { for (UInt q = 0; q < nb_quadrature_points; ++q) { for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) { sigma[3 * i + j] = (*stress_it)(i, j); } - computeDamageAndStress(sigma, *dam, *Ynlt, *Ydq); + this->computeDamageAndStress(sigma, *dam, *Ynlt, *Ydq); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) (*stress_it)(i, j) = sigma[3 * i + j]; ++stress_it; ++dam; ++Ynlt; ++Ydq; } } - updateDissipatedEnergy(ghost_type); + this->updateDissipatedEnergy(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialMarigoNonLocal::setParam(const std::string & key, const std::string & value, - const ID & id) { +template +bool MaterialMarigoNonLocal::setParam(const std::string & key, const std::string & value, + const ID & id) { return MaterialNonLocalParent::setParam(key, value, id) || - MaterialMarigo::setParam(key, value, id); + MaterialMarigo::setParam(key, value, id); } /* -------------------------------------------------------------------------- */ -void MaterialMarigoNonLocal::printself(std::ostream & stream, int indent) const { +template +void MaterialMarigoNonLocal::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_marigo_non_local> [" << std::endl; - MaterialMarigo::printself(stream, indent + 1); + MaterialMarigo::printself(stream, indent + 1); MaterialNonLocalParent::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialMarigoNonLocal); + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_marigo_non_local.hh b/src/model/solid_mechanics/materials/material_marigo_non_local.hh index 66c9e94bc..feb0e30fd 100644 --- a/src/model/solid_mechanics/materials/material_marigo_non_local.hh +++ b/src/model/solid_mechanics/materials/material_marigo_non_local.hh @@ -1,115 +1,107 @@ /** * @file material_marigo_non_local.hh * @author Marion Chambart * @author Nicolas Richart * @date Wed Aug 31 17:08:23 2011 * * @brief * * @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_common.hh" #include "material_marigo.hh" #include "material_non_local.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__ #define __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ - /** * Material Marigo * * parameters in the material files : */ -typedef BaseWeightFunction MarigoNonLocalWeightFunction; -class MaterialMarigoNonLocal : public MaterialMarigo, - public MaterialNonLocal { +template +class MaterialMarigoNonLocal : public MaterialMarigo, + public MaterialNonLocal { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - typedef MaterialNonLocal MaterialNonLocalParent; + typedef MaterialNonLocal MaterialNonLocalParent; - MaterialMarigoNonLocal(Model & model, const ID & id = ""); + MaterialMarigoNonLocal(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialMarigoNonLocal() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// constitutive law virtual void computeNonLocalStress(GhostType ghost_type = _not_ghost); virtual void computeNonLocalStress(Vector & damage, ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; private: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Y, Y, Real); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: ByElementTypeReal Y; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_marigo_non_local_inline_impl.cc" -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialMarigoNonLocal & _this) -{ - _this.printself(stream); - return stream; -} __END_AKANTU__ #endif /* __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_mazars.cc b/src/model/solid_mechanics/materials/material_mazars.cc index 67a52a04d..e3e648d9f 100644 --- a/src/model/solid_mechanics/materials/material_mazars.cc +++ b/src/model/solid_mechanics/materials/material_mazars.cc @@ -1,123 +1,134 @@ /** * @file material_mazars.cc * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the damage material * * @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 "material_mazars.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialMazars::MaterialMazars(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), MaterialDamage(model, id) { +template +MaterialMazars::MaterialMazars(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), + MaterialElastic(model, id), + MaterialDamage(model, id) { AKANTU_DEBUG_IN(); K0 = 1e-4; At = 0.8; Ac = 1.4; Bc = 1900; Bt = 12000; beta = 1.06; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMazars::initMaterial() { +template +void MaterialMazars::initMaterial() { AKANTU_DEBUG_IN(); - MaterialDamage::initMaterial(); - - is_init = true; + MaterialDamage::initMaterial(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMazars::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialMazars::computeStress(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; - Real * dam = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; Real Ehat; computeStress(F, sigma, *dam, Ehat); ++dam; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; - if(!is_non_local) updateDissipatedEnergy(ghost_type); + if(!this->is_non_local) this->updateDissipatedEnergy(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialMazars::setParam(const std::string & key, const std::string & value, - const ID & id) { +template +bool MaterialMazars::setParam(const std::string & key, + const std::string & value, + const ID & id) { std::stringstream sstr(value); if(key == "K0") { sstr >> K0; } else if(key == "At") { sstr >> At; } else if(key == "Bt") { sstr >> Bt; } else if(key == "Ac") { sstr >> Ac; } else if(key == "Bc") { sstr >> Bc; } else if(key == "beta") { sstr >> beta; } - else { return MaterialDamage::setParam(key, value, id); } + else { return MaterialDamage::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialMazars::printself(std::ostream & stream, int indent) const { +template +void MaterialMazars::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_mazars> [" << std::endl; stream << space << " + K0 : " << K0 << std::endl; stream << space << " + At : " << At << std::endl; stream << space << " + Bt : " << Bt << std::endl; stream << space << " + Ac : " << Ac << std::endl; stream << space << " + Bc : " << Bc << std::endl; stream << space << " + beta : " << beta << std::endl; - MaterialDamage::printself(stream, indent + 1); + MaterialDamage::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialMazars); + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_mazars.hh b/src/model/solid_mechanics/materials/material_mazars.hh index 545068d0f..501a009ae 100644 --- a/src/model/solid_mechanics/materials/material_mazars.hh +++ b/src/model/solid_mechanics/materials/material_mazars.hh @@ -1,127 +1,118 @@ /** * @file material_mazars.hh * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Thu Jul 29 15:00:59 2010 * * @brief Material Following the Mazars law for damage evolution * * @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_common.hh" #include "material_damage.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_MAZARS_HH__ #define __AKANTU_MATERIAL_MAZARS_HH__ __BEGIN_AKANTU__ /** * Material Mazars * * parameters in the material files : * - rho : density (default: 0) * - E : Young's modulus (default: 0) * - nu : Poisson's ratio (default: 1/2) * - K0 : Damage threshold * - At : Parameter damage traction 1 * - Bt : Parameter damage traction 2 * - Ac : Parameter damage compression 1 * - Bc : Parameter damage compression 2 * - beta : Parameter for shear */ -class MaterialMazars : public MaterialDamage { +template +class MaterialMazars : public MaterialDamage { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialMazars(Model & model, const ID & id = ""); + MaterialMazars(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialMazars() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma,Real & damage, Real & Ehat); inline void computeDamageAndStress( Real *F, Real * sigma,Real & damage, Real & Ehat); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// damage threshold Real K0; ///parameter damage traction 1 Real At ; ///parameter damage traction 2 Real Bt ; ///parameter damage compression 1 Real Ac ; ///parameter damage compression 2 Real Bc ; ///parameter for shear Real beta ; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "material_mazars_inline_impl.cc" -#endif - -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialMazars & _this) -{ - _this.printself(stream); - return stream; -} +#include "material_mazars_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MATERIAL_MAZARS_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_mazars_inline_impl.cc b/src/model/solid_mechanics/materials/material_mazars_inline_impl.cc index 102b661e1..ecc927f66 100644 --- a/src/model/solid_mechanics/materials/material_mazars_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_mazars_inline_impl.cc @@ -1,167 +1,173 @@ /** * @file material_mazars_inline_impl.cc * @author Nicolas Richart * @author Marion Chambart * @date Tue Jul 27 11:57:43 2010 * * @brief Implementation of the inline functions of the material damage * * @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 . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -inline void MaterialMazars::computeStress(Real * F, Real * sigma, Real & dam, Real & Ehat) { +template +inline void MaterialMazars::computeStress(Real * F, + Real * sigma, + Real & dam, + Real & Ehat) { Real Fdiag[3]; Real Fdiagp[3]; Math::matrix33_eigenvalues(F, Fdiag); Fdiagp[0] = std::max(0., Fdiag[0]); Fdiagp[1] = std::max(0., Fdiag[1]); Fdiagp[2] = std::max(0., Fdiag[2]); Ehat = sqrt(Fdiagp[0]*Fdiagp[0] + Fdiagp[1]*Fdiagp[1] + Fdiagp[2]*Fdiagp[2]); - MaterialElastic::computeStress(F, sigma); + MaterialElastic::computeStress(F, sigma); -#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE +#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE Real Fs = Ehat - K0; if (Fs > 0.) { Real damt; Real damc; damt = 1 - K0*(1 - At)/Ehat - At*(exp(-Bt*(Ehat - K0))); damc = 1 - K0*(1 - Ac)/Ehat - Ac*(exp(-Bc*(Ehat - K0))); Real Cdiag; Cdiag = E*(1-nu)/((1+nu)*(1-2*nu)); Real SigDiag[3]; SigDiag[0] = Cdiag*Fdiag[0] + lambda*(Fdiag[1] + Fdiag[2]); SigDiag[1] = Cdiag*Fdiag[1] + lambda*(Fdiag[0] + Fdiag[2]); SigDiag[2] = Cdiag*Fdiag[2] + lambda*(Fdiag[1] + Fdiag[0]); Real SigDiagT[3]; for (UInt i = 0; i < 3; i++) { if(SigDiag[i] >= 0.) { SigDiagT[i] = SigDiag[i]; } else { SigDiagT[i] = 0.; } } Real TraSigT; TraSigT = SigDiagT[0] + SigDiagT[1] + SigDiagT[2]; Real FDiagT[3]; for (UInt i = 0; i < 3; i++){ FDiagT [i]= (SigDiagT[i]*(1 + nu) - TraSigT*nu)/E; } Real alphat; alphat = (FDiagT[0]*Fdiagp[0] + FDiagT[1]*Fdiagp[1] + FDiagT[2]*Fdiagp[2])/(Ehat*Ehat); alphat = std::min(alphat, 1.); Real alphac; alphac = 1 - alphat; Real damtemp; damtemp = pow(alphat,beta)*damt + pow(alphac,beta)*damc; dam = std::max(damtemp, dam); } dam = std::min(dam,1.); #endif // AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE - if(!is_non_local) { + if(!this->is_non_local) { computeDamageAndStress(F,sigma, dam, Ehat); } } -#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE -inline void MaterialMazars::computeDamageAndStress(__attribute__((unused)) Real *F, - Real * sigma, Real & dam, - __attribute__((unused)) Real & Ehat) { +#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE +template +inline void MaterialMazars::computeDamageAndStress(__attribute__((unused)) Real *F, + Real * sigma, Real & dam, + __attribute__((unused)) Real & Ehat) { #else -inline void MaterialMazars::computeDamageAndStress(Real *F, - Real * sigma, Real & dam, - Real & Ehat) { +template +inline void MaterialMazars::computeDamageAndStress(Real *F, + Real * sigma, Real & dam, + Real & Ehat) { Real Fdiag[3]; Real Fdiagp[3]; Math::matrix33_eigenvalues(F, Fdiag); Fdiagp[0] = std::max(0., Fdiag[0]); Fdiagp[1] = std::max(0., Fdiag[1]); Fdiagp[2] = std::max(0., Fdiag[2]); Real Fs = Ehat - K0; if (Fs > 0.) { Real damt; Real damc; damt = 1 - K0*(1 - At)/Ehat - At*(exp(-Bt*(Ehat - K0))); damc = 1 - K0*(1 - Ac)/Ehat - Ac*(exp(-Bc*(Ehat - K0))); Real Cdiag; - Cdiag = E*(1-nu)/((1+nu)*(1-2*nu)); - + Cdiag = this->E*(1 - this->nu)/((1 + this->nu)*(1-2*this->nu)); + Real SigDiag[3]; - SigDiag[0] = Cdiag*Fdiag[0] + lambda*(Fdiag[1] + Fdiag[2]); - SigDiag[1] = Cdiag*Fdiag[1] + lambda*(Fdiag[0] + Fdiag[2]); - SigDiag[2] = Cdiag*Fdiag[2] + lambda*(Fdiag[1] + Fdiag[0]); + SigDiag[0] = Cdiag*Fdiag[0] + this->lambda*(Fdiag[1] + Fdiag[2]); + SigDiag[1] = Cdiag*Fdiag[1] + this->lambda*(Fdiag[0] + Fdiag[2]); + SigDiag[2] = Cdiag*Fdiag[2] + this->lambda*(Fdiag[1] + Fdiag[0]); Real SigDiagT[3]; for (UInt i = 0; i < 3; i++) { if(SigDiag[i] >= 0.) { SigDiagT[i] = SigDiag[i]; } else { SigDiagT[i] = 0.; } } Real TraSigT; TraSigT = SigDiagT[0] + SigDiagT[1] + SigDiagT[2]; Real FDiagT[3]; for (UInt i = 0; i < 3; i++){ - FDiagT [i]= (SigDiagT[i]*(1 + nu) - TraSigT*nu)/E; + FDiagT [i]= (SigDiagT[i]*(1 + this->nu) - TraSigT*this->nu)/this->E; } Real alphat; alphat = (FDiagT[0]*Fdiagp[0] + FDiagT[1]*Fdiagp[1] + FDiagT[2]*Fdiagp[2])/(Ehat*Ehat); alphat = std::min(alphat, 1.); Real alphac; alphac = 1 - alphat; Real damtemp; damtemp = pow(alphat,beta)*damt + pow(alphac,beta)*damc; dam = std::max(damtemp, dam); } dam = std::min(dam,1.); -#endif // AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE +#endif // AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE for(UInt i = 0; i < 9; ++i) sigma[i] *= 1 - dam; } diff --git a/src/model/solid_mechanics/materials/material_mazars_non_local.cc b/src/model/solid_mechanics/materials/material_mazars_non_local.cc index 01a5a349c..42cb6b4fc 100644 --- a/src/model/solid_mechanics/materials/material_mazars_non_local.cc +++ b/src/model/solid_mechanics/materials/material_mazars_non_local.cc @@ -1,184 +1,192 @@ /** * @file material_mazars_non_local.cc * @author Nicolas Richart * @author Marion Chambart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the non-local mazars material * * @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 "material_mazars_non_local.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialMazarsNonLocal::MaterialMazarsNonLocal(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), - MaterialMazars(model, id), MaterialNonLocalParent(model, id), +template +MaterialMazarsNonLocal::MaterialMazarsNonLocal(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), + MaterialElastic(model, id), + MaterialMazars(model, id), + MaterialNonLocalParent(model, id), Ehat("Ehat", id) { AKANTU_DEBUG_IN(); - - is_non_local = true; - - initInternalVector(this->Ehat, 1); - + this->is_non_local = true; + this->initInternalVector(this->Ehat, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMazarsNonLocal::initMaterial() { +template +void MaterialMazarsNonLocal::initMaterial() { AKANTU_DEBUG_IN(); - MaterialMazars::initMaterial(); - + MaterialMazars::initMaterial(); MaterialNonLocalParent::initMaterial(); - - resizeInternalVector(this->Ehat); - - is_init = true; - + this->resizeInternalVector(this->Ehat); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMazarsNonLocal::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialMazarsNonLocal::computeStress(ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; - Real * dam = damage(el_type, ghost_type).storage(); - Real * Ehatt = Ehat(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); + Real * Ehatt = this->Ehat(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; - MaterialMazars::computeStress(F, sigma, *dam, *Ehatt); + MaterialMazars::computeStress(F, sigma, *dam, *Ehatt); ++dam; ++Ehatt; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMazarsNonLocal::computeNonLocalStress(GhostType ghost_type) { +template +void MaterialMazarsNonLocal::computeNonLocalStress(GhostType ghost_type) { AKANTU_DEBUG_IN(); - ByElementTypeReal nl_var("Non local variable", id); - initInternalVector(nl_var, 1); - resizeInternalVector(nl_var); + ByElementTypeReal nl_var("Non local variable", this->id); + this->initInternalVector(nl_var, 1); + this->resizeInternalVector(nl_var); -#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE - weightedAvergageOnNeighbours(damage, nl_var, 1); +#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE + this->weightedAvergageOnNeighbours(damage, nl_var, 1); #else - weightedAvergageOnNeighbours(Ehat, nl_var, 1); + this->weightedAvergageOnNeighbours(Ehat, nl_var, 1); #endif - UInt spatial_dimension = model->getSpatialDimension(); - - Mesh::type_iterator it = model->getFEM().getMesh().firstType(spatial_dimension, ghost_type); - Mesh::type_iterator last_type = model->getFEM().getMesh().lastType(spatial_dimension, ghost_type); + Mesh::type_iterator it = this->model->getFEM().getMesh().firstType(spatial_dimension, ghost_type); + Mesh::type_iterator last_type = this->model->getFEM().getMesh().lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { - computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type); + this->computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialMazarsNonLocal::computeNonLocalStress(Vector & non_loc_var, ElementType el_type, GhostType ghost_type) { +template +void MaterialMazarsNonLocal::computeNonLocalStress(Vector & non_loc_var, + ElementType el_type, + GhostType ghost_type) { AKANTU_DEBUG_IN(); -#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE - Real * Ehatt = Ehat(el_type, ghost_type).storage(); +#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE + Real * Ehatt = this->Ehat(el_type, ghost_type).storage(); #else - Real * dam = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); #endif Real * nl_var = non_loc_var.storage(); Real sigma[3*3]; Real F[3*3] ; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) { F[3*i + j] = strain_val[spatial_dimension * i + j]; sigma[3 * i + j] = stress_val[spatial_dimension*i + j]; } -#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE - computeDamageAndStress(F, sigma, *nl_var, *Ehatt); +#ifdef AKANTU_MAZARS_NON_LOCAL_AVERAGE_DAMAGE + this->computeDamageAndStress(F, sigma, *nl_var, *Ehatt); ++Ehatt; #else - computeDamageAndStress(F, sigma, *dam, *nl_var); + this->computeDamageAndStress(F, sigma, *dam, *nl_var); ++dam; #endif ++nl_var; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; - updateDissipatedEnergy(ghost_type); + this->updateDissipatedEnergy(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialMazarsNonLocal::setParam(const std::string & key, const std::string & value, - const ID & id) { +template +bool MaterialMazarsNonLocal::setParam(const std::string & key, + const std::string & value, + const ID & id) { return MaterialNonLocalParent::setParam(key, value, id) || - MaterialMazars::setParam(key, value, id); + MaterialMazars::setParam(key, value, id); } /* -------------------------------------------------------------------------- */ -void MaterialMazarsNonLocal::printself(std::ostream & stream, int indent) const { +template +void MaterialMazarsNonLocal::printself(std::ostream & stream, + int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_mazars_non_local> [" << std::endl; - MaterialMazars::printself(stream, indent + 1); + MaterialMazars::printself(stream, indent + 1); MaterialNonLocalParent::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialMazarsNonLocal); + + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_mazars_non_local.hh b/src/model/solid_mechanics/materials/material_mazars_non_local.hh index 2f1b996c3..bc48cf4de 100644 --- a/src/model/solid_mechanics/materials/material_mazars_non_local.hh +++ b/src/model/solid_mechanics/materials/material_mazars_non_local.hh @@ -1,117 +1,111 @@ /** * @file material_mazars_non_local.hh * @author * @date Wed Aug 31 17:08:23 2011 * * @brief * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__ #define __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__ __BEGIN_AKANTU__ /** * Material Mazars Non local * * parameters in the material files : */ -class MaterialMazarsNonLocal : public MaterialMazars, public MaterialNonLocal { +template +class MaterialMazarsNonLocal : public MaterialMazars, + public MaterialNonLocal { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - typedef MaterialNonLocal MaterialNonLocalParent; + typedef MaterialNonLocal MaterialNonLocalParent; - MaterialMazarsNonLocal(Model & model, const ID & id = ""); + MaterialMazarsNonLocal(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialMazarsNonLocal() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// constitutive law virtual void computeNonLocalStress(GhostType ghost_type = _not_ghost); virtual void computeNonLocalStress(Vector & Ehatnl, ElementType el_type, GhostType ghost_type = _not_ghost); /// Compute the tangent stiffness matrix for implicit for a given type void computeTangentStiffness(__attribute__ ((unused)) const ElementType & type, __attribute__ ((unused)) Vector & tangent_matrix, __attribute__ ((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); }; inline Real getStableTimeStep(Real h, const Element & element) { - return MaterialMazars::getStableTimeStep(h, element); + return MaterialMazars::getStableTimeStep(h, element); }; /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: ByElementTypeReal Ehat; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_mazars_non_local_inline_impl.cc" -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialMazarsNonLocal & _this) -{ - _this.printself(stream); - return stream; -} - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_neohookean.cc b/src/model/solid_mechanics/materials/material_neohookean.cc index 11c89bf7e..73b6e4406 100644 --- a/src/model/solid_mechanics/materials/material_neohookean.cc +++ b/src/model/solid_mechanics/materials/material_neohookean.cc @@ -1,230 +1,231 @@ /** * @file material_neohookean.cc * @author Nicolas Richart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the elastic material * * @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 "material_neohookean.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialNeohookean::MaterialNeohookean(Model & model, const ID & id) : +template +MaterialNeohookean::MaterialNeohookean(SolidMechanicsModel & model, + const ID & id) : Material(model, id) { AKANTU_DEBUG_IN(); rho = 0; E = 0; nu = 1./2.; plane_stress = false; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialNeohookean::initMaterial() { +template +void MaterialNeohookean::initMaterial() { AKANTU_DEBUG_IN(); Material::initMaterial(); lambda = nu * E / ((1 + nu) * (1 - 2*nu)); mu = E / (2 * (1 + nu)); if(plane_stress) lambda = 2 * lambda * mu / (lambda + 2 * mu); kpa = lambda + 2./3. * mu; - is_init = true; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialNeohookean::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialNeohookean::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; for (UInt i = 0; i < spatial_dimension; ++i) F[i*3 + i] += 1; //F is now the real F !! computeStress(F, sigma); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialNeohookean::computePotentialEnergy(ElementType el_type, GhostType ghost_type) { +template +void MaterialNeohookean::computePotentialEnergy(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); if(ghost_type != _not_ghost) return; Real * epot = potential_energy(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; computePotentialEnergy(strain_val, epot); epot++; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -void MaterialNeohookean::computeTangentStiffnessByDim(ElementType el_type, - Vector& tangent_matrix, - GhostType ghost_type) { +template +void MaterialNeohookean::computeTangentStiffness(const ElementType & el_type, + Vector & tangent_matrix, + GhostType ghost_type) { +// switch(spatial_dimension) { +// case 1: { computeTangentStiffnessByDim<1>(el_type, tangent_matrix, ghost_type); break; } +// case 2: { computeTangentStiffnessByDim<2>(el_type, tangent_matrix, ghost_type); break; } +// case 3: { computeTangentStiffnessByDim<3>(el_type, tangent_matrix, ghost_type); break; } +// } +// } + + +// /* -------------------------------------------------------------------------- */ +// template +// void MaterialNeohookean::computeTangentStiffnessByDim(ElementType el_type, +// Vector& tangent_matrix, +// GhostType ghost_type) { AKANTU_DEBUG_IN(); tangent_matrix.clear(); Real F[3*3]; MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix); memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; for (UInt i = 0; i < spatial_dimension; ++i) F[i*3 + i] += 1; //F is now the real F !! - computeTangentStiffness(tangent_val, F); + computeTangentStiffness(tangent_val, F); MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -Real MaterialNeohookean::celerity(const Element & elem) { +template +Real MaterialNeohookean::celerity(const Element & elem) { UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(elem.type, elem.ghost_type); UInt size_strain = spatial_dimension * spatial_dimension; Real * strain_val = strain(elem.type, elem.ghost_type).storage() + elem.element * nb_quadrature_points * size_strain; Real F[3*3]; Real C[3*3], Cinv[3*3]; Real cele = 0.; for (UInt q = 0; q < nb_quadrature_points; ++q) { std::fill_n(F, 3*3, 0.); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j] + (i == j); Math::matMul(3, 3, 3, 1., F, F, 0., C); Math::inv3(C, Cinv); Real detC = Math::det3(C); Real defvol = .5 * log(detC); Real p = lambda * defvol; Real traceCinv = Cinv[0] + Cinv[4] + Cinv[8]; Real coef = mu - p; Real rhot = rho/sqrt(detC); Real tmpcele = sqrt((lambda + 2*coef)*traceCinv*traceCinv/rhot); cele = std::max(cele, tmpcele); strain_val += size_strain; } return cele; } /* -------------------------------------------------------------------------- */ -bool MaterialNeohookean::setParam(const std::string & key, const std::string & value, +template +bool MaterialNeohookean::setParam(const std::string & key, const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "E") { sstr >> E; } else if(key == "nu") { sstr >> nu; } else if(key == "Plane_Stress") { sstr >> plane_stress; } else { return Material::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialNeohookean::printself(std::ostream & stream, int indent) const { +template +void MaterialNeohookean::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "MaterialNeohookean [" << std::endl; if(!plane_stress) stream << space << " + Plane strain" << std::endl; else stream << space << " + Plane stress" << std::endl; stream << space << " + id : " << id << std::endl; stream << space << " + name : " << name << std::endl; stream << space << " + density : " << rho << std::endl; stream << space << " + Young's modulus : " << E << std::endl; stream << space << " + Poisson's ratio : " << nu << std::endl; - if(is_init) { + if(this->isInit()) { stream << space << " + First Lamé coefficient : " << lambda << std::endl; stream << space << " + Second Lamé coefficient : " << mu << std::endl; stream << space << " + Bulk coefficient : " << kpa << std::endl; } stream << space << "]" << std::endl; } -/* -------------------------------------------------------------------------- */ -template -void MaterialNeohookean::computeTangentStiffnessByDim<1>(akantu::ElementType el_type, - akantu::Vector& tangent_matrix, - akantu::GhostType ghost_type); -template -void MaterialNeohookean::computeTangentStiffnessByDim<2>(akantu::ElementType el_type, - akantu::Vector& tangent_matrix, - akantu::GhostType ghost_type); -template -void MaterialNeohookean::computeTangentStiffnessByDim<3>(akantu::ElementType el_type, - akantu::Vector& tangent_matrix, - akantu::GhostType ghost_type); /* -------------------------------------------------------------------------- */ -void MaterialNeohookean::computeTangentStiffness(const ElementType & el_type, - Vector & tangent_matrix, - GhostType ghost_type) { - switch(spatial_dimension) { - case 1: { computeTangentStiffnessByDim<1>(el_type, tangent_matrix, ghost_type); break; } - case 2: { computeTangentStiffnessByDim<2>(el_type, tangent_matrix, ghost_type); break; } - case 3: { computeTangentStiffnessByDim<3>(el_type, tangent_matrix, ghost_type); break; } - } -} + +INSTANSIATE_MATERIAL(MaterialNeohookean); + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_neohookean.hh b/src/model/solid_mechanics/materials/material_neohookean.hh index aa57aa068..4175cf6d8 100644 --- a/src/model/solid_mechanics/materials/material_neohookean.hh +++ b/src/model/solid_mechanics/materials/material_neohookean.hh @@ -1,148 +1,136 @@ /** * @file material_neohookean.hh * @author Nicolas Richart * @date Thu Jul 29 15:00:59 2010 * * @brief Material Neo Hookean * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_NEOHOOKEAN_HH__ #define __AKANTU_MATERIAL_NEOHOOKEAN_HH__ __BEGIN_AKANTU__ /** * Material elastic isotropic * * parameters in the material files : * - rho : density (default: 0) * - E : Young's modulus (default: 0) * - nu : Poisson's ratio (default: 1/2) * - Plain_Stress : if 0: plain strain, else: plain stress (default: 0) */ +template class MaterialNeohookean : public Material { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialNeohookean(Model & model, const ID & id = ""); + MaterialNeohookean(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialNeohookean() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// compute the tangent stiffness matrix for an element type void computeTangentStiffness(const ElementType & el_type, Vector & tangent_matrix, GhostType ghost_type = _not_ghost); /// compute the potential energy for all elements virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; private: /// compute the celerity of wave in the material Real celerity(const Element & element); /// compute the potential energy for on element inline void computePotentialEnergy(Real * F, Real * epot); protected: /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma); - // /// compute the tangent stiffness matrix for an element type - template - void computeTangentStiffnessByDim(akantu::ElementType, akantu::Vector& tangent_matrix, akantu::GhostType); - // /// compute the tangent stiffness matrix for an element - template void computeTangentStiffness(Real * tangent, Real * F); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// get the stable time step inline Real getStableTimeStep(Real h, const Element & element); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// the young modulus Real E; /// Poisson coefficient Real nu; /// First Lamé coefficient Real lambda; /// Second Lamé coefficient (shear modulus) Real mu; /// Bulk modulus Real kpa; /// Plain stress or plain strain bool plane_stress; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "material_neohookean_inline_impl.cc" -#endif +#include "material_neohookean_inline_impl.cc" + -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialNeohookean & _this) -{ - _this.printself(stream); - return stream; -} __END_AKANTU__ #endif /* __AKANTU_MATERIAL_NEOHOOKEAN_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_neohookean_inline_impl.cc b/src/model/solid_mechanics/materials/material_neohookean_inline_impl.cc index c40e9c818..501a5b121 100644 --- a/src/model/solid_mechanics/materials/material_neohookean_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_neohookean_inline_impl.cc @@ -1,127 +1,132 @@ /** * @file material_neohookean_inline_impl.cc * @author Marion Chambart * @date Tue Jul 27 11:57:43 2010 * * @brief Implementation of the inline functions of the material neohookean * * @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_math.hh" /* -------------------------------------------------------------------------- */ -inline void MaterialNeohookean::computeStress(Real * F, Real * sigma) { +template +inline void MaterialNeohookean::computeStress(Real * F, Real * sigma) { ///First compute the Left Cauchy-Green deformation tensor : C= F^tF. Real C[3*3]; Math::matMul(3,3,3,1.,F,F,0.,C); ///Compute determinant of C Real detC; detC = Math::det3(C); Real defvol ; defvol= 0.5*log(detC); Real p; p = lambda * defvol; // Real traceC; // traceC = C[0]+C[4]+C[8]; Real Cinv[3*3]; Math::inv3(C, Cinv); Real coef = p - mu; Real S[3*3]; for(UInt i=0; i < 3*3; i++){ S[i] = coef*Cinv[i]; } S[0] = S[0] + mu; S[4] = S[4] + mu; S[8] = S[8] + mu; Math::matrix_matrix(3, 3,3, F, S, sigma, 1.); } /* -------------------------------------------------------------------------- */ template -void MaterialNeohookean::computeTangentStiffness(Real * tangent, Real * F ) { +void MaterialNeohookean::computeTangentStiffness(Real * tangent, + Real * F ) { UInt n = (dim * (dim - 1) / 2 + dim); Real J = Math::det3(F); Real alpha = mu - 0.5*lambda*(J*J - 1); Real Miiii = 2*mu+lambda; Real Miijj = lambda*J*J; Real Mijij = alpha; tangent[0 * n + 0] = Miiii; // test of dimension should by optimized out by the compiler due to the template if(dim >= 2) { tangent[1 * n + 1] = Miiii; tangent[0 * n + 1] = Miijj; tangent[1 * n + 0] = Miijj; tangent[(n - 1) * n + (n - 1)] = Mijij; } if(dim == 3) { tangent[2 * n + 2] = Miiii; tangent[0 * n + 2] = Miijj; tangent[1 * n + 2] = Miijj; tangent[2 * n + 0] = Miijj; tangent[2 * n + 1] = Miijj; tangent[3 * n + 3] = Mijij; tangent[4 * n + 4] = Mijij; } } /* -------------------------------------------------------------------------- */ -inline void MaterialNeohookean::computePotentialEnergy(Real * F, Real * epot) { +template +inline void MaterialNeohookean::computePotentialEnergy(Real * F, + Real * epot) { *epot = 0.; Real C[3*3]; Math::matMul(3,3,3,1.,F,F,0.,C); ///Compute determinant of C Real detC; detC = Math::det3(C); Real defvol ; defvol = 0.5*log(detC); Real p; p = lambda*defvol; Real traceC; traceC = C[0] + C[4] + C[8]; /// potential energy *epot = (0.5*p - mu)*defvol + 0.5*mu*(traceC - 3.); } /* -------------------------------------------------------------------------- */ -inline Real MaterialNeohookean::getStableTimeStep(Real h, - const Element & element) { +template +inline Real MaterialNeohookean::getStableTimeStep(Real h, + const Element & element) { return (h/celerity(element)); } diff --git a/src/model/solid_mechanics/materials/material_non_local.hh b/src/model/solid_mechanics/materials/material_non_local.hh index 681f0a9cd..ca6253afb 100644 --- a/src/model/solid_mechanics/materials/material_non_local.hh +++ b/src/model/solid_mechanics/materials/material_non_local.hh @@ -1,158 +1,148 @@ /** * @file material_non_local.hh * @author Nicolas Richart * @date Thu Jul 28 11:17:41 2011 * * @brief Material class that handle the non locality of a law for example damage. * * @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_common.hh" #include "material.hh" #include "aka_grid.hh" #include "fem.hh" #include "weight_function.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_NON_LOCAL_HH__ #define __AKANTU_MATERIAL_NON_LOCAL_HH__ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -template +template class WeightFunction = BaseWeightFunction> class MaterialNonLocal : public virtual Material { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialNonLocal(Model & model, const ID & id = ""); + MaterialNonLocal(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialNonLocal(); template class PairList : public ByElementType > {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// read properties virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// initialize the material computed parameter virtual void initMaterial(); void updatePairList(const ByElementTypeReal & quadrature_points_coordinates); void computeWeights(const ByElementTypeReal & quadrature_points_coordinates); // void computeQuadraturePointsNeighborhoudVolumes(ByElementTypeReal & volumes) const; template void weightedAvergageOnNeighbours(const ByElementTypeVector & to_accumulate, ByElementTypeVector & accumulated, UInt nb_degree_of_freedom) const; /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; virtual void updateResidual(Vector & displacement, GhostType ghost_type); /// constitutive law virtual void computeNonLocalStress(GhostType ghost_type = _not_ghost) = 0; // void removeDamaged(const ByElementTypeReal & damage, Real thresold); void savePairs(const std::string & filename) const; void neighbourhoodStatistics(const std::string & filename) const; protected: void createCellList(const ByElementTypeReal & quadrature_points_coordinates); // template // void accumulateOnNeighbours(const ByElementTypeVector & to_accumulate, // ByElementTypeVector & accumulated, // UInt nb_degree_of_freedom) const; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO(PairList, pair_list, const PairList &) AKANTU_GET_MACRO(Radius, radius, Real); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// the non local radius Real radius; /// the weight function used - WeightFunction * weight_func; + WeightFunction * weight_func; private: /// the pairs of quadrature points PairList pair_list; /// the weights associated to the pairs PairList pair_weight; /// the regular grid to construct/update the pair lists RegularGrid * cell_list; /// the types of the existing pairs std::set< std::pair > existing_pairs; /// specify if the weights should be updated and at which rate UInt update_weigths; /// count the number of calls of computeStress UInt compute_stress_calls; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "material_non_local_inline_impl.cc" -#endif - -/// standard output stream operator -template -inline std::ostream & operator <<(std::ostream & stream, const MaterialNonLocal & _this) -{ - _this.printself(stream); - return stream; -} +#include "material_non_local_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MATERIAL_NON_LOCAL_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc b/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc index c34530e09..8ffcb6b90 100644 --- a/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_non_local_inline_impl.cc @@ -1,548 +1,549 @@ /** * @file material_non_local_inline_impl.cc * @author Nicolas Richart * @date Thu Aug 25 11:59:39 2011 * * @brief * * @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 . * */ /* -------------------------------------------------------------------------- */ __END_AKANTU__ /* -------------------------------------------------------------------------- */ #include "aka_types.hh" #include "grid_synchronizer.hh" #include "synchronizer_registry.hh" /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -template -MaterialNonLocal::MaterialNonLocal(Model & model, const ID & id) : +template class WeightFunction> +MaterialNonLocal::MaterialNonLocal(SolidMechanicsModel & model, + const ID & id) : Material(model, id), weight_func(NULL), cell_list(NULL), update_weigths(0), compute_stress_calls(0) { AKANTU_DEBUG_IN(); - is_non_local = true; + this->is_non_local = true; - this->weight_func = new WeightFunction(*this); + this->weight_func = new WeightFunction(*this); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -MaterialNonLocal::~MaterialNonLocal() { +template class WeightFunction> +MaterialNonLocal::~MaterialNonLocal() { AKANTU_DEBUG_IN(); delete cell_list; delete weight_func; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::initMaterial() { +template class WeightFunction> +void MaterialNonLocal::initMaterial() { AKANTU_DEBUG_IN(); // Material::initMaterial(); ByElementTypeReal quadrature_points_coordinates("quadrature_points_coordinates_tmp_nl", id); computeQuadraturePointsCoordinates(quadrature_points_coordinates); weight_func->setRadius(radius); weight_func->init(); createCellList(quadrature_points_coordinates); updatePairList(quadrature_points_coordinates); computeWeights(quadrature_points_coordinates); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::updateResidual(Vector & displacement, GhostType ghost_type) { +template class WeightFunction> +void MaterialNonLocal::updateResidual(Vector & displacement, GhostType ghost_type) { AKANTU_DEBUG_IN(); // Update the weights for the non local variable averaging if(ghost_type == _not_ghost && this->update_weigths && (this->compute_stress_calls % this->update_weigths == 0)) { ByElementTypeReal quadrature_points_coordinates("quadrature_points_coordinates", id); computeQuadraturePointsCoordinates(quadrature_points_coordinates); computeWeights(quadrature_points_coordinates); } if(ghost_type == _not_ghost) ++this->compute_stress_calls; computeStress(displacement, ghost_type); computeNonLocalStress(ghost_type); assembleResidual(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template +template class WeightFunction> template -void MaterialNonLocal::weightedAvergageOnNeighbours(const ByElementTypeVector & to_accumulate, +void MaterialNonLocal::weightedAvergageOnNeighbours(const ByElementTypeVector & to_accumulate, ByElementTypeVector & accumulated, UInt nb_degree_of_freedom) const { AKANTU_DEBUG_IN(); std::set< std::pair >::const_iterator first_pair_types = existing_pairs.begin(); std::set< std::pair >::const_iterator last_pair_types = existing_pairs.end(); GhostType ghost_type1, ghost_type2; ghost_type1 = ghost_type2 = _not_ghost; for (; first_pair_types != last_pair_types; ++first_pair_types) { const Vector & pairs = pair_list(first_pair_types->first, ghost_type1)(first_pair_types->second, ghost_type2); const Vector & weights = pair_weight(first_pair_types->first, ghost_type1)(first_pair_types->second, ghost_type2); const Vector & to_acc = to_accumulate(first_pair_types->second, ghost_type2); Vector & acc = accumulated(first_pair_types->first, ghost_type1); acc.resize(to_acc.getSize()); acc.clear(); Vector::const_iterator< types::Vector > first_pair = pairs.begin(2); Vector::const_iterator< types::Vector > last_pair = pairs.end(2); Vector::const_iterator< types::Vector > pair_w = weights.begin(2); for(;first_pair != last_pair; ++first_pair, ++pair_w) { UInt q1 = (*first_pair)(0); UInt q2 = (*first_pair)(1); for(UInt d = 0; d < nb_degree_of_freedom; ++d){ acc(q1, d) += (*pair_w)(0) * to_acc(q2, d); acc(q2, d) += (*pair_w)(1) * to_acc(q1, d); } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::createCellList(const ByElementTypeReal & quadrature_points_coordinates) { +template class WeightFunction> +void MaterialNonLocal::createCellList(const ByElementTypeReal & quadrature_points_coordinates) { AKANTU_DEBUG_IN(); const Real safety_factor = 1.2; // for the cell grid spacing Mesh & mesh = this->model->getFEM().getMesh(); mesh.computeBoundingBox(); Real lower_bounds[spatial_dimension]; Real upper_bounds[spatial_dimension]; mesh.getLocalLowerBounds(lower_bounds); mesh.getLocalUpperBounds(upper_bounds); Real spacing[spatial_dimension]; for (UInt i = 0; i < spatial_dimension; ++i) { spacing[i] = radius * safety_factor; } cell_list = new RegularGrid(spatial_dimension, lower_bounds, upper_bounds, spacing); GhostType ghost_type = _not_ghost; Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type); // first generate the quad points coordinate and count the number of points per cell for(; it != last_type; ++it) { const Vector & quads = quadrature_points_coordinates(*it, ghost_type); Vector::const_iterator first_quad, last_quad; first_quad = quads.begin(spatial_dimension); last_quad = quads.end(spatial_dimension); for(;first_quad != last_quad; ++first_quad) { cell_list->count(*first_quad); } } QuadraturePoint q; q.ghost_type = ghost_type; // second insert the point in the cells cell_list->beginInsertions(); it = mesh.firstType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { Vector & elem_filter = element_filter(*it, ghost_type); UInt nb_element = elem_filter.getSize(); UInt nb_quad = this->model->getFEM().getNbQuadraturePoints(*it, ghost_type); const Vector & quads = quadrature_points_coordinates(*it, ghost_type); q.type = *it; Vector::const_iterator quad = quads.begin(spatial_dimension); UInt * elem = elem_filter.storage(); for (UInt e = 0; e < nb_element; ++e) { q.element = *elem; for (UInt nq = 0; nq < nb_quad; ++nq) { q.num_point = nq; q.setPosition(*quad); cell_list->insert(q, *quad); ++quad; } ++elem; } } cell_list->endInsertions(); SynchronizerRegistry & synch_registry = this->model->getSynchronizerRegistry(); std::stringstream sstr; sstr << id << ":grid_synchronizer"; GridSynchronizer * synch = GridSynchronizer::createGridSynchronizer(mesh, *cell_list, sstr.str()); synch_registry.registerSynchronizer(*synch, _gst_mnl_damage); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::updatePairList(const ByElementTypeReal & quadrature_points_coordinates) { +template class WeightFunction> +void MaterialNonLocal::updatePairList(const ByElementTypeReal & quadrature_points_coordinates) { AKANTU_DEBUG_IN(); Mesh & mesh = this->model->getFEM().getMesh(); GhostType ghost_type = _not_ghost; // generate the pair of neighbor depending of the cell_list Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { // Preparing datas const Vector & quads = quadrature_points_coordinates(*it, ghost_type); Vector::const_iterator first_quad = quads.begin(spatial_dimension); Vector::const_iterator last_quad = quads.end(spatial_dimension); ByElementTypeUInt & pairs = pair_list(ByElementTypeUInt("pairs", id, memory_id), *it, ghost_type); ElementType current_element_type = _not_defined; GhostType current_ghost_type = _casper; //Real * neigh_quad_positions = NULL; Vector * neighbors = NULL; UInt my_num_quad = 0; // loop over quad points for(;first_quad != last_quad; ++first_quad, ++my_num_quad) { RegularGrid::Cell cell = cell_list->getCell(*first_quad); RegularGrid::neighbor_cells_iterator first_neigh_cell = cell_list->beginNeighborCells(cell); RegularGrid::neighbor_cells_iterator last_neigh_cell = cell_list->endNeighborCells(cell); // loop over neighbor cells of the one containing the current quadrature // point for (; first_neigh_cell != last_neigh_cell; ++first_neigh_cell) { RegularGrid::iterator first_neigh_quad = cell_list->beginCell(*first_neigh_cell); RegularGrid::iterator last_neigh_quad = cell_list->endCell(*first_neigh_cell); // loop over the quadrature point in the current cell of the cell list for (;first_neigh_quad != last_neigh_quad; ++first_neigh_quad){ QuadraturePoint & quad = *first_neigh_quad; UInt nb_quad_per_elem = this->model->getFEM().getNbQuadraturePoints(quad.type, quad.ghost_type); UInt neigh_num_quad = quad.element * nb_quad_per_elem + quad.num_point; // little optimization to not search in the map at each quad points if(quad.type != current_element_type || quad.ghost_type != current_ghost_type) { // neigh_quad_positions = quadrature_points_coordinates(quad.type, // quad.ghost_type).storage(); current_element_type = quad.type; current_ghost_type = quad.ghost_type; if(!pairs.exists(current_element_type, current_ghost_type)) { neighbors = &(pairs.alloc(0, 2, current_element_type, current_ghost_type)); } else { neighbors = &(pairs(current_element_type, current_ghost_type)); } existing_pairs.insert(std::pair(*it, current_element_type)); } // types::RVector neigh_quad(neigh_quad_positions + neigh_num_quad * spatial_dimension, // spatial_dimension); const types::RVector & neigh_quad = quad.getPosition(); Real distance = first_quad->distance(neigh_quad); if(distance <= radius && my_num_quad <= neigh_num_quad) { // sotring only half lists UInt pair[2]; pair[0] = my_num_quad; pair[1] = neigh_num_quad; neighbors->push_back(pair); } // } } } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::computeWeights(const ByElementTypeReal & quadrature_points_coordinates) { +template class WeightFunction> +void MaterialNonLocal::computeWeights(const ByElementTypeReal & quadrature_points_coordinates) { AKANTU_DEBUG_IN(); std::set< std::pair >::iterator first_pair_types; std::set< std::pair >::iterator last_pair_types = existing_pairs.end(); GhostType ghost_type1, ghost_type2; ghost_type1 = ghost_type2 = _not_ghost; ByElementTypeReal quadrature_points_volumes("quadrature_points_volumes", id, memory_id); this->model->getFEM().getMesh().initByElementTypeVector(quadrature_points_volumes, 1, 0); weight_func->updateInternals(quadrature_points_volumes); // Compute the weights first_pair_types = existing_pairs.begin(); for (; first_pair_types != last_pair_types; ++first_pair_types) { ElementType type1 = first_pair_types->first; ElementType type2 = first_pair_types->second; const Vector & pairs = pair_list(type1, ghost_type1)(type2, ghost_type2); ByElementTypeReal & weights_type_1 = pair_weight(type1, ghost_type1); Vector * tmp_weight = NULL; if(!weights_type_1.exists(type2, ghost_type2)) { tmp_weight = &(weights_type_1.alloc(0, 2, type2, ghost_type2)); } else { tmp_weight = &(weights_type_1(type2, ghost_type2)); } Vector & weights = *tmp_weight; weights.resize(pairs.getSize()); weights.clear(); const Vector & elem_filter = element_filter(type1, ghost_type1); UInt nb_quad1 = this->model->getFEM().getNbQuadraturePoints(type1); UInt nb_quad2 = this->model->getFEM().getNbQuadraturePoints(type2); UInt nb_tot_quad = nb_quad1 * elem_filter.getSize();; Vector & quads_volumes = quadrature_points_volumes(type1, ghost_type1); quads_volumes.resize(nb_tot_quad); quads_volumes.clear(); Vector::const_iterator iquads1; Vector::const_iterator iquads2; iquads1 = quadrature_points_coordinates(type1, ghost_type1).begin(spatial_dimension); iquads2 = quadrature_points_coordinates(type2, ghost_type2).begin(spatial_dimension); Vector::const_iterator< types::Vector > first_pair = pairs.begin(2); Vector::const_iterator< types::Vector > last_pair = pairs.end(2); Vector::iterator weight = weights.begin(2); this->weight_func->selectType(type1, ghost_type1, type2, ghost_type2); // Weight function for(;first_pair != last_pair; ++first_pair, ++weight) { UInt _q1 = (*first_pair)(0); UInt _q2 = (*first_pair)(1); const types::RVector & pos1 = iquads1[_q1]; const types::RVector & pos2 = iquads2[_q2]; QuadraturePoint q1(_q1 / nb_quad1, _q1 % nb_quad1, _q1, pos1, type1, ghost_type1); QuadraturePoint q2(_q2 / nb_quad2, _q2 % nb_quad2, _q2, pos2, type2, ghost_type2); Real r = pos1.distance(pos2); (*weight)(0) = this->weight_func->operator()(r, q1, q2); if(_q1 != _q2) (*weight)(1) = this->weight_func->operator()(r, q2, q1); else (*weight)(1) = 0; quads_volumes(_q1) += (*weight)(0); quads_volumes(_q2) += (*weight)(1); } } //normalize the weights first_pair_types = existing_pairs.begin(); for (; first_pair_types != last_pair_types; ++first_pair_types) { ElementType type1 = first_pair_types->first; ElementType type2 = first_pair_types->second; const Vector & pairs = pair_list(type1, ghost_type1)(type2, ghost_type2); Vector & weights = pair_weight(type1, ghost_type1)(type2, ghost_type2); Vector & quads_volumes = quadrature_points_volumes(type1, ghost_type1); Vector::const_iterator< types::Vector > first_pair = pairs.begin(2); Vector::const_iterator< types::Vector > last_pair = pairs.end(2); Vector::iterator weight = weights.begin(2); for(;first_pair != last_pair; ++first_pair, ++weight) { UInt q1 = (*first_pair)(0); UInt q2 = (*first_pair)(1); (*weight)(0) *= 1. / quads_volumes(q1); (*weight)(1) *= 1. / quads_volumes(q2); } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template -bool MaterialNonLocal::setParam(const std::string & key, const std::string & value, +template class WeightFunction> +bool MaterialNonLocal::setParam(const std::string & key, const std::string & value, __attribute__((unused)) const ID & id) { std::stringstream sstr(value); if(key == "radius") { sstr >> radius; } else if(key == "UpdateWeights") { sstr >> update_weigths; } else if(!weight_func->setParam(key, value)) return false; return true; } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::savePairs(const std::string & filename) const { +template class WeightFunction> +void MaterialNonLocal::savePairs(const std::string & filename) const { std::ofstream pout; pout.open(filename.c_str()); std::set< std::pair >::const_iterator first_pair_types = existing_pairs.begin(); std::set< std::pair >::const_iterator last_pair_types = existing_pairs.end(); GhostType ghost_type1, ghost_type2; ghost_type1 = ghost_type2 = _not_ghost; for (; first_pair_types != last_pair_types; ++first_pair_types) { const Vector & pairs = pair_list(first_pair_types->first, ghost_type1)(first_pair_types->second, ghost_type2); const Vector & weights = pair_weight(first_pair_types->first, ghost_type1)(first_pair_types->second, ghost_type2); pout << "Types : " << first_pair_types->first << " " << first_pair_types->second << std::endl; Vector::const_iterator< types::Vector > first_pair = pairs.begin(2); Vector::const_iterator< types::Vector > last_pair = pairs.end(2); Vector::const_iterator pair_w = weights.begin(2); for(;first_pair != last_pair; ++first_pair, ++pair_w) { UInt q1 = (*first_pair)(0); UInt q2 = (*first_pair)(1); pout << q1 << " " << q2 << " "<< (*pair_w)(0) << " " << (*pair_w)(1) << std::endl; } } } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::neighbourhoodStatistics(const std::string & filename) const { +template class WeightFunction> +void MaterialNonLocal::neighbourhoodStatistics(const std::string & filename) const { std::ofstream pout; pout.open(filename.c_str()); std::set< std::pair >::const_iterator first_pair_types = existing_pairs.begin(); std::set< std::pair >::const_iterator last_pair_types = existing_pairs.end(); const Mesh & mesh = this->model->getFEM().getMesh(); ByElementTypeUInt nb_neighbors("nb_neighbours", id, memory_id); initInternalVector(nb_neighbors, 1); resizeInternalVector(nb_neighbors); GhostType ghost_type1, ghost_type2; ghost_type1 = ghost_type2 = _not_ghost; for (; first_pair_types != last_pair_types; ++first_pair_types) { const Vector & pairs = pair_list(first_pair_types->first, ghost_type1)(first_pair_types->second, ghost_type2); pout << "Types : " << first_pair_types->first << " " << first_pair_types->second << std::endl; Vector::const_iterator< types::Vector > first_pair = pairs.begin(2); Vector::const_iterator< types::Vector > last_pair = pairs.end(2); Vector & nb_neigh_1 = nb_neighbors(first_pair_types->first, ghost_type1); Vector & nb_neigh_2 = nb_neighbors(first_pair_types->second, ghost_type2); for(;first_pair != last_pair; ++first_pair) { UInt q1 = (*first_pair)(0); UInt q2 = (*first_pair)(1); ++(nb_neigh_1(q1)); if(q1 != q2) ++(nb_neigh_2(q2)); } } Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type1); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type1); UInt nb_quads = 0; Real mean_nb_neig = 0; UInt max_nb_neig = 0; UInt min_nb_neig = std::numeric_limits::max(); for(; it != last_type; ++it) { Vector & nb_neighor = nb_neighbors(*it, ghost_type1); Vector::iterator nb_neigh = nb_neighor.begin(); Vector::iterator end_neigh = nb_neighor.end(); for (; nb_neigh != end_neigh; ++nb_neigh, ++nb_quads) { UInt nb = *nb_neigh; mean_nb_neig += nb; max_nb_neig = std::max(max_nb_neig, nb); min_nb_neig = std::min(min_nb_neig, nb); } } mean_nb_neig /= Real(nb_quads); pout << "Nb quadrature points: " << nb_quads << std::endl; pout << "Average nb neighbors: " << mean_nb_neig << std::endl; pout << "Max nb neighbors: " << max_nb_neig << std::endl; pout << "Min nb neighbors: " << min_nb_neig << std::endl; pout.close(); } /* -------------------------------------------------------------------------- */ -template -void MaterialNonLocal::printself(std::ostream & stream, int indent) const { +template class WeightFunction> +void MaterialNonLocal::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_non_local> [" << std::endl; stream << space << " + Radius : " << radius << std::endl; stream << space << " + UpdateWeights : " << update_weigths << std::endl; stream << space << " + Weight Function : " << *weight_func << std::endl; stream << space << "]" << std::endl; } diff --git a/src/model/solid_mechanics/materials/material_viscoelastic.cc b/src/model/solid_mechanics/materials/material_viscoelastic.cc index 9bb5bf8eb..b82f8d926 100644 --- a/src/model/solid_mechanics/materials/material_viscoelastic.cc +++ b/src/model/solid_mechanics/materials/material_viscoelastic.cc @@ -1,158 +1,164 @@ /** * @file material_viscoelastic.hh * @author Vlad Yastrebov * @date Thu Feb 7 2012 * * @brief Material Visco-elastic * * @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 "material_viscoelastic.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialViscoElastic::MaterialViscoElastic(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), +template +MaterialViscoElastic::MaterialViscoElastic(SolidMechanicsModel & model, const ID & id) : + Material(model, id), MaterialElastic(model, id), stress_dev("stress_dev", id), history_integral("history_integral", id) { AKANTU_DEBUG_IN(); eta = 1.; Ev = 1.; UInt stress_size = spatial_dimension * spatial_dimension; initInternalVector(this->stress_dev, stress_size); initInternalVector(this->history_integral, stress_size); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialViscoElastic::initMaterial() { +template +void MaterialViscoElastic::initMaterial() { AKANTU_DEBUG_IN(); - MaterialElastic::initMaterial(); + MaterialElastic::initMaterial(); resizeInternalVector(this->stress_dev); resizeInternalVector(this->history_integral); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialViscoElastic::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialViscoElastic::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Real tau = eta / Ev; - Real K = E / ( 3 * (1 - 2*nu) ); // kpa ? + Real K = this->E / ( 3 * (1 - 2*this->nu) ); // kpa ? Vector & stress_dev_vect = stress_dev(el_type, ghost_type); Vector & history_int_vect = history_integral(el_type, ghost_type); Vector::iterator stress_d = stress_dev_vect.begin(spatial_dimension, spatial_dimension); Vector::iterator history_int = history_int_vect.begin(spatial_dimension, spatial_dimension); types::Matrix e(spatial_dimension, spatial_dimension); types::Matrix s(spatial_dimension, spatial_dimension); types::Matrix theta_sp(spatial_dimension, spatial_dimension); - Real dt = model->getTimeStep(); + Real dt = this->model->getTimeStep(); Real exp_dt_thau = exp( -dt/tau ); Real exp_dt_thau_2 = exp( -.5*dt/tau ); /// Loop on all quadrature points MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; types::Matrix sigma(stress_val, spatial_dimension, spatial_dimension); types::Matrix F(strain_val, spatial_dimension, spatial_dimension); e.clear(); s.clear(); sigma.clear(); /// Compute the first invariant of strain Real Theta = F.trace(); theta_sp.eye(1/double(spatial_dimension) * Theta); /// Compute the deviator of strain @f$ @f$ for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) { e(i, j) = F(i, j) - theta_sp(i, j); - s(i, j) = E / (1 + nu) * e(i, j); + s(i, j) = this->E / (1 + this->nu) * e(i, j); } /// Update the internal variable for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) (*history_int)(i, j) = exp_dt_thau * (*history_int)(i, j) + exp_dt_thau_2 * (s(i, j) - (*stress_d)(i, j)); // Real alpha = 2./3. * K * Theta; Real alpha = K * Theta; - Real beta = 1. / ( Ev + E ); + Real beta = 1. / ( Ev + this->E ); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) - sigma(i, j) = (i == j) * alpha + beta * (E * s(i, j) + Ev * (*history_int)(i, j)); + sigma(i, j) = (i == j) * alpha + beta * (this->E * s(i, j) + Ev * (*history_int)(i, j)); /// Save the deviator of stress stress_d->copy(s); ++stress_d; ++history_int; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialViscoElastic::setParam(const std::string & key, const std::string & value, +template +bool MaterialViscoElastic::setParam(const std::string & key, const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "eta") { sstr >> eta; } else if(key == "Ev") { sstr >> Ev; } - else { return MaterialElastic::setParam(key, value, id); } + else { return MaterialElastic::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialViscoElastic::printself(std::ostream & stream, int indent) const { +template +void MaterialViscoElastic::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "MaterialViscoElastic [" << std::endl; - MaterialElastic::printself(stream, indent + 1); + MaterialElastic::printself(stream, indent + 1); stream << space << " + Eta : " << eta << std::endl; stream << space << " + Ev : " << Ev << std::endl; stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialViscoElastic); __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_viscoelastic.hh b/src/model/solid_mechanics/materials/material_viscoelastic.hh index b51c9d1c3..a9f3b2423 100644 --- a/src/model/solid_mechanics/materials/material_viscoelastic.hh +++ b/src/model/solid_mechanics/materials/material_viscoelastic.hh @@ -1,132 +1,132 @@ /** * @file material_viscoelastic.hh - * @author Vlad Yastrebov - * @date Thu Feb 7 2012 + * @author Vlad Yastrebov + * @date Thu Feb 7 2012 * * @brief Material Visco-elastic, based on Standard Solid rheological model, see [] J.C. Simo, T.J.R. Hughes, "Computational Inelasticity", Springer (1998), see Sections 10.2 and 10.3 * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_VISCOELASTIC_HH__ #define __AKANTU_MATERIAL_VISCOELASTIC_HH__ __BEGIN_AKANTU__ /** * Material viscoelastic (caughey condition) isotropic * * parameters in the material files : * - rho : density (default: 0) * - E : Young's modulus (default: 0) * - nu : Poisson's ratio (default: 1/2) * - Plane_Stress : if 0: plane strain, else: plane stress (default: 0) * - eta : viscosity * - Ev : stiffness of the viscous element * - h : internal variable of the integral history */ -class MaterialViscoElastic : public MaterialElastic { +template +class MaterialViscoElastic : public MaterialElastic { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ - /* ------------------------------------------------------------------------ */ + /* ------------------------------------------------------------------------ */ public: - MaterialViscoElastic(Model & model, const ID & id = ""); + MaterialViscoElastic(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialViscoElastic() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point //__aka_inline__ void computeStress(Real * F, Real * sigma); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(HistoryIntegral, history_integral, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressDev, stress_dev, Real); - AKANTU_GET_MACRO(EV, Ev, const Real&); - AKANTU_SET_MACRO(EV, Ev, Real &); + AKANTU_GET_MACRO(EV, Ev, const Real&); + AKANTU_SET_MACRO(EV, Ev, Real &); - AKANTU_GET_MACRO(Eta, eta, const Real&); - AKANTU_SET_MACRO(Eta, eta, Real &); + AKANTU_GET_MACRO(Eta, eta, const Real&); + AKANTU_SET_MACRO(Eta, eta, Real &); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// stress due to viscosity // ByElementTypeReal stress_viscosity; /// stress due to elasticity // ByElementTypeReal stress_elastic; /// viscosity, viscous elastic modulus Real eta, Ev; /// history of deviatoric stress ByElementTypeReal stress_dev; /// Internal variable: history integral ByElementTypeReal history_integral; }; /* -------------------------------------------------------------------------- */ /* __aka_inline__ functions */ /* -------------------------------------------------------------------------- */ //#include "material_elastic_caughey_inline_impl.cc" /* -------------------------------------------------------------------------- */ /// standard output stream operator /* inline std::ostream & operator <<(std::ostream & stream, const MaterialViscoElastic & _this) { _this.printself(stream); return stream; } */ __END_AKANTU__ #endif /* __AKANTU_MATERIAL_VISCOELASTIC_HH__ */ - diff --git a/src/model/solid_mechanics/materials/material_vreepeerlings.cc b/src/model/solid_mechanics/materials/material_vreepeerlings.cc index 4c29d2058..abf7fbca6 100644 --- a/src/model/solid_mechanics/materials/material_vreepeerlings.cc +++ b/src/model/solid_mechanics/materials/material_vreepeerlings.cc @@ -1,211 +1,221 @@ /** * @file material_vreepeerlings.cc * @author Cyprien Wolff * @date Fri Feb 17 14:00:00 2012 * * @brief Specialization of the material class for the VreePeerlings material * * @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 "material_vreepeerlings.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialVreePeerlings::MaterialVreePeerlings(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), MaterialDamage(model, id), +template +MaterialVreePeerlings::MaterialVreePeerlings(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), + MaterialElastic(model, id), + MaterialDamage(model, id), Kapa("Kapa",id) { AKANTU_DEBUG_IN(); Kapa0 = 0.0001; Alpha = 0.99; Beta = 300.; Kct = 1.; - Kapa0_randomness = 0; - is_non_local = false; + Kapa0_randomness = 0.; - initInternalVector(this->Kapa, 1); + this->initInternalVector(this->Kapa, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlings::initMaterial() { +template +void MaterialVreePeerlings::initMaterial() { AKANTU_DEBUG_IN(); - MaterialDamage::initMaterial(); + MaterialDamage::initMaterial(); - resizeInternalVector(this->Kapa); + this->resizeInternalVector(this->Kapa); - const Mesh & mesh = model->getFEM().getMesh(); + const Mesh & mesh = this->model->getFEM().getMesh(); Mesh::type_iterator it = mesh.firstType(spatial_dimension); Mesh::type_iterator last_type = mesh.lastType(spatial_dimension); for(; it != last_type; ++it) { Vector ::iterator kapa_it = Kapa(*it).begin(); Vector ::iterator kapa_end = Kapa(*it).end(); for(; kapa_it != kapa_end; ++kapa_it) { Real rand_part = (2 * drand48()-1) * Kapa0_randomness * Kapa0; *kapa_it = Kapa0 + rand_part; } } - - is_init = true; - AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlings::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialVreePeerlings::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; - Real * dam = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); Real * Kapaq = Kapa(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; Real Equistrain; computeStress(F, sigma, *dam, Equistrain, *Kapaq); ++dam; ++Kapaq; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; - if(!is_non_local) updateDissipatedEnergy(ghost_type); + if(!this->is_non_local) this->updateDissipatedEnergy(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialVreePeerlings::setParam(const std::string & key, const std::string & value, +template +bool MaterialVreePeerlings::setParam(const std::string & key, const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "Kapa0") { sstr >> Kapa0; } else if(key == "Alpha") { sstr >> Alpha; } else if(key == "Beta") { sstr >> Beta; } else if(key == "Kct") { sstr >> Kct; } else if(key == "Kapa0_randomness") { sstr >> Kapa0_randomness; } - else { return MaterialDamage::setParam(key, value, id); } + else { return MaterialDamage::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlings::printself(std::ostream & stream, int indent) const { +template +void MaterialVreePeerlings::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_vreepeerlings> [" << std::endl; stream << space << " + Kapa0 : " << Kapa0 << std::endl; stream << space << " + Alpha : " << Alpha << std::endl; stream << space << " + Beta : " << Beta << std::endl; stream << space << " + Kct : " << Kct << std::endl; stream << space << " + Kapa0 randomness : " << Kapa0_randomness << std::endl; - MaterialDamage::printself(stream, indent + 1); + MaterialDamage::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ -UInt MaterialVreePeerlings::getNbDataToPack(const Element & element, +template +UInt MaterialVreePeerlings::getNbDataToPack(const Element & element, SynchronizationTag tag) const { AKANTU_DEBUG_IN(); UInt size = 0; if(tag == _gst_smm_init_mat) { - UInt nb_quad = model->getFEM().getNbQuadraturePoints(element.type); + UInt nb_quad = this->model->getFEM().getNbQuadraturePoints(element.type); size += sizeof(Real) + nb_quad; } - size += MaterialDamage::getNbDataToPack(element, tag); + size += MaterialDamage::getNbDataToPack(element, tag); AKANTU_DEBUG_OUT(); return size; } /* -------------------------------------------------------------------------- */ -UInt MaterialVreePeerlings::getNbDataToUnpack(const Element & element, +template +UInt MaterialVreePeerlings::getNbDataToUnpack(const Element & element, SynchronizationTag tag) const { AKANTU_DEBUG_IN(); UInt size = 0; if(tag == _gst_smm_init_mat) { - UInt nb_quad = model->getFEM().getNbQuadraturePoints(element.type); + UInt nb_quad = this->model->getFEM().getNbQuadraturePoints(element.type); size += sizeof(Real) + nb_quad; } - size += MaterialDamage::getNbDataToPack(element, tag); + size += MaterialDamage::getNbDataToPack(element, tag); AKANTU_DEBUG_OUT(); return size; } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlings::packData(CommunicationBuffer & buffer, +template +void MaterialVreePeerlings::packData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag) const { AKANTU_DEBUG_IN(); if(tag == _gst_smm_init_mat){ - UInt nb_quad = model->getFEM().getNbQuadraturePoints(element.type); + UInt nb_quad = this->model->getFEM().getNbQuadraturePoints(element.type); const Vector & kapa = Kapa(element.type, _not_ghost); for(UInt q = 0; q < nb_quad; ++q) buffer << kapa(element.element * nb_quad + q); } - MaterialDamage::packData(buffer, element, tag); - + MaterialDamage::packData(buffer, element, tag); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlings::unpackData(CommunicationBuffer & buffer, +template +void MaterialVreePeerlings::unpackData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag) { AKANTU_DEBUG_IN(); if(tag == _gst_smm_init_mat) { - UInt nb_quad = model->getFEM().getNbQuadraturePoints(element.type); + UInt nb_quad = this->model->getFEM().getNbQuadraturePoints(element.type); Vector & kapa = Kapa(element.type, _not_ghost); for(UInt q = 0; q < nb_quad; ++q) buffer >> kapa(element.element * nb_quad + q); } - - - MaterialDamage::packData(buffer, element, tag); + MaterialDamage::packData(buffer, element, tag); AKANTU_DEBUG_OUT(); } +/* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialVreePeerlings); + + + __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_vreepeerlings.hh b/src/model/solid_mechanics/materials/material_vreepeerlings.hh index 28776e0cc..1842ec2fd 100644 --- a/src/model/solid_mechanics/materials/material_vreepeerlings.hh +++ b/src/model/solid_mechanics/materials/material_vreepeerlings.hh @@ -1,145 +1,138 @@ /** * @file material_vreepeerlings.hh * @author Cyprien Wolff * @date Fri Feb 17 14:00:00 2012 * * @brief Specialization of the material class for the VreePeerlings material * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_VREEPEERLINGS_HH__ #define __AKANTU_MATERIAL_VREEPEERLINGS_HH__ __BEGIN_AKANTU__ /** * Material vreepeerlings * * parameters in the material files : * - Kapa0 : (default: 50) Initial threshold (of the equivalent strain) * - Alpha : (default: 0.99) Fitting parameter (must be close to 1 to do tend to 0 the stress in the damaged element) * - Beta : (default: 300) This parameter determines the rate at which the damage grows * - Kct : (default: 1) Ratio between compressive and tensile strength * - Kapa0_randomness : (default:0) Kapa random internal variable */ -class MaterialVreePeerlings : public MaterialDamage { +template +class MaterialVreePeerlings : public MaterialDamage { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - MaterialVreePeerlings(Model & model, const ID & id = ""); + MaterialVreePeerlings(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialVreePeerlings() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; protected: /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma, Real & dam, Real & Equistrain, Real & Kapaq); inline void computeDamageAndStress(Real * sigma, Real & dam, Real & Equistrain, Real & Kapaq); /* ------------------------------------------------------------------------ */ /* DataAccessor inherited members */ /* ------------------------------------------------------------------------ */ public: virtual UInt getNbDataToPack(const Element & element, SynchronizationTag tag) const; virtual UInt getNbDataToUnpack(const Element & element, SynchronizationTag tag) const; virtual void packData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag) const; virtual void unpackData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// Initial threshold (of the equivalent strain) Real Kapa0; /// Fitting parameter (must be close to 1 to do tend to 0 the stress in the damaged element) Real Alpha; /// This parameter determines the rate at which the damage grows Real Beta; /// Ratio between compressive and tensile strength Real Kct; /// randomness on Kapa0 Real Kapa0_randomness; /// Kapa random internal variable ByElementTypeReal Kapa; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "material_vreepeerlings_inline_impl.cc" -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialVreePeerlings & _this) -{ - _this.printself(stream); - return stream; -} - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_VREEPEERLINGS_HH__ */ diff --git a/src/model/solid_mechanics/materials/material_vreepeerlings_inline_impl.cc b/src/model/solid_mechanics/materials/material_vreepeerlings_inline_impl.cc index 7428ec73d..652126a96 100644 --- a/src/model/solid_mechanics/materials/material_vreepeerlings_inline_impl.cc +++ b/src/model/solid_mechanics/materials/material_vreepeerlings_inline_impl.cc @@ -1,85 +1,103 @@ /** * @file material_vreepeerlings_inline_impl.cc * @author Cyprien Wolff * @date Fri Feb 17 14:00:00 2012 * * @brief Specialization of the material class for the VreePeerlings material * * @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 . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -inline void MaterialVreePeerlings::computeStress(Real * F, Real * sigma, Real & dam, Real & Equistrain, Real &Kapaq) { +template +inline void MaterialVreePeerlings::computeStress(Real * F, + Real * sigma, + Real & dam, + Real & Equistrain, + Real & Kapaq) { types::Matrix Ft(F, 3, 3); Real I1=0.; Real J2=0.; - if(plane_stress) { - I1 = (Ft(0,0)+Ft(1,1))*(1-2*nu)/(1-nu); - J2 = (3*(Ft(0,0)*Ft(0,0)+Ft(1,1)*Ft(1,1)+(nu/(nu-1)*(Ft(0,0)+Ft(1,1)))*(nu/(nu-1)*(Ft(0,0)+Ft(1,1)))+(Ft(0,1)+Ft(1,0))*(Ft(0,1)+Ft(1,0))/2.+(Ft(1,2)+Ft(2,1))*(Ft(1,2)+Ft(2,1))/2.+(Ft(2,0)+Ft(0,2))*(Ft(2,0)+Ft(0,2))/2.)-I1*I1)/6; + if(this->plane_stress) { + I1 = (Ft(0,0) + Ft(1,1))*(1 - 2*this->nu)/(1 - this->nu); + Real tmp = this->nu/(this->nu - 1); + tmp *= tmp; + J2 = .5*(Ft(0,0)*Ft(0,0) + + Ft(1,1)*Ft(1,1) + + tmp*(Ft(0,0) + Ft(1,1))*(Ft(0,0) + Ft(1,1)) + + .5*(Ft(0,1) + Ft(1,0))*(Ft(0,1) + Ft(1,0))) - + I1*I1/6.; } else { I1 = Ft.trace(); - J2 = (3*(Ft(0,0)*Ft(0,0)+Ft(1,1)*Ft(1,1)+Ft(2,2)*Ft(2,2)+(Ft(0,1)+Ft(1,0))*(Ft(0,1)+Ft(1,0))/2.+(Ft(1,2)+Ft(2,1))*(Ft(1,2)+Ft(2,1))/2.+(Ft(2,0)+Ft(0,2))*(Ft(2,0)+Ft(0,2))/2.)-I1*I1)/6; + J2 = .5*(Ft(0,0)*Ft(0,0) + + Ft(1,1)*Ft(1,1) + + Ft(2,2)*Ft(2,2) + + .5*(Ft(0,1) + Ft(1,0))*(Ft(0,1) + Ft(1,0)) + + .5*(Ft(1,2) + Ft(2,1))*(Ft(1,2) + Ft(2,1)) + + .5*(Ft(2,0) + Ft(0,2))*(Ft(2,0) + Ft(0,2))) - + I1 * I1/6.; } - Equistrain = ((Kct-1)*I1)/(2*Kct*(1-2*nu))+((1)/(2*Kct))*sqrt((((Kct-1)*I1)/(1-2*nu))*(((Kct-1)*I1)/(1-2*nu))+(12*Kct*J2)/((1+nu)*(1+nu))); + Real tmp = (Kct - 1)*I1/(1 - 2*this->nu); + Real nu1 = (1 + this->nu); + Equistrain = tmp / (2*Kct) + 1./(2*Kct) * sqrt(tmp * tmp + (12 * Kct * J2)/(nu1 * nu1)); - MaterialElastic::computeStress(F, sigma); + MaterialElastic::computeStress(F, sigma); - - if(!is_non_local) { + if(!this->is_non_local) { computeDamageAndStress(sigma, dam, Equistrain, Kapaq); } } /* -------------------------------------------------------------------------- */ -inline void MaterialVreePeerlings::computeDamageAndStress(Real * sigma, Real & dam, Real & Equistrain, Real &Kapaq) { - - - -Real Fd = Equistrain - Kapaq; +template +inline void MaterialVreePeerlings::computeDamageAndStress(Real * sigma, + Real & dam, + Real & Equistrain, + Real & Kapaq) { + Real Fd = Equistrain - Kapaq; if (Fd > 0) { Kapaq = std::max(Equistrain,Kapaq); - //dam = 1.-(Kapa0/Kapaq)*((1-Alpha)+Alpha*exp(-Beta*(Kapaq-Kapa0))); - dam = 1.-(Kapa0/Kapaq)*((Alpha-Kapaq)/(Alpha-Kapa0)); - + //dam = 1. - Kapa0/Kapaq*((1 - Alpha) + Alpha*exp(-Beta*(Kapaq - Kapa0))); + dam = 1. - Kapa0/Kapaq * ((Alpha-Kapaq)/(Alpha - Kapa0)); dam = std::min(dam,1.); } sigma[0] *= 1-dam; sigma[4] *= 1-dam; sigma[8] *= 1-dam; sigma[1] *= 1-dam; sigma[3] *= 1-dam; sigma[2] *= 1-dam; sigma[6] *= 1-dam; sigma[5] *= 1-dam; sigma[7] *= 1-dam; } /* -------------------------------------------------------------------------- */ diff --git a/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.cc b/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.cc index 38121a38d..a52e5f4db 100644 --- a/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.cc +++ b/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.cc @@ -1,172 +1,178 @@ /** * @file material_vreepeerlings_non_local.cc * @author Nicolas Richart * @author Cyprien Wolff * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the non-local Vree-Peerlings material * * @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 "material_vreepeerlings_non_local.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -MaterialVreePeerlingsNonLocal::MaterialVreePeerlingsNonLocal(Model & model, const ID & id) : - Material(model, id), MaterialElastic(model, id), - MaterialVreePeerlings(model, id), MaterialNonLocalParent(model, id), +template +MaterialVreePeerlingsNonLocal::MaterialVreePeerlingsNonLocal(SolidMechanicsModel & model, + const ID & id) : + Material(model, id), + MaterialElastic(model, id), + MaterialVreePeerlings(model, id), + MaterialNonLocalParent(model, id), equi_strain("equi_strain", id) { AKANTU_DEBUG_IN(); - is_non_local = true; + this->is_non_local = true; - initInternalVector(this->equi_strain, 1); + this->initInternalVector(this->equi_strain, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlingsNonLocal::initMaterial() { +template +void MaterialVreePeerlingsNonLocal::initMaterial() { AKANTU_DEBUG_IN(); - MaterialVreePeerlings::initMaterial(); - + MaterialVreePeerlings::initMaterial(); MaterialNonLocalParent::initMaterial(); - resizeInternalVector(this->equi_strain); - - is_init = true; + this->resizeInternalVector(this->equi_strain); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlingsNonLocal::computeStress(ElementType el_type, GhostType ghost_type) { +template +void MaterialVreePeerlingsNonLocal::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; - Real * dam = damage(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); Real * equi_straint = equi_strain(el_type, ghost_type).storage(); - Real * Kapaq = Kapa(el_type, ghost_type).storage(); + Real * Kapaq = this->Kapa(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; - MaterialVreePeerlings::computeStress(F, sigma, *dam, *equi_straint, *Kapaq); + MaterialVreePeerlings::computeStress(F, sigma, *dam, *equi_straint, *Kapaq); ++dam; ++equi_straint; ++Kapaq; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlingsNonLocal::computeNonLocalStress(GhostType ghost_type) { +template +void MaterialVreePeerlingsNonLocal::computeNonLocalStress(GhostType ghost_type) { AKANTU_DEBUG_IN(); - ByElementTypeReal nl_var("Non local variable", id); - initInternalVector(nl_var, 1); - resizeInternalVector(nl_var); - - weightedAvergageOnNeighbours(equi_strain, nl_var, 1); + ByElementTypeReal nl_var("Non local variable", this->id); + this->initInternalVector(nl_var, 1); + this->resizeInternalVector(nl_var); - UInt spatial_dimension = model->getSpatialDimension(); + this->weightedAvergageOnNeighbours(equi_strain, nl_var, 1); - Mesh::type_iterator it = model->getFEM().getMesh().firstType(spatial_dimension, ghost_type); - Mesh::type_iterator last_type = model->getFEM().getMesh().lastType(spatial_dimension, ghost_type); + Mesh::type_iterator it = this->model->getFEM().getMesh().firstType(spatial_dimension, ghost_type); + Mesh::type_iterator last_type = this->model->getFEM().getMesh().lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlingsNonLocal::computeNonLocalStress(Vector & non_loc_var, ElementType el_type, GhostType ghost_type) { +template +void MaterialVreePeerlingsNonLocal::computeNonLocalStress(Vector & non_loc_var, ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); - Real * dam = damage(el_type, ghost_type).storage(); - Real * Kapaq = Kapa(el_type, ghost_type).storage(); + Real * dam = this->damage(el_type, ghost_type).storage(); + Real * Kapaq = this->Kapa(el_type, ghost_type).storage(); Real * nl_var = non_loc_var.storage(); Real sigma[3*3]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) { sigma[3 * i + j] = stress_val[spatial_dimension*i + j]; } - computeDamageAndStress(sigma, *dam, *nl_var, *Kapaq); + this->computeDamageAndStress(sigma, *dam, *nl_var, *Kapaq); ++dam; ++Kapaq; ++nl_var; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; - updateDissipatedEnergy(ghost_type); + this->updateDissipatedEnergy(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -bool MaterialVreePeerlingsNonLocal::setParam(const std::string & key, const std::string & value, +template +bool MaterialVreePeerlingsNonLocal::setParam(const std::string & key, const std::string & value, const ID & id) { return MaterialNonLocalParent::setParam(key, value, id) || - MaterialVreePeerlings::setParam(key, value, id); + MaterialVreePeerlings::setParam(key, value, id); } /* -------------------------------------------------------------------------- */ -void MaterialVreePeerlingsNonLocal::printself(std::ostream & stream, int indent) const { +template +void MaterialVreePeerlingsNonLocal::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_vreepeerlings_non_local> [" << std::endl; - MaterialVreePeerlings::printself(stream, indent + 1); + MaterialVreePeerlings::printself(stream, indent + 1); MaterialNonLocalParent::printself(stream, indent + 1); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +INSTANSIATE_MATERIAL(MaterialVreePeerlingsNonLocal); __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.hh b/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.hh index b5cd97993..6188ea5ce 100644 --- a/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.hh +++ b/src/model/solid_mechanics/materials/material_vreepeerlings_non_local.hh @@ -1,119 +1,111 @@ /** * @file material_vreepeerlings_non_local.hh * @author Cyprien Wolff * @author Nicolas Richart * @date Fri Feb 24 16:01:10 2012 * * @brief * * @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_common.hh" #include "material_vreepeerlings.hh" #include "material_non_local.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_VREEPEERLINGS_NON_LOCAL_HH__ #define __AKANTU_MATERIAL_VREEPEERLINGS_NON_LOCAL_HH__ __BEGIN_AKANTU__ /** * Material VreePeerlings Non local * * parameters in the material files : */ -typedef BaseWeightFunction VreePeerlingsNonLocalWeightFunction; -class MaterialVreePeerlingsNonLocal : public MaterialVreePeerlings, - public MaterialNonLocal { +template +class MaterialVreePeerlingsNonLocal : public MaterialVreePeerlings, + public MaterialNonLocal { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - typedef MaterialNonLocal MaterialNonLocalParent; + typedef MaterialNonLocal MaterialNonLocalParent; - MaterialVreePeerlingsNonLocal(Model & model, const ID & id = ""); + MaterialVreePeerlingsNonLocal(SolidMechanicsModel & model, const ID & id = ""); virtual ~MaterialVreePeerlingsNonLocal() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); virtual bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// constitutive law virtual void computeNonLocalStress(GhostType ghost_type = _not_ghost); virtual void computeNonLocalStress(Vector & equi_strainnl, ElementType el_type, GhostType ghost_type = _not_ghost); /// Compute the tangent stiffness matrix for implicit for a given type void computeTangentStiffness(__attribute__ ((unused)) const ElementType & type, __attribute__ ((unused)) Vector & tangent_matrix, __attribute__ ((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); }; /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: ByElementTypeReal equi_strain; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ //#include "material_vreepeerlings_non_local_inline_impl.cc" -/* -------------------------------------------------------------------------- */ -/// standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, const MaterialVreePeerlingsNonLocal & _this) -{ - _this.printself(stream); - return stream; -} - __END_AKANTU__ #endif /* __AKANTU_MATERIAL_VREEPEERLINGS_NON_LOCAL_HH__ */ diff --git a/src/model/solid_mechanics/materials/weight_function.cc b/src/model/solid_mechanics/materials/weight_function.cc index 444c386e7..5716d34de 100644 --- a/src/model/solid_mechanics/materials/weight_function.cc +++ b/src/model/solid_mechanics/materials/weight_function.cc @@ -1,124 +1,35 @@ /** * @file weight_function.cc * @author Nicolas Richart * @date Fri Mar 23 15:55:58 2012 * * @brief implementation of the weight function classes * * @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 "weight_function.hh" __BEGIN_AKANTU__ -/* -------------------------------------------------------------------------- */ -/* Stress based weight function */ -/* -------------------------------------------------------------------------- */ -StressBasedWeightFunction::StressBasedWeightFunction(const Material & material) : - BaseWeightFunction(material), - ft(0.), - spatial_dimension(material.getModel().getSpatialDimension()), - stress_diag("stress_diag", material.getID()), selected_stress_diag(NULL), - stress_base("stress_base", material.getID()), selected_stress_base(NULL), - characteristic_size("lc", material.getID()), selected_characteristic_size(NULL) -{ - material.initInternalVector(stress_diag, spatial_dimension); - material.initInternalVector(stress_base, spatial_dimension * spatial_dimension); - material.initInternalVector(characteristic_size, 1); -} - -/* -------------------------------------------------------------------------- */ -void StressBasedWeightFunction::init() { - material.resizeInternalVector(stress_diag); - material.resizeInternalVector(stress_base); - material.resizeInternalVector(characteristic_size); - - const Mesh & mesh = material.getModel().getFEM().getMesh(); - for (UInt g = _not_ghost; g < _casper; ++g) { - GhostType gt = GhostType(g); - Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt); - Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt); - for(; it != last_type; ++it) { - UInt nb_quadrature_points = - material.getModel().getFEM().getNbQuadraturePoints(*it, gt); - const Vector & element_filter = material.getElementFilter(*it, gt); - UInt nb_element = element_filter.getSize(); - - Vector ones(nb_element*nb_quadrature_points, 1, 1.); - Vector & lc = characteristic_size(*it, gt); - material.getModel().getFEM().integrateOnQuadraturePoints(ones, - lc, - 1, - *it, - gt, - &element_filter); - - for (UInt q = 0; q < nb_quadrature_points * nb_element; q++) { - lc(q) = pow(lc(q), 1./ Real(spatial_dimension)); - } - } - } -} - - -/* -------------------------------------------------------------------------- */ -void StressBasedWeightFunction::updatePrincipalStress(GhostType ghost_type) { - AKANTU_DEBUG_IN(); - - const Mesh & mesh = material.getModel().getFEM().getMesh(); - - Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); - Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type); - for(; it != last_type; ++it) { - Vector::const_iterator sigma = - material.getStress(*it, ghost_type).begin(spatial_dimension, spatial_dimension); - Vector::iterator eigenvalues = - stress_diag(*it, ghost_type).begin(spatial_dimension); - Vector::iterator eigenvalues_end = - stress_diag(*it, ghost_type).end(spatial_dimension); - Vector::iterator eigenvector = - stress_base(*it, ghost_type).begin(spatial_dimension, spatial_dimension); - -#ifndef __trick__ - Vector::iterator cl = characteristic_size(*it, ghost_type).begin(); -#endif - UInt q = 0; - for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues, ++eigenvector, ++cl, ++q) { - // if (q == 4871) std::cout << "Sigma " << *sigma; - sigma->eig(*eigenvalues, *eigenvector); - // if (q == 17774) std::cout << "Before " << *eigenvalues; - *eigenvalues /= ft; -#ifndef __trick__ - // specify a lower bound for principal stress based on the size of the element - for (UInt i = 0; i < spatial_dimension; ++i) { - (*eigenvalues)(i) = std::max(*cl / R, (*eigenvalues)(i)); - } -#endif - // if (q == 17774) std::cout << "After " << *eigenvalues; - } - } - AKANTU_DEBUG_OUT(); -} - __END_AKANTU__ diff --git a/src/model/solid_mechanics/materials/weight_function.hh b/src/model/solid_mechanics/materials/weight_function.hh index 722518af0..bb71ad443 100644 --- a/src/model/solid_mechanics/materials/weight_function.hh +++ b/src/model/solid_mechanics/materials/weight_function.hh @@ -1,197 +1,203 @@ /** * @file weight_function.hh * @author Nicolas Richart * @date Thu Mar 8 16:17:00 2012 * * @brief Weight functions for non local materials * * @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_common.hh" #include "aka_types.hh" #include "solid_mechanics_model.hh" /* -------------------------------------------------------------------------- */ #include #ifndef __AKANTU_WEIGHT_FUNCTION_HH__ #define __AKANTU_WEIGHT_FUNCTION_HH__ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ +template class BaseWeightFunction { public: BaseWeightFunction(const Material & material) : material(material) {} virtual ~BaseWeightFunction() {} virtual void init() {}; virtual void updateInternals(__attribute__((unused)) const ByElementTypeReal & quadrature_points_coordinates) {}; /* ------------------------------------------------------------------------ */ inline void setRadius(Real radius) { R = radius; R2 = R * R; } /* ------------------------------------------------------------------------ */ inline void selectType(__attribute__((unused)) ElementType type1, __attribute__((unused)) GhostType ghost_type1, __attribute__((unused)) ElementType type2, __attribute__((unused)) GhostType ghost_type2) { } /* ------------------------------------------------------------------------ */ inline Real operator()(Real r, __attribute__((unused)) QuadraturePoint & q1, __attribute__((unused)) QuadraturePoint & q2) { Real w = 0; if(r <= R) { Real alpha = (1. - r*r / R2); w = alpha * alpha; // *weight = 1 - sqrt(r / radius); } return w; } /* ------------------------------------------------------------------------ */ bool setParam(__attribute__((unused)) const std::string & key, __attribute__((unused)) const std::string & value) { return false; } /* ------------------------------------------------------------------------ */ virtual void printself(std::ostream & stream) const { stream << "BaseWeightFunction"; } protected: const Material & material; Real R; Real R2; }; /* -------------------------------------------------------------------------- */ -class DamagedWeightFunction : public BaseWeightFunction { +template +class DamagedWeightFunction : public BaseWeightFunction { public: - DamagedWeightFunction(const Material & material) : BaseWeightFunction(material) {} + DamagedWeightFunction(const Material & material) : BaseWeightFunction(material) {} - inline void selectType(__attribute__((unused)) ElementType type1,__attribute__((unused)) GhostType ghost_type1, - ElementType type2, GhostType ghost_type2) { - selected_damage = &(dynamic_cast(material).getDamage(type2, ghost_type2)); + inline void selectType(__attribute__((unused)) ElementType type1, + __attribute__((unused)) GhostType ghost_type1, + ElementType type2, + GhostType ghost_type2) { + selected_damage = + &(dynamic_cast &>(this->material).getDamage(type2, ghost_type2)); } inline Real operator()(Real r, __attribute__((unused)) QuadraturePoint & q1, QuadraturePoint & q2) { UInt quad = q2.global_num; Real D = (*selected_damage)(quad); - Real Radius = (1.-D)*(1.-D) * R2; + Real Radius = (1.-D)*(1.-D) * this->R2; if(Radius < Math::getTolerance()) { - Radius = 0.01 * 0.01 * R2; + Radius = 0.01 * 0.01 * this->R2; } Real alpha = std::max(0., 1. - r*r / Radius); Real w = alpha * alpha; return w; } /* ------------------------------------------------------------------------ */ bool setParam(__attribute__((unused)) const std::string & key, __attribute__((unused)) const std::string & value) { return false; } /* ------------------------------------------------------------------------ */ virtual void printself(std::ostream & stream) const { stream << "DamageWeightFunction"; } private: const Vector * selected_damage; }; /* -------------------------------------------------------------------------- */ /* Stress Based Weight */ /* -------------------------------------------------------------------------- */ -class StressBasedWeightFunction : public BaseWeightFunction { +template +class StressBasedWeightFunction : public BaseWeightFunction { public: StressBasedWeightFunction(const Material & material); void init(); virtual void updateInternals(__attribute__((unused)) const ByElementTypeReal & quadrature_points_coordinates) { updatePrincipalStress(_not_ghost); updatePrincipalStress(_ghost); }; void updatePrincipalStress(GhostType ghost_type); inline void updateQuadraturePointsCoordinates(ByElementTypeReal & quadrature_points_coordinates); inline void selectType(ElementType type1, GhostType ghost_type1, ElementType type2, GhostType ghost_type2); inline Real operator()(Real r, QuadraturePoint & q1, QuadraturePoint & q2); /* ------------------------------------------------------------------------ */ bool setParam(const std::string & key, const std::string & value) { std::stringstream sstr(value); if(key == "ft") { sstr >> ft; } else return false; return true; } /* ------------------------------------------------------------------------ */ virtual void printself(std::ostream & stream) const { stream << "StressBasedWeightFunction [ft : " << ft << "]"; } private: Real ft; - UInt spatial_dimension; ByElementTypeReal stress_diag; Vector * selected_stress_diag; ByElementTypeReal stress_base; Vector * selected_stress_base; ByElementTypeReal quadrature_points_coordinates; Vector * selected_position_1; Vector * selected_position_2; ByElementTypeReal characteristic_size; Vector * selected_characteristic_size; }; - -inline std::ostream & operator <<(std::ostream & stream, const BaseWeightFunction & _this) +template +inline std::ostream & operator <<(std::ostream & stream, + const BaseWeightFunction & _this) { _this.printself(stream); return stream; } #include "weight_function_tmpl.hh" __END_AKANTU__ #endif /* __AKANTU_WEIGHT_FUNCTION_HH__ */ diff --git a/src/model/solid_mechanics/materials/weight_function_tmpl.hh b/src/model/solid_mechanics/materials/weight_function_tmpl.hh index a7ad54114..2632bf330 100644 --- a/src/model/solid_mechanics/materials/weight_function_tmpl.hh +++ b/src/model/solid_mechanics/materials/weight_function_tmpl.hh @@ -1,180 +1,270 @@ /** * @file weight_function.cc * @author Nicolas Richart * @date Fri Mar 23 15:55:58 2012 * * @brief implementation of the weight function classes * * @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 . * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* Stress based weight function */ /* -------------------------------------------------------------------------- */ +template +StressBasedWeightFunction::StressBasedWeightFunction(const Material & material) : + BaseWeightFunction(material), + ft(0.), + stress_diag("stress_diag", material.getID()), selected_stress_diag(NULL), + stress_base("stress_base", material.getID()), selected_stress_base(NULL), + characteristic_size("lc", material.getID()), selected_characteristic_size(NULL) +{ + material.initInternalVector(stress_diag, spatial_dimension); + material.initInternalVector(stress_base, spatial_dimension * spatial_dimension); + material.initInternalVector(characteristic_size, 1); +} + +/* -------------------------------------------------------------------------- */ +template +void StressBasedWeightFunction::init() { + this->material.resizeInternalVector(stress_diag); + this->material.resizeInternalVector(stress_base); + this->material.resizeInternalVector(characteristic_size); + + const Mesh & mesh = this->material.getModel().getFEM().getMesh(); + for (UInt g = _not_ghost; g < _casper; ++g) { + GhostType gt = GhostType(g); + Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt); + Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt); + for(; it != last_type; ++it) { + UInt nb_quadrature_points = + this->material.getModel().getFEM().getNbQuadraturePoints(*it, gt); + const Vector & element_filter = this->material.getElementFilter(*it, gt); + UInt nb_element = element_filter.getSize(); + + Vector ones(nb_element*nb_quadrature_points, 1, 1.); + Vector & lc = characteristic_size(*it, gt); + this->material.getModel().getFEM().integrateOnQuadraturePoints(ones, + lc, + 1, + *it, + gt, + &element_filter); + + for (UInt q = 0; q < nb_quadrature_points * nb_element; q++) { + lc(q) = pow(lc(q), 1./ Real(spatial_dimension)); + } + } + } +} + + +/* -------------------------------------------------------------------------- */ +template +void StressBasedWeightFunction::updatePrincipalStress(GhostType ghost_type) { + AKANTU_DEBUG_IN(); + + const Mesh & mesh = this->material.getModel().getFEM().getMesh(); + + Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); + Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type); + for(; it != last_type; ++it) { + Vector::const_iterator sigma = + this->material.getStress(*it, ghost_type).begin(spatial_dimension, spatial_dimension); + Vector::iterator eigenvalues = + stress_diag(*it, ghost_type).begin(spatial_dimension); + Vector::iterator eigenvalues_end = + stress_diag(*it, ghost_type).end(spatial_dimension); + Vector::iterator eigenvector = + stress_base(*it, ghost_type).begin(spatial_dimension, spatial_dimension); + +#ifndef __trick__ + Vector::iterator cl = characteristic_size(*it, ghost_type).begin(); +#endif + UInt q = 0; + for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues, ++eigenvector, ++cl, ++q) { + // if (q == 4871) std::cout << "Sigma " << *sigma; + sigma->eig(*eigenvalues, *eigenvector); + // if (q == 17774) std::cout << "Before " << *eigenvalues; + *eigenvalues /= ft; +#ifndef __trick__ + // specify a lower bound for principal stress based on the size of the element + for (UInt i = 0; i < spatial_dimension; ++i) { + (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i)); + } +#endif + // if (q == 17774) std::cout << "After " << *eigenvalues; + } + } + AKANTU_DEBUG_OUT(); +} /* -------------------------------------------------------------------------- */ -inline void StressBasedWeightFunction::selectType(ElementType type1, - GhostType ghost_type1, - ElementType type2, GhostType ghost_type2) { +template +inline void StressBasedWeightFunction::selectType(ElementType type1, + GhostType ghost_type1, + ElementType type2, + GhostType ghost_type2) { selected_stress_diag = &stress_diag(type2, ghost_type2); selected_stress_base = &stress_base(type2, ghost_type2); selected_characteristic_size = &characteristic_size(type1, ghost_type1); } /* -------------------------------------------------------------------------- */ -inline Real StressBasedWeightFunction::operator()(Real r, - QuadraturePoint & q1, - QuadraturePoint & q2) { +template +inline Real StressBasedWeightFunction::operator()(Real r, + QuadraturePoint & q1, + QuadraturePoint & q2) { Real zero = std::numeric_limits::epsilon(); if(r < zero) return 1.; // means x and s are the same points const types::RVector & x = q1.getPosition(); const types::RVector & s = q2.getPosition(); types::RVector eigs = selected_stress_diag->begin(spatial_dimension)[q2.global_num]; types::Matrix eigenvects = selected_stress_base->begin(spatial_dimension, spatial_dimension)[q2.global_num]; Real min_rho_lc = selected_characteristic_size->begin()[q1.global_num]; types::RVector x_s(spatial_dimension); x_s = x; x_s -= s; Real rho_2 = 0.; switch(spatial_dimension) { case 1: { rho_2 = eigs[0]; break; } case 2:{ types::RVector u1(eigenvects.storage(), spatial_dimension); Real cos_t = x_s.dot(u1) / (x_s.norm() * u1.norm()); Real cos_t_2; Real sin_t_2; Real sigma1_2 = eigs[0]*eigs[0]; Real sigma2_2 = eigs[1]*eigs[1]; #ifdef __trick__ if(std::abs(cos_t) < zero) { cos_t_2 = 0; sin_t_2 = 1; } else { #endif cos_t_2 = cos_t * cos_t; sin_t_2 = (1 - cos_t_2); #ifdef __trick__ } Real rhop1 = std::max(0., cos_t_2 / sigma1_2); Real rhop2 = std::max(0., sin_t_2 / sigma2_2); #else Real rhop1 = cos_t_2 / sigma1_2; Real rhop2 = sin_t_2 / sigma2_2; #endif rho_2 = 1./ (rhop1 + rhop2); break; } case 3: { types::RVector u1(eigenvects.storage(), spatial_dimension); types::RVector u3(eigenvects.storage() + 2*spatial_dimension, spatial_dimension); types::RVector tmp(spatial_dimension); tmp.crossProduct(x_s, u3); types::RVector u3_C_x_s_C_u3(spatial_dimension); u3_C_x_s_C_u3.crossProduct(u3, tmp); Real norm_u3_C_x_s_C_u3 = u3_C_x_s_C_u3.norm(); Real cos_t = 0.; if(std::abs(norm_u3_C_x_s_C_u3) > zero) { Real inv_norm_u3_C_x_s_C_u3 = 1. / norm_u3_C_x_s_C_u3; cos_t = u1.dot(u3_C_x_s_C_u3) * inv_norm_u3_C_x_s_C_u3; } Real cos_p = u3.dot(x_s) / r; // std::cout << " - cos_t: " << std::setw(13) << cos_t; // std::cout << " - cos_p: " << std::setw(13) << cos_p; Real cos_t_2; Real sin_t_2; Real cos_p_2; Real sin_p_2; Real sigma1_2 = eigs[0]*eigs[0]; Real sigma2_2 = eigs[1]*eigs[1]; Real sigma3_2 = eigs[2]*eigs[2]; #ifdef __trick__ if(std::abs(cos_t) < zero) { cos_t_2 = 0; sin_t_2 = 1; } else { #endif cos_t_2 = cos_t * cos_t; sin_t_2 = (1 - cos_t_2); #ifdef __trick__ } if(std::abs(cos_p) < zero) { cos_p_2 = 0; sin_p_2 = 1; } else { #endif cos_p_2 = cos_p * cos_p; sin_p_2 = (1 - cos_p_2); #ifdef __trick__ } Real rhop1 = std::max(0., sin_p_2 * cos_t_2 / sigma1_2); Real rhop2 = std::max(0., sin_p_2 * sin_t_2 / sigma2_2); Real rhop3 = std::max(0., cos_p_2 / sigma3_2); #else Real rhop1 = sin_p_2 * cos_t_2 / sigma1_2; Real rhop2 = sin_p_2 * sin_t_2 / sigma2_2; Real rhop3 = cos_p_2 / sigma3_2; #endif rho_2 = 1./ (rhop1 + rhop2 + rhop3); } } - Real rho_lc_2 = std::max(R2 * rho_2, min_rho_lc*min_rho_lc); + Real rho_lc_2 = std::max(this->R2 * rho_2, min_rho_lc*min_rho_lc); Real w = std::max(0., 1. - r*r / rho_lc_2); w = w*w; // std::cout << "(" << q1 << "," << q2 << ") " << w << std::endl; // Real w = exp(- 2*2*r*r / rho_lc_2); return w; } diff --git a/src/model/solid_mechanics/solid_mechanics_model_material.cc b/src/model/solid_mechanics/solid_mechanics_model_material.cc index 0b0794652..aaed67f98 100644 --- a/src/model/solid_mechanics/solid_mechanics_model_material.cc +++ b/src/model/solid_mechanics/solid_mechanics_model_material.cc @@ -1,161 +1,176 @@ /** * @file solid_mechanics_model_material.cc * @author Guillaume ANCIAUX * @date Thu Nov 25 10:48:53 2010 * * @brief * * @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 "solid_mechanics_model.hh" #include "material.hh" #include "aka_math.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ +#define AKANTU_INTANTIATE_MATERIAL_BY_DIM(mat, mat_class, mat_id, parser, dim) \ + mat = parser.readSection, \ + SolidMechanicsModel>(*this, mat_id) \ + +#define AKANTU_INTANTIATE_MATERIAL(mat, mat_class, mat_id, parser) \ + switch(spatial_dimension) { \ + case 1: { \ + AKANTU_INTANTIATE_MATERIAL_BY_DIM(mat, mat_class, mat_id, parser, 1); \ + break; } \ + case 2: { \ + AKANTU_INTANTIATE_MATERIAL_BY_DIM(mat, mat_class, mat_id, parser, 2); \ + break; } \ + case 3: { \ + AKANTU_INTANTIATE_MATERIAL_BY_DIM(mat, mat_class, mat_id, parser, 3); \ + break; } \ + } + + +#define AKANTU_INTANTIATE_MATERIAL_IF(data, elem) \ + if (BOOST_PP_TUPLE_ELEM(4, 0, BOOST_PP_APPLY(data)) == \ + BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem))) { \ + AKANTU_INTANTIATE_MATERIAL(BOOST_PP_TUPLE_ELEM(4, 1, BOOST_PP_APPLY(data)), \ + BOOST_PP_TUPLE_ELEM(2, 1, elem), \ + BOOST_PP_TUPLE_ELEM(4, 2, BOOST_PP_APPLY(data)), \ + BOOST_PP_TUPLE_ELEM(4, 3, BOOST_PP_APPLY(data))) \ + } + #define AKANTU_INTANTIATE_OTHER_MATERIAL(r, data, elem) \ - else if (BOOST_PP_TUPLE_ELEM(4, 0, data) == \ - BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem))) \ - BOOST_PP_TUPLE_ELEM(4, 1, data) = \ - BOOST_PP_TUPLE_ELEM(4, 3, data). \ - readSection(*this, \ - BOOST_PP_TUPLE_ELEM(4, 2, data)); + else AKANTU_INTANTIATE_MATERIAL_IF(data, elem) #define AKANTU_INTANTIATE_OTHER_MATERIALS(mat_type, material, mat_id, parser, mat_lst) \ BOOST_PP_SEQ_FOR_EACH(AKANTU_INTANTIATE_OTHER_MATERIAL, \ - (mat_type, material, mat_id, parser), \ + ((mat_type, material, mat_id, parser)), \ mat_lst) #define AKANTU_INTANTIATE_MATERIALS(mat_type, material, mat_id, parser) \ do { \ - if(mat_type == \ - BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, \ - 0, \ - BOOST_PP_SEQ_HEAD(AKANTU_MATERIAL_LIST)))) \ - material = \ - parser.readSection \ - (*this, mat_id); \ + AKANTU_INTANTIATE_MATERIAL_IF(((mat_type, material, mat_id, parser)), \ + BOOST_PP_SEQ_HEAD(AKANTU_MATERIAL_LIST)) \ AKANTU_INTANTIATE_OTHER_MATERIALS(mat_type, material, mat_id, parser, \ BOOST_PP_SEQ_TAIL(AKANTU_MATERIAL_LIST)) \ else AKANTU_DEBUG_ERROR("Malformed material file : unknown material type " \ << mat_type); \ } while(0) /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::readMaterials(const std::string & filename) { Parser parser; parser.open(filename); std::string mat_type = parser.getNextSection("material"); UInt mat_count = 0; while (mat_type != ""){ std::stringstream sstr_mat; sstr_mat << id << ":" << mat_count++ << ":" << mat_type; Material * material; ID mat_id = sstr_mat.str(); /// read the material properties // add all the new materials in the AKANTU_MATERIAL_LIST in the material.hh file AKANTU_INTANTIATE_MATERIALS(mat_type, material, mat_id, parser); materials.push_back(material); mat_type = parser.getNextSection("material"); } } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::initMaterials() { AKANTU_DEBUG_ASSERT(materials.size() != 0, "No material to initialize !"); Material ** mat_val = &(materials.at(0)); /// @todo synchronize element material for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; /// fill the element filters of the materials using the element_material arrays Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt); Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt); for(; it != end; ++it) { UInt nb_element = mesh.getNbElement(*it, gt); UInt * elem_mat_val = element_material(*it, gt).storage(); element_index_by_material.alloc(nb_element, 1, *it, gt); for (UInt el = 0; el < nb_element; ++el) { UInt index = mat_val[elem_mat_val[el]]->addElement(*it, el, gt); element_index_by_material(*it, gt)(el) = index; } } } std::vector::iterator mat_it; for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) { /// init internals properties (*mat_it)->initMaterial(); } synch_registry->synchronize(_gst_smm_init_mat); } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::setMaterialIDsFromIntData(const std::string & data_name) { for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt); Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt); for(; it != end; ++it) { try { const Vector & data = mesh.getUIntData(*it, data_name, gt); AKANTU_DEBUG_ASSERT(element_material.exists(*it, gt), "element_material for type (" << gt << ":" << *it << ") does not exists!"); element_material(*it, gt).copy(data); } catch(...) { AKANTU_DEBUG_ERROR("No data named " << data_name << " present in the mesh " << id << " for the element type " << *it); } } } } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::pushNewMaterial(Material * mat){ materials.push_back(mat); } /* -------------------------------------------------------------------------- */ __END_AKANTU__ diff --git a/src/synchronizer/static_communicator_inline_impl.hh b/src/synchronizer/static_communicator_inline_impl.hh index 4f24c16a0..31605301d 100644 --- a/src/synchronizer/static_communicator_inline_impl.hh +++ b/src/synchronizer/static_communicator_inline_impl.hh @@ -1,157 +1,157 @@ /** * @file static_communicator_inline_impl.cc * @author Nicolas Richart * @date Mon Sep 6 00:16:19 2010 * * @brief implementation of inline functions * * @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 . * */ /* -------------------------------------------------------------------------- */ inline void StaticCommunicator::freeCommunicationRequest(CommunicationRequest * request) { if(request) delete request; } /* -------------------------------------------------------------------------- */ inline void StaticCommunicator::freeCommunicationRequest(std::vector & requests) { std::vector::iterator it; for(it = requests.begin(); it != requests.end(); ++it) { delete (*it); } } #if defined(__INTEL_COMPILER) #pragma warning ( push ) #pragma warning ( disable : 111 ) #endif //defined(__INTEL_COMPILER) /* -------------------------------------------------------------------------- */ #define AKANTU_BOOST_REAL_COMMUNICATOR_CALL(r, call, comm_type) \ case BOOST_PP_LIST_AT(comm_type, 0): { \ BOOST_PP_LIST_AT(comm_type, 1) * comm = \ - dynamic_cast(real_static_communicator); \ + static_cast(real_static_communicator); \ BOOST_PP_IF(BOOST_PP_LIST_AT(call, 0), \ return comm->BOOST_PP_LIST_AT(call, 1), \ comm->BOOST_PP_LIST_AT(call, 1); break;); \ } #define AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(call, ret) \ do { \ switch(real_type) \ { \ BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_REAL_COMMUNICATOR_CALL, \ (ret, (call, BOST_PP_NIL)), \ AKANTU_COMMUNICATOR_LIST_ALL) \ default: \ StaticCommunicatorDummy * comm = \ - dynamic_cast(real_static_communicator); \ + static_cast(real_static_communicator); \ BOOST_PP_IF(ret, return comm->call, comm->call); \ } \ } while(0) /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::send(T * buffer, Int size, Int receiver, Int tag) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(send(buffer, size, receiver, tag), 0); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::receive(T * buffer, Int size, Int sender, Int tag) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(receive(buffer, size, sender, tag), 0); } /* -------------------------------------------------------------------------- */ template inline CommunicationRequest * StaticCommunicator::asyncSend(T * buffer, Int size, Int receiver, Int tag) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(asyncSend(buffer, size, receiver, tag), 1); } /* -------------------------------------------------------------------------- */ template inline CommunicationRequest * StaticCommunicator::asyncReceive(T * buffer, Int size, Int sender, Int tag) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(asyncReceive(buffer, size, sender, tag), 1); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::probe(Int sender, Int tag, CommunicationStatus & status) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(probe(sender, tag, status), 0); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::allReduce(T * values, Int nb_values, const SynchronizerOperation & op) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(allReduce(values, nb_values, op), 0); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::allGather(T * values, Int nb_values) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(allGather(values, nb_values), 0); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::allGatherV(T * values, Int * nb_values) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(allGatherV(values, nb_values), 0); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::gather(T * values, Int nb_values, Int root) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(gather(values, nb_values, root), 0); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::gatherV(T * values, Int * nb_values, Int root) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(gatherV(values, nb_values, root), 0); } /* -------------------------------------------------------------------------- */ template inline void StaticCommunicator::broadcast(T * values, Int nb_values, Int root) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(broadcast(values, nb_values, root), 0); } /* -------------------------------------------------------------------------- */ inline void StaticCommunicator::barrier() { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(barrier(), 0); } /* -------------------------------------------------------------------------- */ inline bool StaticCommunicator::testRequest(CommunicationRequest * request) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(testRequest(request), 1); } /* -------------------------------------------------------------------------- */ inline void StaticCommunicator::wait(CommunicationRequest * request) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(wait(request), 0); } /* -------------------------------------------------------------------------- */ inline void StaticCommunicator::waitAll(std::vector & requests) { AKANTU_BOOST_REAL_COMMUNICATOR_SELECT_CALL(waitAll(requests), 0); } #if defined(__INTEL_COMPILER) #pragma warning ( pop ) #endif //defined(__INTEL_COMPILER) diff --git a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc index 022b629c3..ed980b9fb 100644 --- a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc +++ b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.cc @@ -1,153 +1,154 @@ /** * @file local_material_damage.cc * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Tue Jul 27 11:53:52 2010 * * @brief Specialization of the material class for the damage material * * @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 "local_material_damage.hh" #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ -LocalMaterialDamage::LocalMaterialDamage(Model & model, const ID & id) : +LocalMaterialDamage::LocalMaterialDamage(SolidMechanicsModel & model, + const ID & id) : Material(model, id), damage("damage", id) { AKANTU_DEBUG_IN(); E = 0; nu = 1./2.; Yd = 50; Sd = 5000; initInternalVector(this->damage, 1); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void LocalMaterialDamage::initMaterial() { AKANTU_DEBUG_IN(); Material::initMaterial(); resizeInternalVector(this->damage); lambda = nu * E / ((1 + nu) * (1 - 2*nu)); mu = E / (2 * (1 + nu)); kpa = lambda + 2./3. * mu; is_init = true; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void LocalMaterialDamage::computeStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Real F[3*3]; Real sigma[3*3]; resizeInternalVector(this->damage); Real * dam = damage(el_type, ghost_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; memset(F, 0, 3 * 3 * sizeof(Real)); for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) F[3*i + j] = strain_val[spatial_dimension * i + j]; for (UInt i = 0; i < spatial_dimension; ++i) F[i*3 + i] -= 1; computeStress(F, sigma,*dam); ++dam; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) stress_val[spatial_dimension*i + j] = sigma[3 * i + j]; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void LocalMaterialDamage::computePotentialEnergy(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); if(ghost_type != _not_ghost) return; Real * epot = potential_energy(el_type).storage(); MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN; computePotentialEnergy(strain_val, stress_val, epot); epot++; MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ bool LocalMaterialDamage::setParam(const std::string & key, const std::string & value, const ID & id) { std::stringstream sstr(value); if(key == "E") { sstr >> E; } else if(key == "nu") { sstr >> nu; } else if(key == "Yd") { sstr >> Yd; } else if(key == "Sd") { sstr >> Sd; } else { return Material::setParam(key, value, id); } return true; } /* -------------------------------------------------------------------------- */ void LocalMaterialDamage::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Material<_damage> [" << std::endl; stream << space << " + id : " << id << std::endl; stream << space << " + name : " << name << std::endl; stream << space << " + density : " << rho << std::endl; stream << space << " + Young's modulus : " << E << std::endl; stream << space << " + Poisson's ratio : " << nu << std::endl; stream << space << " + Yd : " << Yd << std::endl; stream << space << " + Sd : " << Sd << std::endl; if(is_init) { stream << space << " + First Lamé coefficient : " << lambda << std::endl; stream << space << " + Second Lamé coefficient : " << mu << std::endl; stream << space << " + Bulk coefficient : " << kpa << std::endl; } stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ __END_AKANTU__ diff --git a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh index f1f8d9744..0c14e0eb2 100644 --- a/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh +++ b/test/test_model/test_solid_mechanics_model/test_materials/local_material_damage.hh @@ -1,139 +1,139 @@ /** * @file local_material_damage.hh * @author Nicolas Richart * @author Guillaume Anciaux * @author Marion Chambart * @date Thu Jul 29 15:00:59 2010 * * @brief Material isotropic elastic * * @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_common.hh" #include "material.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__ #define __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__ __BEGIN_AKANTU__ class LocalMaterialDamage : public Material { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - LocalMaterialDamage(Model & model, const ID & id = ""); + LocalMaterialDamage(SolidMechanicsModel & model, const ID & id = ""); // virtual ~LocalMaterialDamage() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void initMaterial(); bool setParam(const std::string & key, const std::string & value, const ID & id); /// constitutive law for all element of a type void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost); /// constitutive law for a given quadrature point inline void computeStress(Real * F, Real * sigma,Real & damage); /// compute tangent stiffness virtual void computeTangentStiffness(__attribute__ ((unused)) const ElementType & el_type, __attribute__ ((unused)) Vector & tangent_matrix, __attribute__ ((unused)) GhostType ghost_type = _not_ghost) {}; /// compute the potential energy for all elements void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost); /// compute the potential energy for on element inline void computePotentialEnergy(Real * F, Real * sigma, Real * epot); /// compute the celerity of wave in the material inline Real celerity(); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// get the stable time step inline Real getStableTimeStep(Real h, const Element & element); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real); private: /// the young modulus Real E; /// Poisson coefficient Real nu; /// First Lamé coefficient Real lambda; /// Second Lamé coefficient (shear modulus) Real mu; /// resistance to damage Real Yd; /// damage threshold Real Sd; /// Bulk modulus Real kpa; /// damage internal variable ByElementTypeReal damage; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "local_material_damage_inline_impl.cc" /* -------------------------------------------------------------------------- */ /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const LocalMaterialDamage & _this) { _this.printself(stream); return stream; } __END_AKANTU__ #endif /* __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__ */ diff --git a/test/test_vector/test_vector.cc b/test/test_vector/test_vector.cc index 3eb65c0d2..424eac070 100644 --- a/test/test_vector/test_vector.cc +++ b/test/test_vector/test_vector.cc @@ -1,94 +1,96 @@ /** * @file test_vector.cc * @author Nicolas Richart * @date Tue Jun 29 17:32:23 2010 * * @brief test of the vector class * * @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 #include /* -------------------------------------------------------------------------- */ #include "aka_types.hh" #include "aka_vector.hh" /* -------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int def_value[3]; def_value[0] = 10; def_value[1] = 20; def_value[2] = 30; std::cout << "Creating a vector" << std::endl; akantu::Vector int_vect(10, 3, def_value, "test1"); for (unsigned int i = 5; i < int_vect.getSize(); ++i) { for (unsigned int j = 0; j < int_vect.getNbComponent(); ++j) { int_vect.values[i*int_vect.getNbComponent() + j] = def_value[j]*10; } } std::cerr << int_vect; int new_elem[3]; new_elem[0] = 1; new_elem[1] = 2; new_elem[2] = 3; std::cout << "Testing push_back" << std::endl; int_vect.push_back(new_elem); int_vect.push_back(200); int_vect.erase(0); std::cerr << int_vect; akantu::Vector int_vect0(0, 3, def_value, "test2"); std::cerr << int_vect0; int_vect0.push_back(new_elem); std::cerr << int_vect0; std::cout << "Creating a vector of matrices (2,2)" << std::endl; akantu::Vector mat_vect(10, 4, 1.); memset(mat_vect.values, 0, 10*4*sizeof(double)); typedef akantu::Vector RealVector; akantu::types::Matrix m1(2, 3, 1.); akantu::types::Matrix m2(3, 5, 2.); akantu::types::Matrix m3; m3 = m1 * m2; std::cout << m1 << m2 << m3; std::cout << "Iterating on a Matrix(2,2)" << std::endl; RealVector::iterator itm; itm = mat_vect.begin(2, 2); RealVector::iterator endm = mat_vect.end(2, 2); for (; itm != endm; ++itm) { std::cout << *itm << std::endl; } + int_vect0.resize(0); + return EXIT_SUCCESS; }