00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "PoleZeroMaterialLaw.hpp"
00030
00031 template<unsigned DIM>
00032 PoleZeroMaterialLaw<DIM>::PoleZeroMaterialLaw()
00033 {
00034 mpChangeOfBasisMatrix = NULL;
00035 }
00036
00037 template<unsigned DIM>
00038 void PoleZeroMaterialLaw<DIM>::SetParameters(std::vector<std::vector<double> > k,
00039 std::vector<std::vector<double> > a,
00040 std::vector<std::vector<double> > b)
00041 {
00042 if (DIM!=2 && DIM !=3)
00043 {
00044 EXCEPTION("Can only have a 2 or 3d incompressible pole-zero law");
00045 }
00046
00047 assert(k.size()==DIM);
00048 assert(a.size()==DIM);
00049 assert(b.size()==DIM);
00050
00051 for (unsigned i=0; i<DIM; i++)
00052 {
00053 assert(k[i].size()==DIM);
00054 assert(a[i].size()==DIM);
00055 assert(b[i].size()==DIM);
00056
00057 for (unsigned j=0; j<DIM; j++)
00058 {
00059 assert( k[i][j] = k[j][i] );
00060 assert( a[i][j] = a[j][i] );
00061 assert( b[i][j] = b[j][i] );
00062 }
00063 }
00064
00065 mK = k;
00066 mA = a;
00067 mB = b;
00068
00069 for (unsigned M=0; M<DIM; M++)
00070 {
00071 for (unsigned N=0; N<DIM; N++)
00072 {
00073 mIdentity(M,N) = M==N ? 1.0 : 0.0;
00074 }
00075 }
00076 }
00077
00078 template<unsigned DIM>
00079 PoleZeroMaterialLaw<DIM>::PoleZeroMaterialLaw(std::vector<std::vector<double> > k,
00080 std::vector<std::vector<double> > a,
00081 std::vector<std::vector<double> > b)
00082 {
00083 SetParameters(k,a,b);
00084 mpChangeOfBasisMatrix = NULL;
00085 }
00086
00087
00088 template<unsigned DIM>
00089 void PoleZeroMaterialLaw<DIM>::ComputeStressAndStressDerivative(c_matrix<double,DIM,DIM>& rC,
00090 c_matrix<double,DIM,DIM>& rInvC,
00091 double pressure,
00092 c_matrix<double,DIM,DIM>& rT,
00093 FourthOrderTensor<DIM>& rDTdE,
00094 bool computeDTdE)
00095 {
00096
00097 static c_matrix<double,DIM,DIM> C_transformed;
00098 static c_matrix<double,DIM,DIM> invC_transformed;
00099
00100
00101
00102
00103
00104
00105
00106 if(mpChangeOfBasisMatrix)
00107 {
00108
00109 C_transformed = prod(trans(*mpChangeOfBasisMatrix),(c_matrix<double,DIM,DIM>)prod(rC,*mpChangeOfBasisMatrix));
00110 invC_transformed = prod(trans(*mpChangeOfBasisMatrix),(c_matrix<double,DIM,DIM>)prod(rInvC,*mpChangeOfBasisMatrix));
00111 }
00112 else
00113 {
00114 C_transformed = rC;
00115 invC_transformed = rInvC;
00116 }
00117
00118
00119
00120 c_matrix<double,DIM,DIM> E = 0.5*(C_transformed - mIdentity);
00121
00122 for (unsigned M=0; M<DIM; M++)
00123 {
00124 for (unsigned N=0; N<DIM; N++)
00125 {
00126 double e = E(M,N);
00127
00128 {
00129 double b = mB[M][N];
00130 double a = mA[M][N];
00131 double k = mK[M][N];
00132
00133
00134 if(e>=a)
00135 {
00136 EXCEPTION("E_{MN} >= a_{MN} - strain unacceptably large for model");
00137 }
00138
00139 rT(M,N) = k
00140 * e
00141 * (2*(a-e) + b*e)
00142 * pow(a-e,-b-1)
00143 - pressure*invC_transformed(M,N);
00144 }
00145
00146
00147
00148
00149 }
00150 }
00151
00152 if (computeDTdE)
00153 {
00154 for (unsigned M=0; M<DIM; M++)
00155 {
00156 for (unsigned N=0; N<DIM; N++)
00157 {
00158 for (unsigned P=0; P<DIM; P++)
00159 {
00160 for (unsigned Q=0; Q<DIM; Q++)
00161 {
00162 rDTdE(M,N,P,Q) = 2 * pressure * invC_transformed(M,P) * invC_transformed(Q,N);
00163 }
00164 }
00165
00166 double e = E(M,N);
00167
00168 {
00169 double b = mB[M][N];
00170 double a = mA[M][N];
00171 double k = mK[M][N];
00172
00173 rDTdE(M,N,M,N) += k
00174 * pow(a-e, -b-2)
00175 * (
00176 2*(a-e)*(a-e)
00177 + 4*b*e*(a-e)
00178 + b*(b+1)*e*e
00179 );
00180 }
00181 }
00182 }
00183 }
00184
00185
00186
00187 if(mpChangeOfBasisMatrix)
00188 {
00189 static c_matrix<double,DIM,DIM> T_transformed_times_Ptrans;
00190 T_transformed_times_Ptrans = prod(rT, trans(*mpChangeOfBasisMatrix));
00191
00192 rT = prod(*mpChangeOfBasisMatrix, T_transformed_times_Ptrans);
00193
00194
00195 if (computeDTdE)
00196 {
00197 static FourthOrderTensor<DIM> temp;
00198 temp.SetAsProduct(rDTdE, *mpChangeOfBasisMatrix, 0);
00199 rDTdE.SetAsProduct(temp, *mpChangeOfBasisMatrix, 1);
00200 temp.SetAsProduct(rDTdE, *mpChangeOfBasisMatrix, 2);
00201 rDTdE.SetAsProduct(temp, *mpChangeOfBasisMatrix, 3);
00202 }
00203 }
00204
00205 }
00206
00207 template<unsigned DIM>
00208 double PoleZeroMaterialLaw<DIM>::GetZeroStrainPressure()
00209 {
00210 return 0.0;
00211 }
00212
00213 template<unsigned DIM>
00214 void PoleZeroMaterialLaw<DIM>::ScaleMaterialParameters(double scaleFactor)
00215 {
00216 assert(scaleFactor > 0.0);
00217 for (unsigned i=0; i<mK.size(); i++)
00218 {
00219 for (unsigned j=0; j<mK[i].size(); j++)
00220 {
00221 mK[i][j] /= scaleFactor;
00222 }
00223 }
00224 }
00225
00226
00228
00230
00231 template class PoleZeroMaterialLaw<2>;
00232 template class PoleZeroMaterialLaw<3>;