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
21namespace Opm {
22namespace 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{
182public:
184 enum { n = dim==2?4:8 };
185
188
190 typedef rtype resulttype;
191
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
206private:
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{
274public:
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 }
326protected:
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
Represents a cardinal function on a line.
Definition: shapefunctions.hpp:91
rtype evaluateGradient(const ctype &local) const
Evaluate the derivative of the cardinal function.
Definition: shapefunctions.hpp:118
rtype evaluateFunction(const ctype &local) const
Evaluate the shape function.
Definition: shapefunctions.hpp:105
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
Represents a linear shape function on a Q4/Q8 element.
Definition: shapefunctions.hpp:27
void setCoeff(const Dune::FieldVector< rtype, dim > &coeff0_, const Dune::FieldVector< rtype, dim > &coeff1_)
Set the given conefficients.
Definition: shapefunctions.hpp:45
LinearShapeFunction()
Default constructor.
Definition: shapefunctions.hpp:33
Dune::FieldVector< rtype, dim > evaluateGradient(const Dune::FieldVector< ctype, dim > &local) const
Evaluate the gradient of the shape function.
Definition: shapefunctions.hpp:64
@ dimension
Definition: shapefunctions.hpp:30
rtype evaluateFunction(const Dune::FieldVector< ctype, dim > &local) const
Evaluate the shape function.
Definition: shapefunctions.hpp:53
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
Singleton handler for the set of LinearShapeFunction.
Definition: shapefunctions.hpp:181
@ n
Definition: shapefunctions.hpp:184
rtype resulttype
The type of the return value from a shape function.
Definition: shapefunctions.hpp:190
LinearShapeFunction< ctype, rtype, dim > ShapeFunction
A single shape function.
Definition: shapefunctions.hpp:187
static const P1ShapeFunctionSet & instance()
Get the only instance of this class.
Definition: shapefunctions.hpp:193
const ShapeFunction & operator[](int i) const
Obtain a given shape function.
Definition: shapefunctions.hpp:201
Definition: shapefunctions.hpp:273
std::vector< double > gaussLobattoLegendreGrid(int n)
Definition: shapefunctions.hpp:382
TensorProductFunction< double, double, CardinalFunction, dim > ShapeFunction
Definition: shapefunctions.hpp:278
std::vector< ShapeFunction > f
Definition: shapefunctions.hpp:328
int size()
Definition: shapefunctions.hpp:322
double legendreDerivative(double x, int n)
Definition: shapefunctions.hpp:344
std::vector< double > gaussLegendreGrid(int n)
Definition: shapefunctions.hpp:360
double legendre(double x, int n)
Definition: shapefunctions.hpp:330
std::vector< std::vector< CardinalFunction > > cfuncs
Definition: shapefunctions.hpp:327
LagrangeCardinalFunction< double, double > CardinalFunction
Definition: shapefunctions.hpp:275
PNShapeFunctionSet(int n1, int n2, int n3=0)
Definition: shapefunctions.hpp:280
const ShapeFunction & operator[](int i) const
Obtain a given shape function.
Definition: shapefunctions.hpp:317
Represents a tensor-product of 1D functions.
Definition: shapefunctions.hpp:143
@ dimension
Definition: shapefunctions.hpp:146
Dune::FieldVector< rtype, dim > evaluateGradient(const Dune::FieldVector< ctype, dim > &local) const
Definition: shapefunctions.hpp:168
TensorProductFunction()
Empty default constructor.
Definition: shapefunctions.hpp:149
rtype evaluateFunction(const Dune::FieldVector< ctype, dim > &local) const
Evaluate the function.
Definition: shapefunctions.hpp:158
TensorProductFunction(const Dune::FieldVector< ftype, dim > &funcs_)
Construct a tensor-product function.
Definition: shapefunctions.hpp:153
int j
Definition: elasticity_upscale_impl.hpp:658
master push_back(extractMasterFace(Y, min[1]))
Definition: ImplicitAssembly.hpp:43