00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _REALTENSOR_H_
00012 #define _REALTENSOR_H_
00013
00014 #include <algorithm>
00015
00016 #include "SPACE.H"
00017 #include "REAL.H"
00018 #include "MayDay.H"
00019
00020 #include "NamespaceHeader.H"
00021
00022
00023
00024 class RealTensor
00025 {
00026 public:
00027
00028 RealTensor()
00029 {
00030 std::fill(m_T, m_T + SpaceDim*SpaceDim, 0.0);
00031 }
00032
00033 #if CH_SPACEDIM == 1
00034 explicit RealTensor(Real a_t11)
00035 {
00036 m_T[0] = a_t11;
00037 }
00038 #elif CH_SPACEDIM == 2
00039 RealTensor(Real a_t11, Real a_t12,
00040 Real a_t21, Real a_t22)
00041 {
00042 m_T[0] = a_t11; m_T[1] = a_t12;
00043 m_T[2] = a_t21; m_T[3] = a_t22;
00044 }
00045 #elif CH_SPACEDIM == 3
00046 RealTensor(Real a_t11, Real a_t12, Real a_t13,
00047 Real a_t21, Real a_t22, Real a_t23,
00048 Real a_t31, Real a_t32, Real a_t33)
00049 {
00050 m_T[0] = a_t11; m_T[1] = a_t12; m_T[2] = a_t13;
00051 m_T[3] = a_t21; m_T[4] = a_t22; m_T[5] = a_t23;
00052 m_T[6] = a_t31; m_T[7] = a_t32; m_T[8] = a_t33;
00053 }
00054 #elif CH_SPACEDIM == 4
00055 RealTensor(Real a_t11, Real a_t12, Real a_t13, Real a_t14,
00056 Real a_t21, Real a_t22, Real a_t23, Real a_t24,
00057 Real a_t31, Real a_t32, Real a_t33, Real a_t34,
00058 Real a_t41, Real a_t42, Real a_t43, Real a_t44)
00059 {
00060 m_T[ 0] = a_t11; m_T[ 1] = a_t12; m_T[ 2] = a_t13; m_T[ 3] = a_t14;
00061 m_T[ 4] = a_t21; m_T[ 5] = a_t22; m_T[ 6] = a_t23; m_T[ 7] = a_t24;
00062 m_T[ 8] = a_t31; m_T[ 9] = a_t32; m_T[10] = a_t33; m_T[11] = a_t34;
00063 m_T[12] = a_t31; m_T[13] = a_t32; m_T[14] = a_t33; m_T[15] = a_t44;
00064 }
00065 #elif CH_SPACEDIM == 5
00066 RealTensor(Real a_t11, Real a_t12, Real a_t13, Real a_t14, Real a_t15,
00067 Real a_t21, Real a_t22, Real a_t23, Real a_t24, Real a_t25,
00068 Real a_t31, Real a_t32, Real a_t33, Real a_t34, Real a_t35,
00069 Real a_t41, Real a_t42, Real a_t43, Real a_t44, Real a_t45,
00070 Real a_t51, Real a_t52, Real a_t53, Real a_t54, Real a_t55)
00071 {
00072 m_T[ 0] = a_t11; m_T[ 1] = a_t12; m_T[ 2] = a_t13; m_T[ 3] = a_t14; m_T[ 4] = a_t15;
00073 m_T[ 5] = a_t21; m_T[ 6] = a_t22; m_T[ 7] = a_t23; m_T[ 8] = a_t24; m_T[ 9] = a_t25;
00074 m_T[10] = a_t31; m_T[11] = a_t32; m_T[12] = a_t33; m_T[13] = a_t34; m_T[14] = a_t35;
00075 m_T[15] = a_t41; m_T[16] = a_t42; m_T[17] = a_t43; m_T[18] = a_t44; m_T[19] = a_t45;
00076 m_T[20] = a_t51; m_T[21] = a_t52; m_T[22] = a_t53; m_T[23] = a_t54; m_T[24] = a_t55;
00077 }
00078 #elif CH_SPACEDIM == 6
00079 RealTensor(Real a_t11, Real a_t12, Real a_t13, Real a_t14, Real a_t15, Real a_t16,
00080 Real a_t21, Real a_t22, Real a_t23, Real a_t24, Real a_t25, Real a_t26,
00081 Real a_t31, Real a_t32, Real a_t33, Real a_t34, Real a_t35, Real a_t36,
00082 Real a_t41, Real a_t42, Real a_t43, Real a_t44, Real a_t45, Real a_t46,
00083 Real a_t51, Real a_t52, Real a_t53, Real a_t54, Real a_t55, Real a_t56,
00084 Real a_t61, Real a_t62, Real a_t63, Real a_t64, Real a_t65, Real a_t66)
00085 {
00086 m_T[ 0] = a_t11; m_T[ 1] = a_t12; m_T[ 2] = a_t13; m_T[ 3] = a_t14; m_T[ 4] = a_t15; m_T[ 5] = a_t16;
00087 m_T[ 6] = a_t21; m_T[ 7] = a_t22; m_T[ 8] = a_t23; m_T[ 9] = a_t24; m_T[10] = a_t25; m_T[11] = a_t26;
00088 m_T[12] = a_t31; m_T[13] = a_t32; m_T[14] = a_t33; m_T[15] = a_t34; m_T[16] = a_t35; m_T[17] = a_t36;
00089 m_T[18] = a_t41; m_T[19] = a_t42; m_T[20] = a_t43; m_T[21] = a_t44; m_T[22] = a_t45; m_T[23] = a_t46;
00090 m_T[24] = a_t51; m_T[25] = a_t52; m_T[26] = a_t53; m_T[27] = a_t54; m_T[28] = a_t55; m_T[29] = a_t56;
00091 m_T[30] = a_t61; m_T[31] = a_t62; m_T[32] = a_t63; m_T[33] = a_t64; m_T[34] = a_t65; m_T[35] = a_t66;
00092 }
00093 #else
00094 #error "RealTensor is only implemented for SpaceDim <= 6."
00095 #endif
00096
00097
00098 RealTensor(const RealTensor& a_rhs)
00099 {
00100 std::copy(a_rhs.m_T, a_rhs.m_T + SpaceDim*SpaceDim, m_T);
00101 }
00102
00103
00104 ~RealTensor()
00105 {
00106 }
00107
00108
00109 RealTensor& operator=(const RealTensor& a_rhs)
00110 {
00111 if (this != &a_rhs)
00112 {
00113 std::copy(a_rhs.m_T, a_rhs.m_T + SpaceDim*SpaceDim, m_T);
00114 }
00115
00116 return *this;
00117 }
00118
00119
00120 Real operator()(int a_i, int a_j) const
00121 {
00122 return m_T[SpaceDim*a_j + a_i];
00123 }
00124
00125 Real& operator()(int a_i, int a_j)
00126 {
00127 return m_T[SpaceDim*a_j + a_i];
00128 }
00129
00130
00131 Real det() const
00132 {
00133 const Real* tensor = m_T;
00134
00135 return recurDet(tensor,SpaceDim);
00136 }
00137
00138
00139 RealTensor transpose() const
00140 {
00141 RealTensor t = *this;
00142 #if CH_SPACEDIM >= 2
00143 std::swap(t(0, 1), t(1, 0));
00144 #endif
00145 #if CH_SPACEDIM >= 3
00146 std::swap(t(0, 2), t(2, 0));
00147 std::swap(t(1, 2), t(2, 1));
00148 #endif
00149 #if CH_SPACEDIM >= 4
00150 std::swap(t(0, 3), t(3, 0));
00151 std::swap(t(1, 3), t(3, 1));
00152 std::swap(t(2, 3), t(3, 2));
00153 #endif
00154 #if CH_SPACEDIM >= 5
00155 std::swap(t(0, 4), t(4, 0));
00156 std::swap(t(1, 4), t(4, 1));
00157 std::swap(t(2, 4), t(4, 2));
00158 std::swap(t(3, 4), t(4, 3));
00159 #endif
00160 #if CH_SPACEDIM == 6
00161 std::swap(t(0, 5), t(5, 0));
00162 std::swap(t(1, 5), t(5, 1));
00163 std::swap(t(2, 5), t(5, 2));
00164 std::swap(t(3, 5), t(5, 3));
00165 std::swap(t(4, 5), t(5, 4));
00166 #endif
00167 return t;
00168 }
00169
00170 private:
00171
00172
00173 Real recurDet(const Real* a_tensor,
00174 const int& a_size) const
00175 {
00176 Real retval = 0.0;
00177
00178 if (a_size == 1)
00179 {
00180 retval += *a_tensor;
00181 }
00182 else
00183 {
00184 int subSize = a_size - 1;
00185 Real* subTensor = new Real[subSize*subSize];
00186
00187 Real sign = 1.0;
00188
00189 int row1 = 0;
00190 for (int col1 = 0; col1 < a_size; col1++)
00191 {
00192 int subRow = 0;
00193 for (int row2 = 0; row2 < a_size; row2++)
00194 {
00195 if (row2 != row1)
00196 {
00197 int subCol = 0;
00198 for (int col2 = 0; col2 < a_size; col2++)
00199 {
00200 if (col2 != col1)
00201 {
00202 subTensor[subSize*subRow + subCol] = a_tensor[a_size*row2 + col2];
00203
00204 subCol++;
00205 }
00206 }
00207
00208 subRow++;
00209 }
00210 }
00211
00212 retval += sign * a_tensor[a_size*row1 + col1] * recurDet(subTensor,subSize);
00213
00214 sign *= -1.0;
00215 }
00216
00217 delete [] subTensor;
00218 }
00219
00220 return retval;
00221 }
00222
00223 Real m_T[CH_SPACEDIM*CH_SPACEDIM];
00224 };
00225
00226 #include "NamespaceFooter.H"
00227
00228 #endif