shapefunctions.hpp
Go to the documentation of this file.
1 //==============================================================================
11 //==============================================================================
12 #ifndef SHAPEFUNCTIONS_HPP_
13 #define SHAPEFUNCTIONS_HPP_
14 
15 #include <dune/common/fvector.hh>
16 #include <dune/common/dynmatrixev.hh>
17 
18 #include <complex>
19 #include <array>
20 
21 namespace Opm {
22 namespace Elasticity {
23 
25  template<class ctype, class rtype, int dim>
27 {
28  public:
30  enum { dimension = dim };
31 
33  LinearShapeFunction() : coeff0(0.0), coeff1(0.0) {}
34 
38  LinearShapeFunction(const Dune::FieldVector<rtype,dim>& coeff0_,
39  const Dune::FieldVector<rtype,dim>& coeff1_)
40  : coeff0(coeff0_), coeff1(coeff1_) {}
41 
45  void setCoeff(const Dune::FieldVector<rtype,dim>& coeff0_, const Dune::FieldVector<rtype,dim>& coeff1_)
46  {
47  coeff0 = coeff0_;
48  coeff1 = coeff1_;
49  }
50 
53  rtype evaluateFunction(const Dune::FieldVector<ctype,dim>& local) const
54  {
55  rtype result = 1;
56  for (int i = 0; i < dim; ++i)
57  result *= (coeff0[i]+coeff1[i] * local[i]);
58  return result;
59  }
60 
63  Dune::FieldVector<rtype,dim>
64  evaluateGradient(const Dune::FieldVector<ctype,dim>& local) const
65  {
66  Dune::FieldVector<rtype, dim> result;
67  for (int i=0;i<dim;++i) {
68  result[i] = 1;
69  for (int j=0;j<dim;++j) {
70  if (i == j)
71  result[i] *= coeff1[j];
72  else
73  result[i] *= (coeff0[j]+coeff1[j]*local[j]);
74  }
75  }
76 
77  return result;
78  }
79 
80  private:
82  Dune::FieldVector<rtype,dim> coeff0;
83 
85  Dune::FieldVector<rtype,dim> coeff1;
86 };
87 
89  template<class ctype, class rtype>
91 {
92  public:
95 
99  LagrangeCardinalFunction(const std::vector<rtype>& nodes_,
100  size_t i)
101  : nodes(nodes_), node(i) {}
102 
105  rtype evaluateFunction(const ctype& local) const
106  {
107  rtype result = 1;
108  for (size_t i=0; i < nodes.size(); ++i) {
109  if (i != node)
110  result *= (local-nodes[i])/(nodes[node]-nodes[i]);
111  }
112 
113  return result;
114  }
115 
118  rtype evaluateGradient(const ctype& local) const
119  {
120  rtype result = 0;
121  for (size_t i=0; i < nodes.size(); ++i) {
122  rtype f = 1;
123  for (int j=0; j < nodes.size(); ++j) {
124  if (i != j && j != node)
125  f *= (local-nodes[j])/(nodes[node]-nodes[j]);
126  }
127  result += f/(nodes[node]-nodes[i]);
128  }
129 
130  return result;
131  }
132 
133  private:
135  std::vector<rtype> nodes;
136 
137  size_t node;
138 };
139 
141  template<class rtype, class ctype, class ftype, int dim>
143 {
144  public:
146  enum { dimension = dim };
147 
150 
153  TensorProductFunction(const Dune::FieldVector<ftype, dim>& funcs_)
154  : funcs(funcs_) {}
155 
158  rtype evaluateFunction(const Dune::FieldVector<ctype,dim>& local) const
159  {
160  rtype result = 1;
161  for (int i=0; i < dim; ++i)
162  result *= funcs[i].evaluateFunction(local[i]);
163 
164  return result;
165  }
166 
167  Dune::FieldVector<rtype, dim>
168  evaluateGradient(const Dune::FieldVector<ctype,dim>& local) const
169  {
170  Dune::FieldVector<rtype, dim> result;
171  for (int i=0; i < dim; ++i)
172  result[i] = funcs[i].evaluateGradient(local[i]);
173  }
174  private:
175  Dune::FieldVector<ftype, dim> funcs;
176 };
177 
179  template<class ctype, class rtype, int dim>
181 {
182 public:
184  enum { n = dim==2?4:8 };
185 
188 
190  typedef rtype resulttype;
191 
193  static const P1ShapeFunctionSet& instance()
194  {
195  static const P1ShapeFunctionSet sfs;
196  return sfs;
197  }
198 
201  const ShapeFunction& operator[](int i) const
202  {
203  return f[i];
204  }
205 
206 private:
209  {
210  static rtype coeffs11[] = {0,
211  1};
212  static rtype coeffs12[] = {1,
213  -1};
214 
215  static rtype coeffs21[] = { 1, 1,
216  0, 1,
217  1, 0,
218  0, 0};
219  static rtype coeffs22[] = {-1,-1,
220  1,-1,
221  -1, 1,
222  1, 1};
223 
224  static rtype coeffs31[] = { 1, 1, 1,
225  0, 1, 1,
226  1, 0, 1,
227  0, 0, 1,
228  1, 1, 0,
229  0, 1, 0,
230  1, 0, 0,
231  0, 0, 0};
232  static rtype coeffs32[] = {-1,-1,-1,
233  1,-1,-1,
234  -1, 1,-1,
235  1, 1,-1,
236  -1,-1, 1,
237  1,-1, 1,
238  -1, 1, 1,
239  1, 1, 1};
240 
241  rtype* coeffs1;
242  rtype* coeffs2;
243  if (dim == 1) {
244  coeffs1 = coeffs11;
245  coeffs2 = coeffs12;
246  }
247  if (dim == 2) {
248  coeffs1 = coeffs21;
249  coeffs2 = coeffs22;
250  }
251  if (dim == 3) {
252  coeffs1 = coeffs31;
253  coeffs2 = coeffs32;
254  }
255 
256  Dune::FieldVector<rtype,dim> c1;
257  Dune::FieldVector<rtype,dim> c2;
258  for (int i=0;i<n;++i) {
259  for (int j=0;j<dim;++j) {
260  c1[j] = coeffs1[i*dim+j];
261  c2[j] = coeffs2[i*dim+j];
262  }
263  f[i].setCoeff(c1,c2);
264  }
265  }
266 
268  std::array<ShapeFunction, n> f;
269 };
270 
271  template<int dim>
273 {
274 public:
276 
279 
280  PNShapeFunctionSet(int n1, int n2, int n3=0)
281  {
282  int dims[3] = {n1, n2, n3};
283  cfuncs.resize(dim);
284  for (int i=0; i < dim; ++i) {
285  std::vector<double> grid;
286  grid = gaussLobattoLegendreGrid(dims[i]);
287  for (int j=0;j<dims[i];++j)
289  }
290  int l=0;
291  Dune::FieldVector<CardinalFunction,dim> fs;
292  if (dim == 3) {
293  f.resize(n1*n2*n3);
294  for (int k=0; k < n3; ++k) {
295  for (int j=0; j < n2; ++j)
296  for (int i=0; i< n1; ++i) {
297  fs[0] = cfuncs[0][i];
298  fs[1] = cfuncs[1][j];
299  fs[2] = cfuncs[2][k];
300  f[l++] = ShapeFunction(fs);
301  }
302  }
303  } else {
304  f.resize(n1*n2);
305  for (int j=0; j < n2; ++j) {
306  for (int i=0; i< n1; ++i) {
307  fs[0] = cfuncs[0][i];
308  fs[1] = cfuncs[1][j];
309  f[l++] = ShapeFunction(fs);
310  }
311  }
312  }
313  }
314 
317  const ShapeFunction& operator[](int i) const
318  {
319  return f[i];
320  }
321 
322  int size()
323  {
324  return f.size();
325  }
326 protected:
327  std::vector< std::vector<CardinalFunction> > cfuncs;
328  std::vector<ShapeFunction> f;
329 
330  double legendre(double x, int n)
331  {
332  std::vector<double> Ln;
333  Ln.resize(n+1);
334  Ln[0] = 1.f;
335  Ln[1] = x;
336  if( n > 1 ) {
337  for( int i=1;i<n;i++ )
338  Ln[i+1] = (2*i+1.0)/(i+1.0)*x*Ln[i]-i/(i+1.0)*Ln[i-1];
339  }
340 
341  return Ln[n];
342  }
343 
344  double legendreDerivative(double x, int n)
345  {
346  std::vector<double> Ln;
347  Ln.resize(n+1);
348 
349  Ln[0] = 1.0; Ln[1] = x;
350 
351  if( (x == 1.0) || (x == -1.0) )
352  return( pow(x,n-1)*n*(n+1.0)/2.0 );
353  else {
354  for( int i=1;i<n;i++ )
355  Ln[i+1] = (2.0*i+1.0)/(i+1.0)*x*Ln[i]-(double)i/(i+1.0)*Ln[i-1];
356  return( (double)n/(1.0-x*x)*Ln[n-1]-n*x/(1-x*x)*Ln[n] );
357  }
358  }
359 
360  std::vector<double> gaussLegendreGrid(int n)
361  {
362  Dune::DynamicMatrix<double> A(n,n,0.0);
363 
364  A[0][1] = 1.f;
365  for (int i=1;i<n-1;++i) {
366  A[i][i-1] = (double)i/(2.0*(i+1.0)-1.0);
367  A[i][i+1] = (double)(i+1.0)/(2*(i+1.0)-1.0);
368  }
369  A[n-1][n-2] = (n-1.0)/(2.0*n-1.0);
370 
371  Dune::DynamicVector<std::complex<double> > eigenValues(n);
372  Dune::DynamicMatrixHelp::eigenValuesNonSym(A, eigenValues);
373 
374  std::vector<double> result(n);
375  for (int i=0; i < n; ++i)
376  result[i] = std::real(eigenValues[i]);
377  std::sort(result.begin(),result.begin()+n);
378 
379  return result;
380  }
381 
382  std::vector<double> gaussLobattoLegendreGrid(int n)
383  {
384  assert(n > 1);
385  const double tolerance = 1.e-15;
386 
387  std::vector<double> result(n);
388  result[0] = 0.0;
389  result[n-1] = 1.0;
390  if (n == 3)
391  result[1] = 0.5;
392 
393  if (n < 4)
394  return result;
395 
396  std::vector<double> glgrid = gaussLegendreGrid(n-1);
397  for (int i=1;i<n-1;++i) {
398  result[i] = (glgrid[i-1]+glgrid[i])/2.0;
399  double old = 0.0;
400  while (std::abs(old-result[i]) > tolerance) {
401  old = result[i];
402  double L = legendre(old, n-1);
403  double Ld = legendreDerivative(old, n-1);
404  result[i] += (1.0-old*old)*Ld/((n-1.0)*n*L);
405  }
406  result[i] = (result[i]+1.0)/2.0;
407  }
408 
409  return result;
410  }
411 };
412 
413 }
414 }
415 
416 #endif
const ShapeFunction & operator[](int i) const
Obtain a given shape function.
Definition: shapefunctions.hpp:317
rtype resulttype
The type of the return value from a shape function.
Definition: shapefunctions.hpp:190
PNShapeFunctionSet(int n1, int n2, int n3=0)
Definition: shapefunctions.hpp:280
Represents a linear shape function on a Q4/Q8 element.
Definition: shapefunctions.hpp:26
void setCoeff(const Dune::FieldVector< rtype, dim > &coeff0_, const Dune::FieldVector< rtype, dim > &coeff1_)
Set the given conefficients.
Definition: shapefunctions.hpp:45
Definition: applier.hpp:18
Dune::FieldVector< rtype, dim > evaluateGradient(const Dune::FieldVector< ctype, dim > &local) const
Definition: shapefunctions.hpp:168
std::vector< std::vector< CardinalFunction > > cfuncs
Definition: shapefunctions.hpp:327
int size()
Definition: shapefunctions.hpp:322
double legendre(double x, int n)
Definition: shapefunctions.hpp:330
rtype evaluateGradient(const ctype &local) const
Evaluate the derivative of the cardinal function.
Definition: shapefunctions.hpp:118
LinearShapeFunction(const Dune::FieldVector< rtype, dim > &coeff0_, const Dune::FieldVector< rtype, dim > &coeff1_)
Construct a shape function with the given coefficients.
Definition: shapefunctions.hpp:38
std::vector< double > gaussLegendreGrid(int n)
Definition: shapefunctions.hpp:360
LagrangeCardinalFunction()
Empty default constructor.
Definition: shapefunctions.hpp:94
LagrangeCardinalFunction(const std::vector< rtype > &nodes_, size_t i)
Construct a cardinal function with the given nodes.
Definition: shapefunctions.hpp:99
static const P1ShapeFunctionSet & instance()
Get the only instance of this class.
Definition: shapefunctions.hpp:193
rtype evaluateFunction(const ctype &local) const
Evaluate the shape function.
Definition: shapefunctions.hpp:105
std::vector< double > gaussLobattoLegendreGrid(int n)
Definition: shapefunctions.hpp:382
double legendreDerivative(double x, int n)
Definition: shapefunctions.hpp:344
Represents a cardinal function on a line.
Definition: shapefunctions.hpp:90
Definition: shapefunctions.hpp:272
TensorProductFunction()
Empty default constructor.
Definition: shapefunctions.hpp:149
Definition: shapefunctions.hpp:30
Represents a tensor-product of 1D functions.
Definition: shapefunctions.hpp:142
rtype evaluateFunction(const Dune::FieldVector< ctype, dim > &local) const
Evaluate the function.
Definition: shapefunctions.hpp:158
master push_back(extractMasterFace(Y, min[1]))
Singleton handler for the set of LinearShapeFunction.
Definition: shapefunctions.hpp:180
LinearShapeFunction< ctype, rtype, dim > ShapeFunction
A single shape function.
Definition: shapefunctions.hpp:187
const ShapeFunction & operator[](int i) const
Obtain a given shape function.
Definition: shapefunctions.hpp:201
std::vector< ShapeFunction > f
Definition: shapefunctions.hpp:328
LagrangeCardinalFunction< double, double > CardinalFunction
Definition: shapefunctions.hpp:275
TensorProductFunction< double, double, CardinalFunction, dim > ShapeFunction
Definition: shapefunctions.hpp:278
Definition: shapefunctions.hpp:184
LinearShapeFunction()
Default constructor.
Definition: shapefunctions.hpp:33
TensorProductFunction(const Dune::FieldVector< ftype, dim > &funcs_)
Construct a tensor-product function.
Definition: shapefunctions.hpp:153
int j
Definition: elasticity_upscale_impl.hpp:658
rtype evaluateFunction(const Dune::FieldVector< ctype, dim > &local) const
Evaluate the shape function.
Definition: shapefunctions.hpp:53
Dune::FieldVector< rtype, dim > evaluateGradient(const Dune::FieldVector< ctype, dim > &local) const
Evaluate the gradient of the shape function.
Definition: shapefunctions.hpp:64
Definition: shapefunctions.hpp:146