12#ifndef BELFEM_CL_TENSOR_HPP
13#define BELFEM_CL_TENSOR_HPP
41 template<
typename T >
76 mOffsetK( aSizeI * aSizeJ ),
77 mOffsetL( aSizeI * aSizeJ * aSizeK ),
79 mCapacity( aSizeI * aSizeJ * aSizeK * aSizeL )
81 BELFEM_ASSERT( mCapacity > 0,
"Tensor sizes must not be zero" );
83 mData = ( T * ) malloc( ( mCapacity ) *
sizeof( T ) );
95 mOffsetK( aSizeI * aSizeJ ),
96 mOffsetL( aSizeI * aSizeJ * aSizeK ),
98 mCapacity( aSizeI * aSizeJ * aSizeK )
100 BELFEM_ASSERT( mCapacity > 0,
"Tensor sizes must not be zero" );
102 mData = ( T * ) malloc( ( mCapacity ) *
sizeof( T ) );
110 const real aValue ) :
111 Tensor( aSizeI, aSizeJ, aSizeK, aSizeL )
113 this->
fill( aValue );
121 && aElasticityMatrix.
n_cols() == 6,
122 "Matrix must be allocated as 6x6" );
131 mSizeI( aOther.
size_i() ),
132 mSizeJ( aOther.
size_j() ),
133 mSizeK( aOther.
size_k() ),
134 mSizeL( aOther.
size_l() ),
135 mOffsetJ( aOther.mOffsetJ ),
136 mOffsetK( aOther.mOffsetK ),
137 mOffsetL( aOther.mOffsetL ),
138 mOrder( aOther.mOrder ),
139 mCapacity( aOther.mCapacity )
141 mData = ( T * ) malloc( mCapacity *
sizeof( T ) );
142 std::memcpy( mData, aOther.mData, mCapacity *
sizeof( T ) );
149 mSizeI( aOther.
size_i() ),
150 mSizeJ( aOther.
size_j() ),
151 mSizeK( aOther.
size_k() ),
152 mSizeL( aOther.
size_l() ),
153 mOffsetJ( aOther.mOffsetJ ),
154 mOffsetK( aOther.mOffsetK ),
155 mOffsetL( aOther.mOffsetL ),
156 mOrder( aOther.mOrder ),
157 mCapacity( aOther.mCapacity )
159 mData = aOther.mData ;
160 aOther.mData = nullptr ;
238 std::fill_n( mData, mCapacity, aValue );
264 T K =
E / ( 3. * ( 1.0 - 2.0 *
nu ) );
267 T G =
E / ( 2.0 * ( 1.0 +
nu ) );
292 aPoisson23, aPoisson13, aPoisson12,
293 aShear23, aShear13, aShear12, tS );
321 return mSizeI == 3 && mSizeJ == 3 && mSizeK == 3 && mSizeL == 3 ;
327 print(
const string aLabel=
"Tensor")
330 fprintf( stdout,
" %s:\n", aLabel.c_str() );
332 for(
index_t l=0; l<mSizeL; ++l )
334 for(
index_t k=0; k<mSizeK; ++k )
336 for(
index_t j=0; j<mSizeJ; ++j )
338 for(
index_t i=0; i<mSizeI; ++i )
340 fprintf( stdout,
" %u : ( %u, %u, %u, %u ) = %12.3f\n",
341 (
unsigned int ) tCount,
346 (
double ) mData[ tCount ] );
367 BELFEM_ASSERT( mOrder == 3,
"Tensor order must be of order 3" );
369 BELFEM_ASSERT( I < mSizeI,
"Index i out of bounds ( %u vs %u )",
371 (
unsigned int ) mSizeI );
373 BELFEM_ASSERT( J < mSizeJ,
"Index j out of bounds ( %u vs %u )",
375 (
unsigned int ) mSizeJ );
377 BELFEM_ASSERT( K < mSizeK,
"Index k out of bounds ( %u vs %u )",
379 (
unsigned int ) mSizeK );
381 return mData[ K * mOffsetK + J * mOffsetJ + I ] ;
395 BELFEM_ASSERT( mOrder == 3,
"Tensor order must be of order 3" );
397 BELFEM_ASSERT( I < mSizeI,
"Index i out of bounds ( %u vs %u )",
399 (
unsigned int ) mSizeI );
401 BELFEM_ASSERT( J < mSizeJ,
"Index j out of bounds ( %u vs %u )",
403 (
unsigned int ) mSizeJ );
405 BELFEM_ASSERT( K < mSizeK,
"Index k out of bounds ( %u vs %u )",
407 (
unsigned int ) mSizeK );
409 return mData[ K * mOffsetK + J * mOffsetJ + I ] ;
424 BELFEM_ASSERT( mOrder == 4,
"Tensor order must be of order 4" );
426 BELFEM_ASSERT( I < mSizeI,
"Index i out of bounds ( %u vs %u )",
428 (
unsigned int ) mSizeI );
430 BELFEM_ASSERT( J < mSizeJ,
"Index j out of bounds ( %u vs %u )",
432 (
unsigned int ) mSizeJ );
434 BELFEM_ASSERT( K < mSizeK,
"Index k out of bounds ( %u vs %u )",
436 (
unsigned int ) mSizeK );
438 BELFEM_ASSERT( L < mSizeL,
"Index l out of bounds ( %u vs %u )",
440 (
unsigned int ) mSizeL );
442 return mData[ L * mOffsetL + K * mOffsetK + J * mOffsetJ + I ] ;
457 BELFEM_ASSERT( mOrder == 4,
"Tensor order must be of order 4" );
459 BELFEM_ASSERT( I < mSizeI,
"Index i out of bounds ( %u vs %u )",
461 (
unsigned int ) mSizeI );
463 BELFEM_ASSERT( J < mSizeJ,
"Index j out of bounds ( %u vs %u )",
465 (
unsigned int ) mSizeJ );
467 BELFEM_ASSERT( K < mSizeK,
"Index k out of bounds ( %u vs %u )",
469 (
unsigned int ) mSizeK );
471 BELFEM_ASSERT( L < mSizeL,
"Index l out of bounds ( %u vs %u )",
473 (
unsigned int ) mSizeL );
475 return mData[ L * mOffsetL + K * mOffsetK + J * mOffsetJ + I ] ;
488 if(
this == &aTensor )
return *
this;
491 "Tensor orders must match for copy assignment" );
494 "Tensor dimensions must match for copy assignment" );
497 "Tensor dimensions must match for copy assignment" );
500 "Tensor dimensions must match for copy assignment" );
503 "Tensor dimensions must match for copy assignment" );
505 std::memcpy( mData, aTensor.
data(), mCapacity *
sizeof( T ) );
517 if(
this == &aTensor )
return *
this;
520 "Tensor orders must match for move assignment" );
523 "Tensor dimensions must match for move assignment" );
526 "Tensor dimensions must match for move assignment" );
529 "Tensor dimensions must match for move assignment" );
532 "Tensor dimensions must match for move assignment" );
535 mData = aTensor.mData ;
536 aTensor.mData = nullptr ;
545 this->
fill( aScalar );
568 std::for_each( mData, mData + mCapacity,
569 [ aScalar ]( T & tVal )
570 { tVal += aScalar; } );
580 "Tensor orders must match for addition operator" );
583 "Tensor dimensions must match for addition operator" );
586 "Tensor dimensions must match for addition operator" );
589 "Tensor dimensions must match for addition operator" );
592 "Tensor dimensions must match for addition operator" );
594 std::transform( mData, mData + mCapacity, aTensor.
data(),
595 mData, std::plus< T >() );
606 std::for_each( mData, mData + mCapacity,
607 [ aScalar ]( T & tVal )
608 { tVal -= aScalar; } );
618 "Tensor orders must match for subtraction operator" );
621 "Tensor dimensions must match for subtraction operator" );
624 "Tensor dimensions must match for subtraction operator" );
627 "Tensor dimensions must match for subtraction operator" );
630 "Tensor dimensions must match for subtraction operator" );
632 std::transform( mData, mData + mCapacity, aTensor.
data(),
633 mData, std::minus< T >() );
644 std::for_each( mData, mData + mCapacity,
645 [ aScalar ]( T & tVal )
646 { tVal *= aScalar; } );
657 std::for_each( mData, mData + mCapacity,
658 [ aScalar ]( T & tVal )
659 { tVal /= aScalar; } );
695 "operating tensor must be 3x3x3x3" );
699 "argument matrix must be allocated as 3x3" );
703 "target matrix must be allocated as 3x3" );
721 "Matrix must be allocated as 6x6" );
730 template<
typename T >
736 "Tensor orders must match for addition operator" );
739 "Tensor dimensions must match for addition operator" );
742 "Tensor dimensions must match for addition operator" );
745 "Tensor dimensions must match for addition operator" );
748 "Tensor dimensions must match for addition operator" );
758 template<
typename T >
764 "Tensor orders must match for subtraction operator" );
767 "Tensor dimensions must match for subtraction operator" );
770 "Tensor dimensions must match for subtraction operator" );
773 "Tensor dimensions must match for subtraction operator" );
776 "Tensor dimensions must match for subtraction operator" );
787 template<
typename T >
793 "Both tensors must be of size 3x3x3x3" );
802 template<
typename T >
808 "Tensor A must be of size 3x3x3x3" );
811 "when contracting a 3x3x3x3 tensor with a matrix, latter one must be 3x3" );
820 template<
typename T >
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
size_t n_rows() const
Definition cl_AR_Matrix.hpp:205
size_t n_cols() const
Definition cl_AR_Matrix.hpp:213
Third- or fourth-order tensor container; the constitutive helpers (contraction, rotation,...
Definition cl_Tensor.hpp:43
Tensor(Tensor< T > &&aOther)
Definition cl_Tensor.hpp:148
Tensor< T > & operator=(const T &aScalar)
Definition cl_Tensor.hpp:543
Tensor(const Tensor< T > &aOther)
Definition cl_Tensor.hpp:130
Tensor< T > & operator+=(const Tensor< T > &aTensor)
Definition cl_Tensor.hpp:577
void fill(const T aA, const T aB)
fill tensor in an isotropic way
Definition cl_Tensor.hpp:247
Tensor< T > & operator+=(const T &aScalar)
Definition cl_Tensor.hpp:566
index_t order() const
Definition cl_Tensor.hpp:198
void to_matrix(Matrix< real > &aMatrix)
converts a tensor to the elastitity matrix in Voigt notation
Definition cl_Tensor.hpp:717
void ddot(const Matrix< T > &aB, Matrix< T > &aC)
contract with 3x3 matrox
Definition cl_Tensor.hpp:692
Tensor< T > & operator*=(const T &aScalar)
Definition cl_Tensor.hpp:642
Tensor< T > & operator=(Tensor< T > &&aTensor)
move assignment
Definition cl_Tensor.hpp:515
T * data()
expose the underlying raw pointer
Definition cl_Tensor.hpp:211
Tensor< T > & operator=(const Matrix< T > &aElasticityMatrix)
Definition cl_Tensor.hpp:552
index_t size_j() const
Definition cl_Tensor.hpp:181
Tensor(const index_t aSizeI, const index_t aSizeJ, const index_t aSizeK, const index_t aSizeL, const real aValue)
Definition cl_Tensor.hpp:106
void fill_orthotropic_elasticity(const T aYoung1, const T aYoung2, const T aYoung3, const T aPoisson23, const T aPoisson13, const T aPoisson12, const T aShear23, const T aShear13, const T aShear12)
Definition cl_Tensor.hpp:275
~Tensor()
Definition cl_Tensor.hpp:165
void ddot(const Tensor< T > &aB, Tensor< T > &aC)
contract with other tensor
Definition cl_Tensor.hpp:674
bool is_3333() const
returns true if this is a 3x3x3x3 tensor
Definition cl_Tensor.hpp:319
T & operator()(const index_t I, const index_t J, const index_t K)
access operator ( writable version )
Definition cl_Tensor.hpp:362
void print(const string aLabel="Tensor")
Definition cl_Tensor.hpp:327
index_t size_l() const
Definition cl_Tensor.hpp:193
index_t capacity() const
memory size
Definition cl_Tensor.hpp:308
Tensor< T > & operator=(const Tensor< T > &aTensor)
copy assignment
Definition cl_Tensor.hpp:486
const T & operator()(const index_t I, const index_t J, const index_t K, const index_t L) const
access operator ( const version )
Definition cl_Tensor.hpp:451
Tensor< T > & operator-=(const T &aScalar)
Definition cl_Tensor.hpp:604
Tensor< T > & operator-=(const Tensor< T > &aTensor)
Definition cl_Tensor.hpp:615
Tensor(const index_t aSizeI, const index_t aSizeJ, const index_t aSizeK, const index_t aSizeL)
Definition cl_Tensor.hpp:67
Tensor(const Matrix< real > &aElasticityMatrix)
Definition cl_Tensor.hpp:117
const T & operator()(const index_t I, const index_t J, const index_t K) const
access operator ( const version )
Definition cl_Tensor.hpp:390
T & operator()(const index_t I, const index_t J, const index_t K, const index_t L)
access operator ( writable version )
Definition cl_Tensor.hpp:418
void fill(const T aValue)
fill all values
Definition cl_Tensor.hpp:235
Tensor(const index_t aSizeI, const index_t aSizeJ, const index_t aSizeK)
Definition cl_Tensor.hpp:87
Tensor< T > & operator/=(const T &aScalar)
Definition cl_Tensor.hpp:655
void fill_isotropic_elasticity(const T E, const T nu)
special funcition to create an isotropic elasticity tensor
Definition cl_Tensor.hpp:259
index_t size_k() const
Definition cl_Tensor.hpp:187
const T * data() const
expose the underlying raw pointer ( const version )
Definition cl_Tensor.hpp:222
index_t size_i() const
Definition cl_Tensor.hpp:175
Inverse of a square matrix.
void fill(T *A, const T a, const T b)
Definition fn_TR_fill.hpp:29
void contract42(const T *A, const T *B, T *C)
tensor contraction A_ijkl * B_kl = C_ij
Definition fn_TR_contract42_arma.hpp:28
void mat_to_ten(const T *C, T *A)
elasticity matrix conversion elasticity matrix C => tensor A
Definition fn_TR_mat_to_ten.hpp:27
void contract44(const T *A, const T *B, T *C)
tensor contraction A_ijmn * B_mnkl = C_ijkl
Definition fn_TR_contract44.hpp:26
bool equal_equal(const T *A, const T *B, const index_t aCapacity)
Definition fn_TR_equal_equal.hpp:23
void ten_to_mat(const T *A, T *C)
elasticity matrix conversion Elasticity tensor A => elasticity matrix C
Definition fn_TR_ten_to_mat.hpp:28
USER GUIDES:
Definition cl_Capacitor.cpp:16
void compliance_matrix(const T &aE1, const T &aE2, const T &aE3, const T &aNu23, const T &aNu13, const T &aNu12, const T &aG23, const T &aG31, const T &aG12, Matrix< T > &aS)
Definition fn_compliance_matrix.hpp:19
auto operator+(const Matrix< T > &aA, const Matrix< T > &aB) -> decltype(aA.matrix_data()+aB.matrix_data())
Definition op_MatrixPlus.hpp:23
@ nu
Definition cl_Material.hpp:156
@ E
Definition cl_Material.hpp:155
auto operator-(const Matrix< T > &aA, const Matrix< T > &aB) -> decltype(aA.matrix_data() - aB.matrix_data())
Definition op_MatrixMinus.hpp:23
uint32_t index_t
Definition typedefs.hpp:52
auto inv(const T &aExpression) -> decltype(arma::inv(aExpression))
Definition fn_AR_inv.hpp:22
auto operator%(const Vector< T > &aA, const Vector< T > &aB) -> decltype(aA.vector_data() % aB.vector_data())
Definition op_AR_VectorElementwiseMultiplication.hpp:22
double real
Definition typedefs.hpp:36
bool operator==(const Matrix< T > &aA, const Matrix< T > &aB)
Definition op_AR_MatrixEqualEqual.hpp:23