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
00032 template<unsigned DIM>
00033 PoleZeroMaterialLaw<DIM>::PoleZeroMaterialLaw()
00034 {
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 }
00085
00086
00087 template<unsigned DIM>
00088 void PoleZeroMaterialLaw<DIM>::ComputeStressAndStressDerivative(c_matrix<double,DIM,DIM>& rC,
00089 c_matrix<double,DIM,DIM>& rInvC,
00090 double pressure,
00091 c_matrix<double,DIM,DIM>& rT,
00092 FourthOrderTensor<DIM,DIM,DIM,DIM>& rDTdE,
00093 bool computeDTdE)
00094 {
00095 static c_matrix<double,DIM,DIM> C_transformed;
00096 static c_matrix<double,DIM,DIM> invC_transformed;
00097
00098
00099
00100
00101
00102
00103
00104 ComputeTransformedDeformationTensor(rC, rInvC, C_transformed, invC_transformed);
00105
00106
00107
00108
00109 c_matrix<double,DIM,DIM> E = 0.5*(C_transformed - mIdentity);
00110
00111 for (unsigned M=0; M<DIM; M++)
00112 {
00113 for (unsigned N=0; N<DIM; N++)
00114 {
00115 double e = E(M,N);
00116
00117 {
00118 double b = mB[M][N];
00119 double a = mA[M][N];
00120 double k = mK[M][N];
00121
00122
00123 if(e>=a)
00124 {
00125 EXCEPTION("E_{MN} >= a_{MN} - strain unacceptably large for model");
00126 }
00127
00128 rT(M,N) = k
00129 * e
00130 * (2*(a-e) + b*e)
00131 * pow(a-e,-b-1)
00132 - pressure*invC_transformed(M,N);
00133 }
00134
00135
00136
00137
00138 }
00139 }
00140
00141 if (computeDTdE)
00142 {
00143 for (unsigned M=0; M<DIM; M++)
00144 {
00145 for (unsigned N=0; N<DIM; N++)
00146 {
00147 for (unsigned P=0; P<DIM; P++)
00148 {
00149 for (unsigned Q=0; Q<DIM; Q++)
00150 {
00151 rDTdE(M,N,P,Q) = 2 * pressure * invC_transformed(M,P) * invC_transformed(Q,N);
00152 }
00153 }
00154
00155 double e = E(M,N);
00156
00157 {
00158 double b = mB[M][N];
00159 double a = mA[M][N];
00160 double k = mK[M][N];
00161
00162 rDTdE(M,N,M,N) += k
00163 * pow(a-e, -b-2)
00164 * (
00165 2*(a-e)*(a-e)
00166 + 4*b*e*(a-e)
00167 + b*(b+1)*e*e
00168 );
00169 }
00170 }
00171 }
00172 }
00173
00174
00175
00176 this->TransformStressAndStressDerivative(rT, rDTdE, computeDTdE);
00177 }
00178
00179 template<unsigned DIM>
00180 double PoleZeroMaterialLaw<DIM>::GetZeroStrainPressure()
00181 {
00182 return 0.0;
00183 }
00184
00185 template<unsigned DIM>
00186 void PoleZeroMaterialLaw<DIM>::ScaleMaterialParameters(double scaleFactor)
00187 {
00188 assert(scaleFactor > 0.0);
00189 for (unsigned i=0; i<mK.size(); i++)
00190 {
00191 for (unsigned j=0; j<mK[i].size(); j++)
00192 {
00193 mK[i][j] /= scaleFactor;
00194 }
00195 }
00196 }
00197
00198
00200
00202
00203 template class PoleZeroMaterialLaw<2>;
00204 template class PoleZeroMaterialLaw<3>;