MFEM  v3.3
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
eltrans.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 "../mesh/mesh_headers.hpp"
13 #include "fem.hpp"
14 #include <cmath>
15 
16 namespace mfem
17 {
18 
20  : IntPoint(static_cast<IntegrationPoint *>(NULL)),
21  EvalState(0),
22  Attribute(-1),
23  ElementNo(-1)
24 { }
25 
27 {
28  MFEM_ASSERT((EvalState & WEIGHT_MASK) == 0, "");
29  Jacobian();
31  return (Wght = (dFdx.Width() == 0) ? 1.0 : dFdx.Weight());
32 }
33 
35 {
36  MFEM_ASSERT((EvalState & ADJUGATE_MASK) == 0, "");
37  Jacobian();
39  if (dFdx.Width() > 0) { CalcAdjugate(dFdx, adjJ); }
41  return adjJ;
42 }
43 
45 {
46  // TODO: compute as invJ = / adjJ/Weight, if J is square,
47  // \ adjJ/Weight^2, otherwise.
48  MFEM_ASSERT((EvalState & INVERSE_MASK) == 0, "");
49  Jacobian();
51  if (dFdx.Width() > 0) { CalcInverse(dFdx, invJ); }
53  return invJ;
54 }
55 
57 {
58  switch (GeomType)
59  {
60  case Geometry::POINT : FElem = &PointFE; break;
61  case Geometry::SEGMENT : FElem = &SegmentFE; break;
62  case Geometry::TRIANGLE : FElem = &TriangleFE; break;
63  case Geometry::SQUARE : FElem = &QuadrilateralFE; break;
64  case Geometry::TETRAHEDRON : FElem = &TetrahedronFE; break;
65  case Geometry::CUBE : FElem = &HexahedronFE; break;
66  default:
67  MFEM_ABORT("unknown Geometry::Type!");
68  }
69  int dim = FElem->GetDim();
70  int dof = FElem->GetDof();
71  const IntegrationRule &nodes = FElem->GetNodes();
72  PointMat.SetSize(dim, dof);
73  for (int j = 0; j < dof; j++)
74  {
75  nodes.IntPoint(j).Get(&PointMat(0,j), dim);
76  }
77 }
78 
79 const DenseMatrix &IsoparametricTransformation::EvalJacobian()
80 {
81  MFEM_ASSERT((EvalState & JACOBIAN_MASK) == 0, "");
82 
83  dshape.SetSize(FElem->GetDof(), FElem->GetDim());
84  dFdx.SetSize(PointMat.Height(), dshape.Width());
85  if (dshape.Width() > 0)
86  {
87  FElem->CalcDShape(*IntPoint, dshape);
88  Mult(PointMat, dshape, dFdx);
89  }
91 
92  return dFdx;
93 }
94 
96 {
97  switch (FElem->Space())
98  {
99  case FunctionSpace::Pk:
100  return (FElem->GetOrder()-1);
101  case FunctionSpace::Qk:
102  return (FElem->GetOrder());
103  default:
104  mfem_error("IsoparametricTransformation::OrderJ()");
105  }
106  return 0;
107 }
108 
110 {
111  switch (FElem->Space())
112  {
113  case FunctionSpace::Pk:
114  return (FElem->GetOrder() - 1) * FElem->GetDim();
115  case FunctionSpace::Qk:
116  return (FElem->GetOrder() * FElem->GetDim() - 1);
117  default:
118  mfem_error("IsoparametricTransformation::OrderW()");
119  }
120  return 0;
121 }
122 
124 {
125  if (FElem->Space() == fe->Space())
126  {
127  int k = FElem->GetOrder();
128  int d = FElem->GetDim();
129  int l = fe->GetOrder();
130  switch (fe->Space())
131  {
132  case FunctionSpace::Pk:
133  return ((k-1)*(d-1)+(l-1));
134  case FunctionSpace::Qk:
135  return (k*(d-1)+(l-1));
136  }
137  }
138  mfem_error("IsoparametricTransformation::OrderGrad(...)");
139  return 0;
140 }
141 
143  Vector &trans)
144 {
145  shape.SetSize(FElem->GetDof());
146  trans.SetSize(PointMat.Height());
147 
148  FElem -> CalcShape(ip, shape);
149  PointMat.Mult(shape, trans);
150 }
151 
153  DenseMatrix &tr)
154 {
155  int dof, n, dim, i, j, k;
156 
157  dim = PointMat.Height();
158  dof = FElem->GetDof();
159  n = ir.GetNPoints();
160 
161  shape.SetSize(dof);
162  tr.SetSize(dim, n);
163 
164  for (j = 0; j < n; j++)
165  {
166  FElem -> CalcShape (ir.IntPoint(j), shape);
167  for (i = 0; i < dim; i++)
168  {
169  tr(i, j) = 0.0;
170  for (k = 0; k < dof; k++)
171  {
172  tr(i, j) += PointMat(i, k) * shape(k);
173  }
174  }
175  }
176 }
177 
179  DenseMatrix &result)
180 {
181  result.SetSize(PointMat.Height(), matrix.Width());
182 
183  IntegrationPoint ip;
184  Vector col;
185 
186  for (int j = 0; j < matrix.Width(); j++)
187  {
188  ip.x = matrix(0, j);
189  if (matrix.Height() > 1)
190  {
191  ip.y = matrix(1, j);
192  if (matrix.Height() > 2)
193  {
194  ip.z = matrix(2, j);
195  }
196  }
197 
198  result.GetColumnReference(j, col);
199  Transform(ip, col);
200  }
201 }
202 
204  IntegrationPoint &ip)
205 {
206  const int max_iter = 16;
207  const double ref_tol = 1e-15;
208  const double phys_tol = 1e-15*pt.Normlinf();
209 
210  const int dim = FElem->GetDim();
211  const int sdim = PointMat.Height();
212  const int geom = FElem->GetGeomType();
213  IntegrationPoint xip, prev_xip;
214  double xd[3], yd[3], dxd[3], Jid[9];
215  Vector x(xd, dim), y(yd, sdim), dx(dxd, dim);
216  DenseMatrix Jinv(Jid, dim, sdim);
217  bool hit_bdr = false, prev_hit_bdr;
218 
219  // Use the center of the element as initial guess
220  xip = Geometries.GetCenter(geom);
221  xip.Get(xd, dim); // xip -> x
222 
223  for (int it = 0; it < max_iter; it++)
224  {
225  // Newton iteration: x := x + J(x)^{-1} [pt-F(x)]
226  // or when dim != sdim: x := x + [J^t.J]^{-1}.J^t [pt-F(x)]
227  Transform(xip, y);
228  subtract(pt, y, y); // y = pt-y
229  if (y.Normlinf() < phys_tol) { ip = xip; return 0; }
230  SetIntPoint(&xip);
231  CalcInverse(Jacobian(), Jinv);
232  Jinv.Mult(y, dx);
233  x += dx;
234  prev_xip = xip;
235  prev_hit_bdr = hit_bdr;
236  xip.Set(xd, dim); // x -> xip
237  // If xip is ouside project it on the boundary on the line segment
238  // between prev_xip and xip
239  hit_bdr = !Geometry::ProjectPoint(geom, prev_xip, xip);
240  if (dx.Normlinf() < ref_tol) { ip = xip; return 0; }
241  if (hit_bdr)
242  {
243  xip.Get(xd, dim); // xip -> x
244  if (prev_hit_bdr)
245  {
246  prev_xip.Get(dxd, dim); // prev_xip -> dx
247  subtract(x, dx, dx); // dx = xip - prev_xip
248  if (dx.Normlinf() < ref_tol) { return 1; }
249  }
250  }
251  }
252  ip = xip;
253  return 2;
254 }
255 
257  IntegrationPoint &ip2)
258 {
259  double vec[3];
260  Vector v (vec, Transf.GetPointMat().Height());
261 
262  Transf.Transform (ip1, v);
263  ip2.Set(vec, v.Size());
264 }
265 
267  IntegrationRule &ir2)
268 {
269  int i, n;
270 
271  n = ir1.GetNPoints();
272  for (i = 0; i < n; i++)
273  {
274  Transform (ir1.IntPoint(i), ir2.IntPoint(i));
275  }
276 }
277 
278 }
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:46
void Set(const double *p, const int dim)
Definition: intrules.hpp:32
void Get(double *p, const int dim) const
Definition: intrules.hpp:45
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:115
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:83
DenseMatrix & GetPointMat()
Read and write access to the underlying point matrix describing the transformation.
Definition: eltrans.hpp:122
const IntegrationPoint * IntPoint
Definition: eltrans.hpp:26
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:310
const Geometry::Type geom
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:51
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
Definition: densemat.cpp:2902
void SetIdentityTransformation(int GeomType)
Definition: eltrans.cpp:56
int GetOrder() const
Returns the order of the finite element.
Definition: fe.hpp:124
Data type dense matrix using column-major storage.
Definition: densemat.hpp:22
virtual int TransformBack(const Vector &, IntegrationPoint &)
Definition: eltrans.cpp:203
Polynomials of order k.
Definition: fe.hpp:34
const DenseMatrix & EvalAdjugateJ()
Definition: eltrans.cpp:34
int Space() const
Returns the type of space on each element.
Definition: fe.hpp:127
double Normlinf() const
Returns the l_infinity norm of the vector.
Definition: vector.cpp:672
virtual void Transform(const IntegrationPoint &, Vector &)
Definition: eltrans.cpp:142
const IntegrationPoint & GetCenter(int GeomType)
Definition: geom.hpp:57
double Weight() const
Definition: densemat.cpp:443
PointFiniteElement PointFE
Definition: point.cpp:30
Geometry Geometries
Definition: geom.cpp:544
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:225
int dim
Definition: ex3.cpp:47
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:36
virtual int OrderGrad(const FiniteElement *fe)
order of adj(J)^t.grad(fi)
Definition: eltrans.cpp:123
const DenseMatrix & Jacobian()
Definition: eltrans.hpp:64
TriLinear3DFiniteElement HexahedronFE
Definition: hexahedron.cpp:52
const IntegrationRule & GetNodes() const
Definition: fe.hpp:166
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3010
int GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:118
const DenseMatrix & EvalInverseJ()
Definition: eltrans.cpp:44
static bool ProjectPoint(int GeomType, const IntegrationPoint &beg, IntegrationPoint &end)
Definition: geom.cpp:317
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:121
void subtract(const Vector &x, const Vector &y, Vector &z)
Definition: vector.cpp:390
void mfem_error(const char *msg)
Definition: error.cpp:106
void Transform(const IntegrationPoint &, IntegrationPoint &)
Definition: eltrans.cpp:256
void GetColumnReference(int c, Vector &col)
Definition: densemat.hpp:217
Linear3DFiniteElement TetrahedronFE
Linear2DFiniteElement TriangleFE
Definition: triangle.cpp:198
Class for integration point with weight.
Definition: intrules.hpp:25
IsoparametricTransformation Transf
Definition: eltrans.hpp:149
Vector data type.
Definition: vector.hpp:36
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:142
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:82
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...
BiLinear2DFiniteElement QuadrilateralFE
Linear1DFiniteElement SegmentFE
Definition: segment.cpp:49
Tensor products of polynomials of order k.
Definition: fe.hpp:35