MFEM  v3.3.2
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
nonlininteg.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #include "fem.hpp"
13 
14 namespace mfem
15 {
16 
18  const FiniteElement &el, ElementTransformation &Tr,
19  const Vector &elfun, Vector &elvect)
20 {
21  mfem_error("NonlinearFormIntegrator::AssembleElementVector"
22  " is not overloaded!");
23 }
24 
26  const FiniteElement &el1, const FiniteElement &el2,
27  FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect)
28 {
29  mfem_error("NonlinearFormIntegrator::AssembleFaceVector"
30  " is not overloaded!");
31 }
32 
34  const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun,
35  DenseMatrix &elmat)
36 {
37  mfem_error("NonlinearFormIntegrator::AssembleElementGrad"
38  " is not overloaded!");
39 }
40 
42  const FiniteElement &el1, const FiniteElement &el2,
43  FaceElementTransformations &Tr, const Vector &elfun,
44  DenseMatrix &elmat)
45 {
46  mfem_error("NonlinearFormIntegrator::AssembleElementGrad"
47  " is not overloaded!");
48 }
49 
50 
52  const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun)
53 {
54  mfem_error("NonlinearFormIntegrator::GetElementEnergy"
55  " is not overloaded!");
56  return 0.0;
57 }
58 
60 {
61  Z.SetSize(J.Width());
63  return 0.5*(Z*Z)/J.Det();
64 }
65 
67 {
68  int dim = J.Width();
69  double t;
70 
71  Z.SetSize(dim);
72  S.SetSize(dim);
74  MultAAt(Z, S);
75  t = 0.5*S.Trace();
76  for (int i = 0; i < dim; i++)
77  {
78  S(i,i) -= t;
79  }
80  t = J.Det();
81  S *= -1.0/(t*t);
82  Mult(S, Z, P);
83 }
84 
86  const DenseMatrix &J, const DenseMatrix &DS, const double weight,
87  DenseMatrix &A) const
88 {
89  int dof = DS.Height(), dim = DS.Width();
90  double t;
91 
92  Z.SetSize(dim);
93  S.SetSize(dim);
94  G.SetSize(dof, dim);
95  C.SetSize(dof, dim);
96 
98  MultAAt(Z, S);
99 
100  t = 1.0/J.Det();
101  Z *= t; // Z = J^{-t}
102  S *= t; // S = |J| (J.J^t)^{-1}
103  t = 0.5*S.Trace();
104 
105  MultABt(DS, Z, G); // G = DS.J^{-1}
106  Mult(G, S, C);
107 
108  // 1.
109  for (int i = 0; i < dof; i++)
110  for (int j = 0; j <= i; j++)
111  {
112  double a = 0.0;
113  for (int d = 0; d < dim; d++)
114  {
115  a += G(i,d)*G(j,d);
116  }
117  a *= weight;
118  for (int k = 0; k < dim; k++)
119  for (int l = 0; l <= k; l++)
120  {
121  double b = a*S(k,l);
122  A(i+k*dof,j+l*dof) += b;
123  if (i != j)
124  {
125  A(j+k*dof,i+l*dof) += b;
126  }
127  if (k != l)
128  {
129  A(i+l*dof,j+k*dof) += b;
130  if (i != j)
131  {
132  A(j+l*dof,i+k*dof) += b;
133  }
134  }
135  }
136  }
137 
138  // 2.
139  for (int i = 1; i < dof; i++)
140  for (int j = 0; j < i; j++)
141  {
142  for (int k = 1; k < dim; k++)
143  for (int l = 0; l < k; l++)
144  {
145  double a =
146  weight*(C(i,l)*G(j,k) - C(i,k)*G(j,l) +
147  C(j,k)*G(i,l) - C(j,l)*G(i,k) +
148  t*(G(i,k)*G(j,l) - G(i,l)*G(j,k)));
149 
150  A(i+k*dof,j+l*dof) += a;
151  A(j+l*dof,i+k*dof) += a;
152 
153  A(i+l*dof,j+k*dof) -= a;
154  A(j+k*dof,i+l*dof) -= a;
155  }
156  }
157 }
158 
159 
160 inline void NeoHookeanModel::EvalCoeffs() const
161 {
162  mu = c_mu->Eval(*Ttr, Ttr->GetIntPoint());
163  K = c_K->Eval(*Ttr, Ttr->GetIntPoint());
164  if (c_g)
165  {
166  g = c_g->Eval(*Ttr, Ttr->GetIntPoint());
167  }
168 }
169 
170 double NeoHookeanModel::EvalW(const DenseMatrix &J) const
171 {
172  int dim = J.Width();
173 
174  if (have_coeffs)
175  {
176  EvalCoeffs();
177  }
178 
179  double dJ = J.Det();
180  double sJ = dJ/g;
181  double bI1 = pow(dJ, -2.0/dim)*(J*J); // \bar{I}_1
182 
183  return 0.5*(mu*(bI1 - dim) + K*(sJ - 1.0)*(sJ - 1.0));
184 }
185 
187 {
188  int dim = J.Width();
189 
190  if (have_coeffs)
191  {
192  EvalCoeffs();
193  }
194 
195  Z.SetSize(dim);
197 
198  double dJ = J.Det();
199  double a = mu*pow(dJ, -2.0/dim);
200  double b = K*(dJ/g - 1.0)/g - a*(J*J)/(dim*dJ);
201 
202  P = 0.0;
203  P.Add(a, J);
204  P.Add(b, Z);
205 }
206 
208  const double weight, DenseMatrix &A) const
209 {
210  int dof = DS.Height(), dim = DS.Width();
211 
212  if (have_coeffs)
213  {
214  EvalCoeffs();
215  }
216 
217  Z.SetSize(dim);
218  G.SetSize(dof, dim);
219  C.SetSize(dof, dim);
220 
221  double dJ = J.Det();
222  double sJ = dJ/g;
223  double a = mu*pow(dJ, -2.0/dim);
224  double bc = a*(J*J)/dim;
225  double b = bc - K*sJ*(sJ - 1.0);
226  double c = 2.0*bc/dim + K*sJ*(2.0*sJ - 1.0);
227 
229  Z *= (1.0/dJ); // Z = J^{-t}
230 
231  MultABt(DS, J, C); // C = DS J^t
232  MultABt(DS, Z, G); // G = DS J^{-1}
233 
234  a *= weight;
235  b *= weight;
236  c *= weight;
237 
238  // 1.
239  for (int i = 0; i < dof; i++)
240  for (int k = 0; k <= i; k++)
241  {
242  double s = 0.0;
243  for (int d = 0; d < dim; d++)
244  {
245  s += DS(i,d)*DS(k,d);
246  }
247  s *= a;
248 
249  for (int d = 0; d < dim; d++)
250  {
251  A(i+d*dof,k+d*dof) += s;
252  }
253 
254  if (k != i)
255  for (int d = 0; d < dim; d++)
256  {
257  A(k+d*dof,i+d*dof) += s;
258  }
259  }
260 
261  a *= (-2.0/dim);
262 
263  // 2.
264  for (int i = 0; i < dof; i++)
265  for (int j = 0; j < dim; j++)
266  for (int k = 0; k < dof; k++)
267  for (int l = 0; l < dim; l++)
268  {
269  A(i+j*dof,k+l*dof) +=
270  a*(C(i,j)*G(k,l) + G(i,j)*C(k,l)) +
271  b*G(i,l)*G(k,j) + c*G(i,j)*G(k,l);
272  }
273 }
274 
277  const Vector &elfun)
278 {
279  int dof = el.GetDof(), dim = el.GetDim();
280  double energy;
281 
282  DSh.SetSize(dof, dim);
283  Jrt.SetSize(dim);
284  Jpr.SetSize(dim);
285  Jpt.SetSize(dim);
286  PMatI.UseExternalData(elfun.GetData(), dof, dim);
287 
288  const IntegrationRule *ir = IntRule;
289  if (!ir)
290  {
291  ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
292  }
293 
294  energy = 0.0;
295  model->SetTransformation(Ttr);
296  for (int i = 0; i < ir->GetNPoints(); i++)
297  {
298  const IntegrationPoint &ip = ir->IntPoint(i);
299  Ttr.SetIntPoint(&ip);
300  CalcInverse(Ttr.Jacobian(), Jrt);
301 
302  el.CalcDShape(ip, DSh);
303  MultAtB(PMatI, DSh, Jpr);
304  Mult(Jpr, Jrt, Jpt);
305 
306  energy += ip.weight * Ttr.Weight() * model->EvalW(Jpt);
307  }
308 
309  return energy;
310 }
311 
313  const FiniteElement &el, ElementTransformation &Ttr,
314  const Vector &elfun, Vector &elvect)
315 {
316  int dof = el.GetDof(), dim = el.GetDim();
317 
318  DSh.SetSize(dof, dim);
319  DS.SetSize(dof, dim);
320  Jrt.SetSize(dim);
321  Jpt.SetSize(dim);
322  P.SetSize(dim);
323  PMatI.UseExternalData(elfun.GetData(), dof, dim);
324  elvect.SetSize(dof*dim);
325  PMatO.UseExternalData(elvect.GetData(), dof, dim);
326 
327  const IntegrationRule *ir = IntRule;
328  if (!ir)
329  {
330  ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
331  }
332 
333  elvect = 0.0;
334  model->SetTransformation(Ttr);
335  for (int i = 0; i < ir->GetNPoints(); i++)
336  {
337  const IntegrationPoint &ip = ir->IntPoint(i);
338  Ttr.SetIntPoint(&ip);
339  CalcInverse(Ttr.Jacobian(), Jrt);
340 
341  el.CalcDShape(ip, DSh);
342  Mult(DSh, Jrt, DS);
343  MultAtB(PMatI, DS, Jpt);
344 
345  model->EvalP(Jpt, P);
346 
347  P *= ip.weight * Ttr.Weight();
348  AddMultABt(DS, P, PMatO);
349  }
350 }
351 
354  const Vector &elfun,
355  DenseMatrix &elmat)
356 {
357  int dof = el.GetDof(), dim = el.GetDim();
358 
359  DSh.SetSize(dof, dim);
360  DS.SetSize(dof, dim);
361  Jrt.SetSize(dim);
362  Jpt.SetSize(dim);
363  PMatI.UseExternalData(elfun.GetData(), dof, dim);
364  elmat.SetSize(dof*dim);
365 
366  const IntegrationRule *ir = IntRule;
367  if (!ir)
368  {
369  ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
370  }
371 
372  elmat = 0.0;
373  model->SetTransformation(Ttr);
374  for (int i = 0; i < ir->GetNPoints(); i++)
375  {
376  const IntegrationPoint &ip = ir->IntPoint(i);
377  Ttr.SetIntPoint(&ip);
378  CalcInverse(Ttr.Jacobian(), Jrt);
379 
380  el.CalcDShape(ip, DSh);
381  Mult(DSh, Jrt, DS);
382  MultAtB(PMatI, DS, Jpt);
383 
384  model->AssembleH(Jpt, DS, ip.weight * Ttr.Weight(), elmat);
385  }
386 }
387 
388 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:222
Abstract class for Finite Elements.
Definition: fe.hpp:47
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
Definition: densemat.cpp:3362
virtual void EvalP(const DenseMatrix &J, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
virtual double EvalW(const DenseMatrix &J) const
Evaluate the strain energy density function, W = W(Jpt).
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:116
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:83
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:861
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:320
virtual void AssembleH(const DenseMatrix &J, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: nonlininteg.cpp:85
double Det() const
Definition: densemat.cpp:435
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:468
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:42
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:52
int GetOrder() const
Returns the order of the finite element.
Definition: fe.hpp:125
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
virtual double EvalW(const DenseMatrix &Jpt) const =0
Evaluate the strain energy density function, W = W(Jpt).
virtual void EvalP(const DenseMatrix &J, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: nonlininteg.cpp:66
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:54
double * GetData() const
Definition: vector.hpp:121
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const =0
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:225
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:3120
int dim
Definition: ex3.cpp:47
void EvalCoeffs() const
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:36
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
Definition: densemat.cpp:528
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint, using the method SetIntPoint().
Definition: eltrans.hpp:67
virtual void AssembleFaceGrad(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, DenseMatrix &elmat)
Assemble the local action of the gradient of the NonlinearFormIntegrator resulting from a face integr...
Definition: nonlininteg.cpp:41
virtual void AssembleElementGrad(const FiniteElement &el, ElementTransformation &Ttr, const Vector &elfun, DenseMatrix &elmat)
Assemble the local gradient matrix.
virtual void AssembleElementVector(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, Vector &elvect)
Perform the local action of the NonlinearFormIntegrator.
Definition: nonlininteg.cpp:17
virtual double GetElementEnergy(const FiniteElement &el, ElementTransformation &Ttr, const Vector &elfun)
Computes the integral of W(Jacobian(Trt)) over a target zone.
void SetTransformation(ElementTransformation &_Ttr)
Definition: nonlininteg.hpp:90
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3156
int GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:119
virtual void AssembleElementGrad(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun, DenseMatrix &elmat)
Assemble the local gradient matrix.
Definition: nonlininteg.cpp:33
double Trace() const
Trace of a square matrix.
Definition: densemat.cpp:411
void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
Definition: densemat.cpp:3485
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:122
void mfem_error(const char *msg)
Definition: error.cpp:107
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
Definition: densemat.cpp:3304
virtual void AssembleFaceVector(const FiniteElement &el1, const FiniteElement &el2, FaceElementTransformations &Tr, const Vector &elfun, Vector &elvect)
Perform the local action of the NonlinearFormIntegrator resulting from a face integral term...
Definition: nonlininteg.cpp:25
ElementTransformation * Ttr
Definition: nonlininteg.hpp:79
const IntegrationRule * IntRule
Definition: nonlininteg.hpp:29
virtual void AssembleH(const DenseMatrix &J, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Class for integration point with weight.
Definition: intrules.hpp:25
virtual double EvalW(const DenseMatrix &J) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: nonlininteg.cpp:59
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const =0
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
virtual void AssembleElementVector(const FiniteElement &el, ElementTransformation &Ttr, const Vector &elfun, Vector &elvect)
Perform the local action of the NonlinearFormIntegrator.
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
Definition: densemat.cpp:3637
Vector data type.
Definition: vector.hpp:41
virtual double GetElementEnergy(const FiniteElement &el, ElementTransformation &Tr, const Vector &elfun)
Compute the local energy.
Definition: nonlininteg.cpp:51
void UseExternalData(double *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition: densemat.hpp:64
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:86
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:343