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 }
00035
00036 template<unsigned DIM>
00037 void PoleZeroMaterialLaw<DIM>::SetParameters(std::vector<std::vector<double> > k,
00038 std::vector<std::vector<double> > a,
00039 std::vector<std::vector<double> > b)
00040 {
00041 if (DIM!=2 && DIM !=3)
00042 {
00043 EXCEPTION("Can only have a 2 or 3d incompressible pole-zero law");
00044 }
00045
00046 assert(k.size()==DIM);
00047 assert(a.size()==DIM);
00048 assert(b.size()==DIM);
00049
00050 for (unsigned i=0; i<DIM; i++)
00051 {
00052 assert(k[i].size()==DIM);
00053 assert(a[i].size()==DIM);
00054 assert(b[i].size()==DIM);
00055
00056 for (unsigned j=0; j<DIM; j++)
00057 {
00058 assert( k[i][j] = k[j][i] );
00059 assert( a[i][j] = a[j][i] );
00060 assert( b[i][j] = b[j][i] );
00061 }
00062 }
00063
00064 mK = k;
00065 mA = a;
00066 mB = b;
00067
00068 for (unsigned M=0; M<DIM; M++)
00069 {
00070 for (unsigned N=0; N<DIM; N++)
00071 {
00072 mIdentity(M,N) = M==N ? 1.0 : 0.0;
00073 }
00074 }
00075 }
00076
00077 template<unsigned DIM>
00078 PoleZeroMaterialLaw<DIM>::PoleZeroMaterialLaw(std::vector<std::vector<double> > k,
00079 std::vector<std::vector<double> > a,
00080 std::vector<std::vector<double> > b)
00081 {
00082 SetParameters(k,a,b);
00083 }
00084
00085 template<unsigned DIM>
00086 void PoleZeroMaterialLaw<DIM>::ComputeStressAndStressDerivative(c_matrix<double,DIM,DIM>& rC,
00087 c_matrix<double,DIM,DIM>& rInvC,
00088 double pressure,
00089 c_matrix<double,DIM,DIM>& rT,
00090 FourthOrderTensor<DIM>& rDTdE,
00091 bool computeDTdE)
00092 {
00093 assert(fabs(rC(0,1) - rC(1,0)) < 1e-6);
00094
00095 c_matrix<double,DIM,DIM> E = 0.5*(rC - mIdentity);
00096
00097 for (unsigned M=0; M<DIM; M++)
00098 {
00099 for (unsigned N=0; N<DIM; N++)
00100 {
00101 double e = E(M,N);
00102
00103 {
00104 double b = mB[M][N];
00105 double a = mA[M][N];
00106 double k = mK[M][N];
00107
00108
00109 assert(e < a);
00110
00111 rT(M,N) = k
00112 * e
00113 * (2*(a-e) + b*e)
00114 * pow(a-e,-b-1)
00115 - pressure*rInvC(M,N);
00116 }
00117
00118
00119
00120
00121 }
00122 }
00123
00124 if (computeDTdE)
00125 {
00126 for (unsigned M=0; M<DIM; M++)
00127 {
00128 for (unsigned N=0; N<DIM; N++)
00129 {
00130 for (unsigned P=0; P<DIM; P++)
00131 {
00132 for (unsigned Q=0; Q<DIM; Q++)
00133 {
00134 rDTdE(M,N,P,Q) = 2 * pressure * rInvC(M,P) * rInvC(Q,N);
00135 }
00136 }
00137
00138 double e = E(M,N);
00139
00140 {
00141 double b = mB[M][N];
00142 double a = mA[M][N];
00143 double k = mK[M][N];
00144
00145 rDTdE(M,N,M,N) += k
00146 * pow(a-e, -b-2)
00147 * (
00148 2*(a-e)*(a-e)
00149 + 4*b*e*(a-e)
00150 + b*(b+1)*e*e
00151 );
00152 }
00153 }
00154 }
00155 }
00156 }
00157
00158 template<unsigned DIM>
00159 double PoleZeroMaterialLaw<DIM>::GetZeroStrainPressure()
00160 {
00161 return 0.0;
00162 }
00163
00164 template<unsigned DIM>
00165 void PoleZeroMaterialLaw<DIM>::ScaleMaterialParameters(double scaleFactor)
00166 {
00167 assert(scaleFactor > 0.0);
00168 for (unsigned i=0; i<mK.size(); i++)
00169 {
00170 for (unsigned j=0; j<mK[i].size(); j++)
00171 {
00172 mK[i][j] /= scaleFactor;
00173 }
00174 }
00175 }
00176
00177
00179
00181
00182 template class PoleZeroMaterialLaw<2>;
00183 template class PoleZeroMaterialLaw<3>;