00001 #ifndef DUNE_P1_LINEAR_ELASTICITY_ASSEMBLER_HH
00002 #define DUNE_P1_LINEAR_ELASTICITY_ASSEMBLER_HH
00003
00004 #include<map>
00005 #include<iostream>
00006 #include<iomanip>
00007 #include<fstream>
00008 #include<vector>
00009 #include<sstream>
00010
00011 #include<dune/common/fvector.hh>
00012 #include<dune/common/fmatrix.hh>
00013 #include<dune/common/exceptions.hh>
00014 #include<dune/grid/common/grid.hh>
00015 #include<dune/grid/common/referenceelements.hh>
00016 #include<dune/istl/operators.hh>
00017 #include<dune/istl/bvector.hh>
00018
00019 #include<dune/grid/common/quadraturerules.hh>
00020 #include<dune/disc/operators/localstiffness.hh>
00021 #include<dune/disc/shapefunctions/lagrangeshapefunctions.hh>
00022 #include<dune/disc/operators/boundaryconditions.hh>
00023
00031 namespace Dune
00032 {
00043
00044
00059 template<class GridView, class RT>
00060 class LinearElasticityLocalStiffness
00061 : public LinearLocalStiffness<GridView,RT,GridView::dimension>
00062 {
00063
00064 typedef typename GridView::Grid::ctype DT;
00065 typedef typename GridView::template Codim<0>::Entity Entity;
00066
00067
00068 enum {dim=GridView::dimension};
00069
00071 typedef FieldVector<double, (dim+1)*dim/2> SymmTensor;
00072
00073 public:
00074
00075
00076 enum {m=dim};
00077
00078
00079 typedef FieldMatrix<RT,m,m> MBlockType;
00080 typedef FieldVector<RT,m> VBlockType;
00081 typedef array<BoundaryConditions::Flags,m> BCBlockType;
00082
00083
00084
00085
00086
00087 double E_;
00088
00089
00090 double nu_;
00091
00092 typedef std::map<std::pair<GeometryType, int>, std::vector<FieldVector<DT,dim> > > CacheType;
00093 CacheType gradientCache_;
00094
00096 LinearElasticityLocalStiffness ()
00097 {}
00098
00100 LinearElasticityLocalStiffness (double E, double nu, bool procBoundaryAsDirichlet_=true)
00101 : E_(E), nu_(nu)
00102 {
00103 procBoundaryAsDirichlet = procBoundaryAsDirichlet_;
00104 }
00105
00107 void setEandNu(double E, double nu)
00108 {
00109 E_ = E;
00110 nu_ = nu;
00111 }
00112
00114
00123 void assemble (const Entity& e, int k=1)
00124 {
00125
00126 GeometryType gt = e.type();
00127 const typename LagrangeShapeFunctionSetContainer<DT,RT,dim>::value_type& sfs
00128 = LagrangeShapeFunctions<DT,RT,dim>::general(gt,k);
00129
00130
00131 setcurrentsize(sfs.size());
00132
00133 for (int i=0; i<sfs.size(); i++)
00134 {
00135 this->b[i] = 0;
00136 for (int j=0; j<this->bctype[i].size(); j++)
00137 this->bctype[i][j] = BoundaryConditions::neumann;
00138 for (int j=0; j<sfs.size(); j++)
00139 this->A[i][j] = 0;
00140 }
00141
00142
00143 int p = (gt.isSimplex())
00144 ? 2*(k-1)
00145 : 2*(k*dim-1);
00146
00147 const std::vector<FieldVector<DT,dim> >* shapeGradients = NULL;
00148
00149 typename CacheType::iterator shapeFunctionGradients = gradientCache_.find(std::make_pair(gt,p));
00150
00151 if (shapeFunctionGradients == gradientCache_.end()) {
00152
00153 std::vector<FieldVector<DT,dim> > newGradientSet(sfs.size() * QuadratureRules<DT,dim>::rule(gt,p).size());
00154
00155 for (size_t g=0; g<Dune::QuadratureRules<DT,dim>::rule(gt,p).size(); ++g) {
00156
00157
00158 const Dune::FieldVector<DT,dim>& quadPos = Dune::QuadratureRules<DT,dim>::rule(gt,p)[g].position();
00159
00160 for (int i=0; i<sfs.size(); i++) {
00161
00162 for (int l=0; l<dim; l++)
00163 newGradientSet[sfs.size()*g + i][l] = sfs[i].evaluateDerivative(0,l,quadPos);
00164
00165 }
00166
00167 }
00168
00169 gradientCache_.insert(std::make_pair(std::make_pair(gt,p), newGradientSet));
00170
00171 }
00172
00173 shapeGradients = &gradientCache_.find(std::make_pair(gt,p))->second;
00174
00175
00176 for (size_t g=0; g<Dune::QuadratureRules<DT,dim>::rule(gt,p).size(); ++g) {
00177
00178
00179 const Dune::FieldVector<DT,dim>& local = Dune::QuadratureRules<DT,dim>::rule(gt,p)[g].position();
00180
00181
00182 const Dune::FieldMatrix<DT,dim,dim>& jac = e.geometry().jacobianInverseTransposed(local);
00183
00184
00185 double weight = Dune::QuadratureRules<DT,dim>::rule(gt,p)[g].weight();
00186
00187
00188 DT detjac = e.geometry().integrationElement(local);
00189
00190
00191 Dune::FieldVector<DT,dim> grad[sfs.size()], temp, gv;
00192 for (int i=0; i<sfs.size(); i++) {
00193 grad[i] = 0;
00194 jac.umv((*shapeGradients)[sfs.size()*g + i],grad[i]);
00195 }
00196
00197
00198
00199
00200 std::vector<array<SymmTensor,dim> > strain(sfs.size());
00201
00202 for (int i=0; i<sfs.size(); i++)
00203 for (int k=0; k<dim; k++) {
00204
00205
00206 FieldMatrix<double, dim, dim> deformationGradient(0);
00207 deformationGradient[k] = grad[i];
00208
00209
00210 computeStrain(deformationGradient,strain[i][k]);
00211
00212 }
00213
00214
00215 for (int row=0; row<sfs.size(); row++) {
00216
00217 for (int rcomp=0; rcomp<dim; rcomp++) {
00218
00219 SymmTensor stress = hookeTimesStrain(strain[row][rcomp]);
00220
00221 for (int col=0; col<=row; col++) {
00222
00223 for (int ccomp=0; ccomp<dim; ccomp++) {
00224
00225 this->A[row][col][rcomp][ccomp] += stress*strain[col][ccomp] * weight * detjac;
00226
00227 }
00228 }
00229 }
00230
00231 }
00232
00233 }
00234
00235 for (int row=0; row<sfs.size(); row++)
00236 for (int col=0; col<=row; col++) {
00237
00238
00239
00240 if (row!=col) {
00241 for (int rcomp=0; rcomp<dim; rcomp++)
00242 for (int ccomp=0; ccomp<dim; ccomp++)
00243 this->A[col][row][ccomp][rcomp] = this->A[row][col][rcomp][ccomp];
00244 }
00245 }
00246
00247 }
00248
00249
00250 void computeStrain(const FieldMatrix<double, dim, dim>& grad,
00251 SymmTensor& strain) const
00252 {
00253
00254 if (dim==2) {
00255
00256 strain[0] = grad[0][0];
00257 strain[1] = grad[1][1];
00258 strain[2] = grad[0][1] + grad[1][0];
00259
00260 } else if (dim==3) {
00261
00262 strain[0] = grad[0][0];
00263 strain[1] = grad[1][1];
00264 strain[2] = grad[2][2];
00265 strain[3] = grad[0][1] + grad[1][0];
00266 strain[4] = grad[0][2] + grad[2][0];
00267 strain[5] = grad[2][1] + grad[1][2];
00268
00269 } else
00270 DUNE_THROW(NotImplemented, "No elasticity assembler for " << dim << "-dimensional problems");
00271 }
00272
00273
00274 SymmTensor hookeTimesStrain(const SymmTensor& strain) const {
00275
00276 if (dim==3) {
00277
00278
00279 FieldMatrix<double, 6, 6> hookeTensor;
00280
00281 hookeTensor = 0;
00282
00283 hookeTensor[0][0] = 1-nu_;
00284 hookeTensor[0][1] = nu_;
00285 hookeTensor[0][2] = nu_;
00286
00287 hookeTensor[1][0] = nu_;
00288 hookeTensor[1][1] = 1-nu_;
00289 hookeTensor[1][2] = nu_;
00290
00291 hookeTensor[2][0] = nu_;
00292 hookeTensor[2][1] = nu_;
00293 hookeTensor[2][2] = 1-nu_;
00294
00295 hookeTensor[3][3] = 0.5 -nu_;
00296 hookeTensor[4][4] = 0.5 -nu_;
00297 hookeTensor[5][5] = 0.5 -nu_;
00298
00299 hookeTensor *= (E_/(1+nu_)/(1-2*nu_));
00300
00301
00302 SymmTensor stress;
00303 stress = 0;
00304 hookeTensor.umv(strain, stress);
00305
00306 return stress;
00307
00308 } else if (dim==2) {
00309
00310
00311 FieldMatrix<double, 3, 3> hookeTensor;
00312
00313 hookeTensor = 0;
00314
00315 hookeTensor[0][0] = 1-nu_;
00316 hookeTensor[0][1] = nu_;
00317
00318 hookeTensor[1][0] = nu_;
00319 hookeTensor[1][1] = 1-nu_;
00320
00321 hookeTensor[2][2] = 0.5 -nu_;
00322
00323 hookeTensor *= (E_/(1+nu_)/(1-2*nu_));
00324
00325
00326 SymmTensor stress;
00327 stress = 0;
00328 hookeTensor.umv(strain, stress);
00329
00330 return stress;
00331
00332 } else
00333 DUNE_THROW(NotImplemented, "No elasticity assembler for " << dim << "-dimensional problems");
00334
00335 }
00336
00338 void assembleBoundaryCondition (const Entity& e, int k=1)
00339 {
00340 }
00341
00342 private:
00343
00344
00345 bool procBoundaryAsDirichlet;
00346
00347 };
00348
00350 }
00351 #endif