1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.7.0.
11
/// This class defines the interface for a finite element.
13
class stokes_0_finite_element_0_0_0: public ufc::finite_element
18
stokes_0_finite_element_0_0_0() : ufc::finite_element()
24
virtual ~stokes_0_finite_element_0_0_0()
29
/// Return a string identifying the finite element
30
virtual const char* signature() const
32
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
35
/// Return the cell shape
36
virtual ufc::shape cell_shape() const
41
/// Return the dimension of the finite element function space
42
virtual unsigned int space_dimension() const
47
/// Return the rank of the value space
48
virtual unsigned int value_rank() const
53
/// Return the dimension of the value space for axis i
54
virtual unsigned int value_dimension(unsigned int i) const
59
/// Evaluate basis function i at given point in cell
60
virtual void evaluate_basis(unsigned int i,
62
const double* coordinates,
63
const ufc::cell& c) const
65
// Extract vertex coordinates
66
const double * const * element_coordinates = c.coordinates;
68
// Compute Jacobian of affine map from reference cell
69
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
70
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
71
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
72
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
74
// Compute determinant of Jacobian
75
const double detJ = J_00*J_11 - J_01*J_10;
77
// Compute inverse of Jacobian
79
// Get coordinates and map to the reference (UFC) element
80
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
81
element_coordinates[0][0]*element_coordinates[2][1] +\
82
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
83
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
84
element_coordinates[1][0]*element_coordinates[0][1] -\
85
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
87
// Map coordinates to the reference square
88
if (std::abs(y - 1.0) < 1e-08)
91
x = 2.0 *x/(1.0 - y) - 1.0;
97
// Map degree of freedom to element degree of freedom
98
const unsigned int dof = i;
101
const double scalings_y_0 = 1;
102
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
103
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
105
// Compute psitilde_a
106
const double psitilde_a_0 = 1;
107
const double psitilde_a_1 = x;
108
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
110
// Compute psitilde_bs
111
const double psitilde_bs_0_0 = 1;
112
const double psitilde_bs_0_1 = 1.5*y + 0.5;
113
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
114
const double psitilde_bs_1_0 = 1;
115
const double psitilde_bs_1_1 = 2.5*y + 1.5;
116
const double psitilde_bs_2_0 = 1;
118
// Compute basisvalues
119
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
120
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
121
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
122
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
123
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
124
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
126
// Table(s) of coefficients
127
static const double coefficients0[6][6] = \
128
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
129
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
130
{0, 0, 0.2, 0, 0, 0.163299316},
131
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
132
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
133
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
135
// Extract relevant coefficients
136
const double coeff0_0 = coefficients0[dof][0];
137
const double coeff0_1 = coefficients0[dof][1];
138
const double coeff0_2 = coefficients0[dof][2];
139
const double coeff0_3 = coefficients0[dof][3];
140
const double coeff0_4 = coefficients0[dof][4];
141
const double coeff0_5 = coefficients0[dof][5];
144
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
147
/// Evaluate all basis functions at given point in cell
148
virtual void evaluate_basis_all(double* values,
149
const double* coordinates,
150
const ufc::cell& c) const
152
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
155
/// Evaluate order n derivatives of basis function i at given point in cell
156
virtual void evaluate_basis_derivatives(unsigned int i,
159
const double* coordinates,
160
const ufc::cell& c) const
162
// Extract vertex coordinates
163
const double * const * element_coordinates = c.coordinates;
165
// Compute Jacobian of affine map from reference cell
166
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
167
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
168
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
169
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
171
// Compute determinant of Jacobian
172
const double detJ = J_00*J_11 - J_01*J_10;
174
// Compute inverse of Jacobian
176
// Get coordinates and map to the reference (UFC) element
177
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
178
element_coordinates[0][0]*element_coordinates[2][1] +\
179
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
180
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
181
element_coordinates[1][0]*element_coordinates[0][1] -\
182
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
184
// Map coordinates to the reference square
185
if (std::abs(y - 1.0) < 1e-08)
188
x = 2.0 *x/(1.0 - y) - 1.0;
191
// Compute number of derivatives
192
unsigned int num_derivatives = 1;
194
for (unsigned int j = 0; j < n; j++)
195
num_derivatives *= 2;
198
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
199
unsigned int **combinations = new unsigned int *[num_derivatives];
201
for (unsigned int j = 0; j < num_derivatives; j++)
203
combinations[j] = new unsigned int [n];
204
for (unsigned int k = 0; k < n; k++)
205
combinations[j][k] = 0;
208
// Generate combinations of derivatives
209
for (unsigned int row = 1; row < num_derivatives; row++)
211
for (unsigned int num = 0; num < row; num++)
213
for (unsigned int col = n-1; col+1 > 0; col--)
215
if (combinations[row][col] + 1 > 1)
216
combinations[row][col] = 0;
219
combinations[row][col] += 1;
226
// Compute inverse of Jacobian
227
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
229
// Declare transformation matrix
230
// Declare pointer to two dimensional array and initialise
231
double **transform = new double *[num_derivatives];
233
for (unsigned int j = 0; j < num_derivatives; j++)
235
transform[j] = new double [num_derivatives];
236
for (unsigned int k = 0; k < num_derivatives; k++)
240
// Construct transformation matrix
241
for (unsigned int row = 0; row < num_derivatives; row++)
243
for (unsigned int col = 0; col < num_derivatives; col++)
245
for (unsigned int k = 0; k < n; k++)
246
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
251
for (unsigned int j = 0; j < 1*num_derivatives; j++)
254
// Map degree of freedom to element degree of freedom
255
const unsigned int dof = i;
258
const double scalings_y_0 = 1;
259
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
260
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
262
// Compute psitilde_a
263
const double psitilde_a_0 = 1;
264
const double psitilde_a_1 = x;
265
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
267
// Compute psitilde_bs
268
const double psitilde_bs_0_0 = 1;
269
const double psitilde_bs_0_1 = 1.5*y + 0.5;
270
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
271
const double psitilde_bs_1_0 = 1;
272
const double psitilde_bs_1_1 = 2.5*y + 1.5;
273
const double psitilde_bs_2_0 = 1;
275
// Compute basisvalues
276
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
277
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
278
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
279
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
280
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
281
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
283
// Table(s) of coefficients
284
static const double coefficients0[6][6] = \
285
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
286
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
287
{0, 0, 0.2, 0, 0, 0.163299316},
288
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
289
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
290
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
292
// Interesting (new) part
293
// Tables of derivatives of the polynomial base (transpose)
294
static const double dmats0[6][6] = \
296
{4.89897949, 0, 0, 0, 0, 0},
298
{0, 9.48683298, 0, 0, 0, 0},
299
{4, 0, 7.07106781, 0, 0, 0},
302
static const double dmats1[6][6] = \
304
{2.44948974, 0, 0, 0, 0, 0},
305
{4.24264069, 0, 0, 0, 0, 0},
306
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
307
{2, 6.12372436, 3.53553391, 0, 0, 0},
308
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
310
// Compute reference derivatives
311
// Declare pointer to array of derivatives on FIAT element
312
double *derivatives = new double [num_derivatives];
314
// Declare coefficients
322
// Declare new coefficients
323
double new_coeff0_0 = 0;
324
double new_coeff0_1 = 0;
325
double new_coeff0_2 = 0;
326
double new_coeff0_3 = 0;
327
double new_coeff0_4 = 0;
328
double new_coeff0_5 = 0;
330
// Loop possible derivatives
331
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
333
// Get values from coefficients array
334
new_coeff0_0 = coefficients0[dof][0];
335
new_coeff0_1 = coefficients0[dof][1];
336
new_coeff0_2 = coefficients0[dof][2];
337
new_coeff0_3 = coefficients0[dof][3];
338
new_coeff0_4 = coefficients0[dof][4];
339
new_coeff0_5 = coefficients0[dof][5];
341
// Loop derivative order
342
for (unsigned int j = 0; j < n; j++)
344
// Update old coefficients
345
coeff0_0 = new_coeff0_0;
346
coeff0_1 = new_coeff0_1;
347
coeff0_2 = new_coeff0_2;
348
coeff0_3 = new_coeff0_3;
349
coeff0_4 = new_coeff0_4;
350
coeff0_5 = new_coeff0_5;
352
if(combinations[deriv_num][j] == 0)
354
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
355
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
356
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
357
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
358
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
359
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
361
if(combinations[deriv_num][j] == 1)
363
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
364
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
365
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
366
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
367
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
368
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
372
// Compute derivatives on reference element as dot product of coefficients and basisvalues
373
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
376
// Transform derivatives back to physical element
377
for (unsigned int row = 0; row < num_derivatives; row++)
379
for (unsigned int col = 0; col < num_derivatives; col++)
381
values[row] += transform[row][col]*derivatives[col];
384
// Delete pointer to array of derivatives on FIAT element
385
delete [] derivatives;
387
// Delete pointer to array of combinations of derivatives and transform
388
for (unsigned int row = 0; row < num_derivatives; row++)
390
delete [] combinations[row];
391
delete [] transform[row];
394
delete [] combinations;
398
/// Evaluate order n derivatives of all basis functions at given point in cell
399
virtual void evaluate_basis_derivatives_all(unsigned int n,
401
const double* coordinates,
402
const ufc::cell& c) const
404
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
407
/// Evaluate linear functional for dof i on the function f
408
virtual double evaluate_dof(unsigned int i,
409
const ufc::function& f,
410
const ufc::cell& c) const
412
// The reference points, direction and weights:
413
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
414
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
415
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
417
const double * const * x = c.coordinates;
419
// Iterate over the points:
420
// Evaluate basis functions for affine mapping
421
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
422
const double w1 = X[i][0][0];
423
const double w2 = X[i][0][1];
425
// Compute affine mapping y = F(X)
427
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
428
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
430
// Evaluate function at physical points
432
f.evaluate(values, y, c);
434
// Map function values using appropriate mapping
435
// Affine map: Do nothing
437
// Note that we do not map the weights (yet).
439
// Take directional components
440
for(int k = 0; k < 1; k++)
441
result += values[k]*D[i][0][k];
442
// Multiply by weights
448
/// Evaluate linear functionals for all dofs on the function f
449
virtual void evaluate_dofs(double* values,
450
const ufc::function& f,
451
const ufc::cell& c) const
453
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
456
/// Interpolate vertex values from dof values
457
virtual void interpolate_vertex_values(double* vertex_values,
458
const double* dof_values,
459
const ufc::cell& c) const
461
// Evaluate at vertices and use affine mapping
462
vertex_values[0] = dof_values[0];
463
vertex_values[1] = dof_values[1];
464
vertex_values[2] = dof_values[2];
467
/// Return the number of sub elements (for a mixed element)
468
virtual unsigned int num_sub_elements() const
473
/// Create a new finite element for sub element i (for a mixed element)
474
virtual ufc::finite_element* create_sub_element(unsigned int i) const
476
return new stokes_0_finite_element_0_0_0();
481
/// This class defines the interface for a finite element.
483
class stokes_0_finite_element_0_0_1: public ufc::finite_element
488
stokes_0_finite_element_0_0_1() : ufc::finite_element()
494
virtual ~stokes_0_finite_element_0_0_1()
499
/// Return a string identifying the finite element
500
virtual const char* signature() const
502
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
505
/// Return the cell shape
506
virtual ufc::shape cell_shape() const
508
return ufc::triangle;
511
/// Return the dimension of the finite element function space
512
virtual unsigned int space_dimension() const
517
/// Return the rank of the value space
518
virtual unsigned int value_rank() const
523
/// Return the dimension of the value space for axis i
524
virtual unsigned int value_dimension(unsigned int i) const
529
/// Evaluate basis function i at given point in cell
530
virtual void evaluate_basis(unsigned int i,
532
const double* coordinates,
533
const ufc::cell& c) const
535
// Extract vertex coordinates
536
const double * const * element_coordinates = c.coordinates;
538
// Compute Jacobian of affine map from reference cell
539
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
540
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
541
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
542
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
544
// Compute determinant of Jacobian
545
const double detJ = J_00*J_11 - J_01*J_10;
547
// Compute inverse of Jacobian
549
// Get coordinates and map to the reference (UFC) element
550
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
551
element_coordinates[0][0]*element_coordinates[2][1] +\
552
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
553
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
554
element_coordinates[1][0]*element_coordinates[0][1] -\
555
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
557
// Map coordinates to the reference square
558
if (std::abs(y - 1.0) < 1e-08)
561
x = 2.0 *x/(1.0 - y) - 1.0;
567
// Map degree of freedom to element degree of freedom
568
const unsigned int dof = i;
571
const double scalings_y_0 = 1;
572
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
573
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
575
// Compute psitilde_a
576
const double psitilde_a_0 = 1;
577
const double psitilde_a_1 = x;
578
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
580
// Compute psitilde_bs
581
const double psitilde_bs_0_0 = 1;
582
const double psitilde_bs_0_1 = 1.5*y + 0.5;
583
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
584
const double psitilde_bs_1_0 = 1;
585
const double psitilde_bs_1_1 = 2.5*y + 1.5;
586
const double psitilde_bs_2_0 = 1;
588
// Compute basisvalues
589
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
590
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
591
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
592
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
593
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
594
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
596
// Table(s) of coefficients
597
static const double coefficients0[6][6] = \
598
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
599
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
600
{0, 0, 0.2, 0, 0, 0.163299316},
601
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
602
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
603
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
605
// Extract relevant coefficients
606
const double coeff0_0 = coefficients0[dof][0];
607
const double coeff0_1 = coefficients0[dof][1];
608
const double coeff0_2 = coefficients0[dof][2];
609
const double coeff0_3 = coefficients0[dof][3];
610
const double coeff0_4 = coefficients0[dof][4];
611
const double coeff0_5 = coefficients0[dof][5];
614
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
617
/// Evaluate all basis functions at given point in cell
618
virtual void evaluate_basis_all(double* values,
619
const double* coordinates,
620
const ufc::cell& c) const
622
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
625
/// Evaluate order n derivatives of basis function i at given point in cell
626
virtual void evaluate_basis_derivatives(unsigned int i,
629
const double* coordinates,
630
const ufc::cell& c) const
632
// Extract vertex coordinates
633
const double * const * element_coordinates = c.coordinates;
635
// Compute Jacobian of affine map from reference cell
636
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
637
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
638
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
639
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
641
// Compute determinant of Jacobian
642
const double detJ = J_00*J_11 - J_01*J_10;
644
// Compute inverse of Jacobian
646
// Get coordinates and map to the reference (UFC) element
647
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
648
element_coordinates[0][0]*element_coordinates[2][1] +\
649
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
650
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
651
element_coordinates[1][0]*element_coordinates[0][1] -\
652
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
654
// Map coordinates to the reference square
655
if (std::abs(y - 1.0) < 1e-08)
658
x = 2.0 *x/(1.0 - y) - 1.0;
661
// Compute number of derivatives
662
unsigned int num_derivatives = 1;
664
for (unsigned int j = 0; j < n; j++)
665
num_derivatives *= 2;
668
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
669
unsigned int **combinations = new unsigned int *[num_derivatives];
671
for (unsigned int j = 0; j < num_derivatives; j++)
673
combinations[j] = new unsigned int [n];
674
for (unsigned int k = 0; k < n; k++)
675
combinations[j][k] = 0;
678
// Generate combinations of derivatives
679
for (unsigned int row = 1; row < num_derivatives; row++)
681
for (unsigned int num = 0; num < row; num++)
683
for (unsigned int col = n-1; col+1 > 0; col--)
685
if (combinations[row][col] + 1 > 1)
686
combinations[row][col] = 0;
689
combinations[row][col] += 1;
696
// Compute inverse of Jacobian
697
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
699
// Declare transformation matrix
700
// Declare pointer to two dimensional array and initialise
701
double **transform = new double *[num_derivatives];
703
for (unsigned int j = 0; j < num_derivatives; j++)
705
transform[j] = new double [num_derivatives];
706
for (unsigned int k = 0; k < num_derivatives; k++)
710
// Construct transformation matrix
711
for (unsigned int row = 0; row < num_derivatives; row++)
713
for (unsigned int col = 0; col < num_derivatives; col++)
715
for (unsigned int k = 0; k < n; k++)
716
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
721
for (unsigned int j = 0; j < 1*num_derivatives; j++)
724
// Map degree of freedom to element degree of freedom
725
const unsigned int dof = i;
728
const double scalings_y_0 = 1;
729
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
730
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
732
// Compute psitilde_a
733
const double psitilde_a_0 = 1;
734
const double psitilde_a_1 = x;
735
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
737
// Compute psitilde_bs
738
const double psitilde_bs_0_0 = 1;
739
const double psitilde_bs_0_1 = 1.5*y + 0.5;
740
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
741
const double psitilde_bs_1_0 = 1;
742
const double psitilde_bs_1_1 = 2.5*y + 1.5;
743
const double psitilde_bs_2_0 = 1;
745
// Compute basisvalues
746
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
747
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
748
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
749
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
750
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
751
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
753
// Table(s) of coefficients
754
static const double coefficients0[6][6] = \
755
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
756
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
757
{0, 0, 0.2, 0, 0, 0.163299316},
758
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
759
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
760
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
762
// Interesting (new) part
763
// Tables of derivatives of the polynomial base (transpose)
764
static const double dmats0[6][6] = \
766
{4.89897949, 0, 0, 0, 0, 0},
768
{0, 9.48683298, 0, 0, 0, 0},
769
{4, 0, 7.07106781, 0, 0, 0},
772
static const double dmats1[6][6] = \
774
{2.44948974, 0, 0, 0, 0, 0},
775
{4.24264069, 0, 0, 0, 0, 0},
776
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
777
{2, 6.12372436, 3.53553391, 0, 0, 0},
778
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
780
// Compute reference derivatives
781
// Declare pointer to array of derivatives on FIAT element
782
double *derivatives = new double [num_derivatives];
784
// Declare coefficients
792
// Declare new coefficients
793
double new_coeff0_0 = 0;
794
double new_coeff0_1 = 0;
795
double new_coeff0_2 = 0;
796
double new_coeff0_3 = 0;
797
double new_coeff0_4 = 0;
798
double new_coeff0_5 = 0;
800
// Loop possible derivatives
801
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
803
// Get values from coefficients array
804
new_coeff0_0 = coefficients0[dof][0];
805
new_coeff0_1 = coefficients0[dof][1];
806
new_coeff0_2 = coefficients0[dof][2];
807
new_coeff0_3 = coefficients0[dof][3];
808
new_coeff0_4 = coefficients0[dof][4];
809
new_coeff0_5 = coefficients0[dof][5];
811
// Loop derivative order
812
for (unsigned int j = 0; j < n; j++)
814
// Update old coefficients
815
coeff0_0 = new_coeff0_0;
816
coeff0_1 = new_coeff0_1;
817
coeff0_2 = new_coeff0_2;
818
coeff0_3 = new_coeff0_3;
819
coeff0_4 = new_coeff0_4;
820
coeff0_5 = new_coeff0_5;
822
if(combinations[deriv_num][j] == 0)
824
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
825
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
826
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
827
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
828
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
829
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
831
if(combinations[deriv_num][j] == 1)
833
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
834
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
835
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
836
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
837
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
838
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
842
// Compute derivatives on reference element as dot product of coefficients and basisvalues
843
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
846
// Transform derivatives back to physical element
847
for (unsigned int row = 0; row < num_derivatives; row++)
849
for (unsigned int col = 0; col < num_derivatives; col++)
851
values[row] += transform[row][col]*derivatives[col];
854
// Delete pointer to array of derivatives on FIAT element
855
delete [] derivatives;
857
// Delete pointer to array of combinations of derivatives and transform
858
for (unsigned int row = 0; row < num_derivatives; row++)
860
delete [] combinations[row];
861
delete [] transform[row];
864
delete [] combinations;
868
/// Evaluate order n derivatives of all basis functions at given point in cell
869
virtual void evaluate_basis_derivatives_all(unsigned int n,
871
const double* coordinates,
872
const ufc::cell& c) const
874
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
877
/// Evaluate linear functional for dof i on the function f
878
virtual double evaluate_dof(unsigned int i,
879
const ufc::function& f,
880
const ufc::cell& c) const
882
// The reference points, direction and weights:
883
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
884
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
885
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
887
const double * const * x = c.coordinates;
889
// Iterate over the points:
890
// Evaluate basis functions for affine mapping
891
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
892
const double w1 = X[i][0][0];
893
const double w2 = X[i][0][1];
895
// Compute affine mapping y = F(X)
897
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
898
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
900
// Evaluate function at physical points
902
f.evaluate(values, y, c);
904
// Map function values using appropriate mapping
905
// Affine map: Do nothing
907
// Note that we do not map the weights (yet).
909
// Take directional components
910
for(int k = 0; k < 1; k++)
911
result += values[k]*D[i][0][k];
912
// Multiply by weights
918
/// Evaluate linear functionals for all dofs on the function f
919
virtual void evaluate_dofs(double* values,
920
const ufc::function& f,
921
const ufc::cell& c) const
923
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
926
/// Interpolate vertex values from dof values
927
virtual void interpolate_vertex_values(double* vertex_values,
928
const double* dof_values,
929
const ufc::cell& c) const
931
// Evaluate at vertices and use affine mapping
932
vertex_values[0] = dof_values[0];
933
vertex_values[1] = dof_values[1];
934
vertex_values[2] = dof_values[2];
937
/// Return the number of sub elements (for a mixed element)
938
virtual unsigned int num_sub_elements() const
943
/// Create a new finite element for sub element i (for a mixed element)
944
virtual ufc::finite_element* create_sub_element(unsigned int i) const
946
return new stokes_0_finite_element_0_0_1();
951
/// This class defines the interface for a finite element.
953
class stokes_0_finite_element_0_0: public ufc::finite_element
958
stokes_0_finite_element_0_0() : ufc::finite_element()
964
virtual ~stokes_0_finite_element_0_0()
969
/// Return a string identifying the finite element
970
virtual const char* signature() const
972
return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
975
/// Return the cell shape
976
virtual ufc::shape cell_shape() const
978
return ufc::triangle;
981
/// Return the dimension of the finite element function space
982
virtual unsigned int space_dimension() const
987
/// Return the rank of the value space
988
virtual unsigned int value_rank() const
993
/// Return the dimension of the value space for axis i
994
virtual unsigned int value_dimension(unsigned int i) const
999
/// Evaluate basis function i at given point in cell
1000
virtual void evaluate_basis(unsigned int i,
1002
const double* coordinates,
1003
const ufc::cell& c) const
1005
// Extract vertex coordinates
1006
const double * const * element_coordinates = c.coordinates;
1008
// Compute Jacobian of affine map from reference cell
1009
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1010
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1011
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1012
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1014
// Compute determinant of Jacobian
1015
const double detJ = J_00*J_11 - J_01*J_10;
1017
// Compute inverse of Jacobian
1019
// Get coordinates and map to the reference (UFC) element
1020
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1021
element_coordinates[0][0]*element_coordinates[2][1] +\
1022
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1023
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1024
element_coordinates[1][0]*element_coordinates[0][1] -\
1025
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1027
// Map coordinates to the reference square
1028
if (std::abs(y - 1.0) < 1e-08)
1031
x = 2.0 *x/(1.0 - y) - 1.0;
1038
if (0 <= i && i <= 5)
1040
// Map degree of freedom to element degree of freedom
1041
const unsigned int dof = i;
1043
// Generate scalings
1044
const double scalings_y_0 = 1;
1045
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1046
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
1048
// Compute psitilde_a
1049
const double psitilde_a_0 = 1;
1050
const double psitilde_a_1 = x;
1051
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
1053
// Compute psitilde_bs
1054
const double psitilde_bs_0_0 = 1;
1055
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1056
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
1057
const double psitilde_bs_1_0 = 1;
1058
const double psitilde_bs_1_1 = 2.5*y + 1.5;
1059
const double psitilde_bs_2_0 = 1;
1061
// Compute basisvalues
1062
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1063
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1064
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1065
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
1066
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
1067
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1069
// Table(s) of coefficients
1070
static const double coefficients0[6][6] = \
1071
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
1072
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
1073
{0, 0, 0.2, 0, 0, 0.163299316},
1074
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
1075
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
1076
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
1078
// Extract relevant coefficients
1079
const double coeff0_0 = coefficients0[dof][0];
1080
const double coeff0_1 = coefficients0[dof][1];
1081
const double coeff0_2 = coefficients0[dof][2];
1082
const double coeff0_3 = coefficients0[dof][3];
1083
const double coeff0_4 = coefficients0[dof][4];
1084
const double coeff0_5 = coefficients0[dof][5];
1087
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
1090
if (6 <= i && i <= 11)
1092
// Map degree of freedom to element degree of freedom
1093
const unsigned int dof = i - 6;
1095
// Generate scalings
1096
const double scalings_y_0 = 1;
1097
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1098
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
1100
// Compute psitilde_a
1101
const double psitilde_a_0 = 1;
1102
const double psitilde_a_1 = x;
1103
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
1105
// Compute psitilde_bs
1106
const double psitilde_bs_0_0 = 1;
1107
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1108
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
1109
const double psitilde_bs_1_0 = 1;
1110
const double psitilde_bs_1_1 = 2.5*y + 1.5;
1111
const double psitilde_bs_2_0 = 1;
1113
// Compute basisvalues
1114
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1115
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1116
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1117
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
1118
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
1119
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1121
// Table(s) of coefficients
1122
static const double coefficients0[6][6] = \
1123
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
1124
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
1125
{0, 0, 0.2, 0, 0, 0.163299316},
1126
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
1127
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
1128
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
1130
// Extract relevant coefficients
1131
const double coeff0_0 = coefficients0[dof][0];
1132
const double coeff0_1 = coefficients0[dof][1];
1133
const double coeff0_2 = coefficients0[dof][2];
1134
const double coeff0_3 = coefficients0[dof][3];
1135
const double coeff0_4 = coefficients0[dof][4];
1136
const double coeff0_5 = coefficients0[dof][5];
1139
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
1144
/// Evaluate all basis functions at given point in cell
1145
virtual void evaluate_basis_all(double* values,
1146
const double* coordinates,
1147
const ufc::cell& c) const
1149
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1152
/// Evaluate order n derivatives of basis function i at given point in cell
1153
virtual void evaluate_basis_derivatives(unsigned int i,
1156
const double* coordinates,
1157
const ufc::cell& c) const
1159
// Extract vertex coordinates
1160
const double * const * element_coordinates = c.coordinates;
1162
// Compute Jacobian of affine map from reference cell
1163
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1164
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1165
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1166
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1168
// Compute determinant of Jacobian
1169
const double detJ = J_00*J_11 - J_01*J_10;
1171
// Compute inverse of Jacobian
1173
// Get coordinates and map to the reference (UFC) element
1174
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1175
element_coordinates[0][0]*element_coordinates[2][1] +\
1176
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1177
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1178
element_coordinates[1][0]*element_coordinates[0][1] -\
1179
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1181
// Map coordinates to the reference square
1182
if (std::abs(y - 1.0) < 1e-08)
1185
x = 2.0 *x/(1.0 - y) - 1.0;
1188
// Compute number of derivatives
1189
unsigned int num_derivatives = 1;
1191
for (unsigned int j = 0; j < n; j++)
1192
num_derivatives *= 2;
1195
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1196
unsigned int **combinations = new unsigned int *[num_derivatives];
1198
for (unsigned int j = 0; j < num_derivatives; j++)
1200
combinations[j] = new unsigned int [n];
1201
for (unsigned int k = 0; k < n; k++)
1202
combinations[j][k] = 0;
1205
// Generate combinations of derivatives
1206
for (unsigned int row = 1; row < num_derivatives; row++)
1208
for (unsigned int num = 0; num < row; num++)
1210
for (unsigned int col = n-1; col+1 > 0; col--)
1212
if (combinations[row][col] + 1 > 1)
1213
combinations[row][col] = 0;
1216
combinations[row][col] += 1;
1223
// Compute inverse of Jacobian
1224
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1226
// Declare transformation matrix
1227
// Declare pointer to two dimensional array and initialise
1228
double **transform = new double *[num_derivatives];
1230
for (unsigned int j = 0; j < num_derivatives; j++)
1232
transform[j] = new double [num_derivatives];
1233
for (unsigned int k = 0; k < num_derivatives; k++)
1234
transform[j][k] = 1;
1237
// Construct transformation matrix
1238
for (unsigned int row = 0; row < num_derivatives; row++)
1240
for (unsigned int col = 0; col < num_derivatives; col++)
1242
for (unsigned int k = 0; k < n; k++)
1243
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1248
for (unsigned int j = 0; j < 2*num_derivatives; j++)
1251
if (0 <= i && i <= 5)
1253
// Map degree of freedom to element degree of freedom
1254
const unsigned int dof = i;
1256
// Generate scalings
1257
const double scalings_y_0 = 1;
1258
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1259
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
1261
// Compute psitilde_a
1262
const double psitilde_a_0 = 1;
1263
const double psitilde_a_1 = x;
1264
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
1266
// Compute psitilde_bs
1267
const double psitilde_bs_0_0 = 1;
1268
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1269
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
1270
const double psitilde_bs_1_0 = 1;
1271
const double psitilde_bs_1_1 = 2.5*y + 1.5;
1272
const double psitilde_bs_2_0 = 1;
1274
// Compute basisvalues
1275
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1276
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1277
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1278
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
1279
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
1280
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1282
// Table(s) of coefficients
1283
static const double coefficients0[6][6] = \
1284
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
1285
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
1286
{0, 0, 0.2, 0, 0, 0.163299316},
1287
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
1288
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
1289
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
1291
// Interesting (new) part
1292
// Tables of derivatives of the polynomial base (transpose)
1293
static const double dmats0[6][6] = \
1294
{{0, 0, 0, 0, 0, 0},
1295
{4.89897949, 0, 0, 0, 0, 0},
1297
{0, 9.48683298, 0, 0, 0, 0},
1298
{4, 0, 7.07106781, 0, 0, 0},
1299
{0, 0, 0, 0, 0, 0}};
1301
static const double dmats1[6][6] = \
1302
{{0, 0, 0, 0, 0, 0},
1303
{2.44948974, 0, 0, 0, 0, 0},
1304
{4.24264069, 0, 0, 0, 0, 0},
1305
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
1306
{2, 6.12372436, 3.53553391, 0, 0, 0},
1307
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
1309
// Compute reference derivatives
1310
// Declare pointer to array of derivatives on FIAT element
1311
double *derivatives = new double [num_derivatives];
1313
// Declare coefficients
1314
double coeff0_0 = 0;
1315
double coeff0_1 = 0;
1316
double coeff0_2 = 0;
1317
double coeff0_3 = 0;
1318
double coeff0_4 = 0;
1319
double coeff0_5 = 0;
1321
// Declare new coefficients
1322
double new_coeff0_0 = 0;
1323
double new_coeff0_1 = 0;
1324
double new_coeff0_2 = 0;
1325
double new_coeff0_3 = 0;
1326
double new_coeff0_4 = 0;
1327
double new_coeff0_5 = 0;
1329
// Loop possible derivatives
1330
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1332
// Get values from coefficients array
1333
new_coeff0_0 = coefficients0[dof][0];
1334
new_coeff0_1 = coefficients0[dof][1];
1335
new_coeff0_2 = coefficients0[dof][2];
1336
new_coeff0_3 = coefficients0[dof][3];
1337
new_coeff0_4 = coefficients0[dof][4];
1338
new_coeff0_5 = coefficients0[dof][5];
1340
// Loop derivative order
1341
for (unsigned int j = 0; j < n; j++)
1343
// Update old coefficients
1344
coeff0_0 = new_coeff0_0;
1345
coeff0_1 = new_coeff0_1;
1346
coeff0_2 = new_coeff0_2;
1347
coeff0_3 = new_coeff0_3;
1348
coeff0_4 = new_coeff0_4;
1349
coeff0_5 = new_coeff0_5;
1351
if(combinations[deriv_num][j] == 0)
1353
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
1354
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
1355
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
1356
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
1357
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
1358
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
1360
if(combinations[deriv_num][j] == 1)
1362
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
1363
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
1364
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
1365
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
1366
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
1367
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
1371
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1372
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
1375
// Transform derivatives back to physical element
1376
for (unsigned int row = 0; row < num_derivatives; row++)
1378
for (unsigned int col = 0; col < num_derivatives; col++)
1380
values[row] += transform[row][col]*derivatives[col];
1383
// Delete pointer to array of derivatives on FIAT element
1384
delete [] derivatives;
1386
// Delete pointer to array of combinations of derivatives and transform
1387
for (unsigned int row = 0; row < num_derivatives; row++)
1389
delete [] combinations[row];
1390
delete [] transform[row];
1393
delete [] combinations;
1394
delete [] transform;
1397
if (6 <= i && i <= 11)
1399
// Map degree of freedom to element degree of freedom
1400
const unsigned int dof = i - 6;
1402
// Generate scalings
1403
const double scalings_y_0 = 1;
1404
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1405
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
1407
// Compute psitilde_a
1408
const double psitilde_a_0 = 1;
1409
const double psitilde_a_1 = x;
1410
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
1412
// Compute psitilde_bs
1413
const double psitilde_bs_0_0 = 1;
1414
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1415
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
1416
const double psitilde_bs_1_0 = 1;
1417
const double psitilde_bs_1_1 = 2.5*y + 1.5;
1418
const double psitilde_bs_2_0 = 1;
1420
// Compute basisvalues
1421
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1422
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1423
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1424
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
1425
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
1426
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1428
// Table(s) of coefficients
1429
static const double coefficients0[6][6] = \
1430
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
1431
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
1432
{0, 0, 0.2, 0, 0, 0.163299316},
1433
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
1434
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
1435
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
1437
// Interesting (new) part
1438
// Tables of derivatives of the polynomial base (transpose)
1439
static const double dmats0[6][6] = \
1440
{{0, 0, 0, 0, 0, 0},
1441
{4.89897949, 0, 0, 0, 0, 0},
1443
{0, 9.48683298, 0, 0, 0, 0},
1444
{4, 0, 7.07106781, 0, 0, 0},
1445
{0, 0, 0, 0, 0, 0}};
1447
static const double dmats1[6][6] = \
1448
{{0, 0, 0, 0, 0, 0},
1449
{2.44948974, 0, 0, 0, 0, 0},
1450
{4.24264069, 0, 0, 0, 0, 0},
1451
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
1452
{2, 6.12372436, 3.53553391, 0, 0, 0},
1453
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
1455
// Compute reference derivatives
1456
// Declare pointer to array of derivatives on FIAT element
1457
double *derivatives = new double [num_derivatives];
1459
// Declare coefficients
1460
double coeff0_0 = 0;
1461
double coeff0_1 = 0;
1462
double coeff0_2 = 0;
1463
double coeff0_3 = 0;
1464
double coeff0_4 = 0;
1465
double coeff0_5 = 0;
1467
// Declare new coefficients
1468
double new_coeff0_0 = 0;
1469
double new_coeff0_1 = 0;
1470
double new_coeff0_2 = 0;
1471
double new_coeff0_3 = 0;
1472
double new_coeff0_4 = 0;
1473
double new_coeff0_5 = 0;
1475
// Loop possible derivatives
1476
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1478
// Get values from coefficients array
1479
new_coeff0_0 = coefficients0[dof][0];
1480
new_coeff0_1 = coefficients0[dof][1];
1481
new_coeff0_2 = coefficients0[dof][2];
1482
new_coeff0_3 = coefficients0[dof][3];
1483
new_coeff0_4 = coefficients0[dof][4];
1484
new_coeff0_5 = coefficients0[dof][5];
1486
// Loop derivative order
1487
for (unsigned int j = 0; j < n; j++)
1489
// Update old coefficients
1490
coeff0_0 = new_coeff0_0;
1491
coeff0_1 = new_coeff0_1;
1492
coeff0_2 = new_coeff0_2;
1493
coeff0_3 = new_coeff0_3;
1494
coeff0_4 = new_coeff0_4;
1495
coeff0_5 = new_coeff0_5;
1497
if(combinations[deriv_num][j] == 0)
1499
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
1500
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
1501
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
1502
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
1503
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
1504
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
1506
if(combinations[deriv_num][j] == 1)
1508
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
1509
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
1510
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
1511
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
1512
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
1513
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
1517
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1518
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
1521
// Transform derivatives back to physical element
1522
for (unsigned int row = 0; row < num_derivatives; row++)
1524
for (unsigned int col = 0; col < num_derivatives; col++)
1526
values[num_derivatives + row] += transform[row][col]*derivatives[col];
1529
// Delete pointer to array of derivatives on FIAT element
1530
delete [] derivatives;
1532
// Delete pointer to array of combinations of derivatives and transform
1533
for (unsigned int row = 0; row < num_derivatives; row++)
1535
delete [] combinations[row];
1536
delete [] transform[row];
1539
delete [] combinations;
1540
delete [] transform;
1545
/// Evaluate order n derivatives of all basis functions at given point in cell
1546
virtual void evaluate_basis_derivatives_all(unsigned int n,
1548
const double* coordinates,
1549
const ufc::cell& c) const
1551
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1554
/// Evaluate linear functional for dof i on the function f
1555
virtual double evaluate_dof(unsigned int i,
1556
const ufc::function& f,
1557
const ufc::cell& c) const
1559
// The reference points, direction and weights:
1560
static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
1561
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
1562
static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
1564
const double * const * x = c.coordinates;
1565
double result = 0.0;
1566
// Iterate over the points:
1567
// Evaluate basis functions for affine mapping
1568
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1569
const double w1 = X[i][0][0];
1570
const double w2 = X[i][0][1];
1572
// Compute affine mapping y = F(X)
1574
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1575
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1577
// Evaluate function at physical points
1579
f.evaluate(values, y, c);
1581
// Map function values using appropriate mapping
1582
// Affine map: Do nothing
1584
// Note that we do not map the weights (yet).
1586
// Take directional components
1587
for(int k = 0; k < 2; k++)
1588
result += values[k]*D[i][0][k];
1589
// Multiply by weights
1595
/// Evaluate linear functionals for all dofs on the function f
1596
virtual void evaluate_dofs(double* values,
1597
const ufc::function& f,
1598
const ufc::cell& c) const
1600
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1603
/// Interpolate vertex values from dof values
1604
virtual void interpolate_vertex_values(double* vertex_values,
1605
const double* dof_values,
1606
const ufc::cell& c) const
1608
// Evaluate at vertices and use affine mapping
1609
vertex_values[0] = dof_values[0];
1610
vertex_values[2] = dof_values[1];
1611
vertex_values[4] = dof_values[2];
1612
// Evaluate at vertices and use affine mapping
1613
vertex_values[1] = dof_values[6];
1614
vertex_values[3] = dof_values[7];
1615
vertex_values[5] = dof_values[8];
1618
/// Return the number of sub elements (for a mixed element)
1619
virtual unsigned int num_sub_elements() const
1624
/// Create a new finite element for sub element i (for a mixed element)
1625
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1630
return new stokes_0_finite_element_0_0_0();
1633
return new stokes_0_finite_element_0_0_1();
1641
/// This class defines the interface for a finite element.
1643
class stokes_0_finite_element_0_1: public ufc::finite_element
1648
stokes_0_finite_element_0_1() : ufc::finite_element()
1654
virtual ~stokes_0_finite_element_0_1()
1659
/// Return a string identifying the finite element
1660
virtual const char* signature() const
1662
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
1665
/// Return the cell shape
1666
virtual ufc::shape cell_shape() const
1668
return ufc::triangle;
1671
/// Return the dimension of the finite element function space
1672
virtual unsigned int space_dimension() const
1677
/// Return the rank of the value space
1678
virtual unsigned int value_rank() const
1683
/// Return the dimension of the value space for axis i
1684
virtual unsigned int value_dimension(unsigned int i) const
1689
/// Evaluate basis function i at given point in cell
1690
virtual void evaluate_basis(unsigned int i,
1692
const double* coordinates,
1693
const ufc::cell& c) const
1695
// Extract vertex coordinates
1696
const double * const * element_coordinates = c.coordinates;
1698
// Compute Jacobian of affine map from reference cell
1699
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1700
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1701
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1702
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1704
// Compute determinant of Jacobian
1705
const double detJ = J_00*J_11 - J_01*J_10;
1707
// Compute inverse of Jacobian
1709
// Get coordinates and map to the reference (UFC) element
1710
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1711
element_coordinates[0][0]*element_coordinates[2][1] +\
1712
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1713
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1714
element_coordinates[1][0]*element_coordinates[0][1] -\
1715
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1717
// Map coordinates to the reference square
1718
if (std::abs(y - 1.0) < 1e-08)
1721
x = 2.0 *x/(1.0 - y) - 1.0;
1727
// Map degree of freedom to element degree of freedom
1728
const unsigned int dof = i;
1730
// Generate scalings
1731
const double scalings_y_0 = 1;
1732
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1734
// Compute psitilde_a
1735
const double psitilde_a_0 = 1;
1736
const double psitilde_a_1 = x;
1738
// Compute psitilde_bs
1739
const double psitilde_bs_0_0 = 1;
1740
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1741
const double psitilde_bs_1_0 = 1;
1743
// Compute basisvalues
1744
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1745
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1746
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1748
// Table(s) of coefficients
1749
static const double coefficients0[3][3] = \
1750
{{0.471404521, -0.288675135, -0.166666667},
1751
{0.471404521, 0.288675135, -0.166666667},
1752
{0.471404521, 0, 0.333333333}};
1754
// Extract relevant coefficients
1755
const double coeff0_0 = coefficients0[dof][0];
1756
const double coeff0_1 = coefficients0[dof][1];
1757
const double coeff0_2 = coefficients0[dof][2];
1760
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1763
/// Evaluate all basis functions at given point in cell
1764
virtual void evaluate_basis_all(double* values,
1765
const double* coordinates,
1766
const ufc::cell& c) const
1768
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1771
/// Evaluate order n derivatives of basis function i at given point in cell
1772
virtual void evaluate_basis_derivatives(unsigned int i,
1775
const double* coordinates,
1776
const ufc::cell& c) const
1778
// Extract vertex coordinates
1779
const double * const * element_coordinates = c.coordinates;
1781
// Compute Jacobian of affine map from reference cell
1782
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1783
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1784
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1785
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1787
// Compute determinant of Jacobian
1788
const double detJ = J_00*J_11 - J_01*J_10;
1790
// Compute inverse of Jacobian
1792
// Get coordinates and map to the reference (UFC) element
1793
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1794
element_coordinates[0][0]*element_coordinates[2][1] +\
1795
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1796
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1797
element_coordinates[1][0]*element_coordinates[0][1] -\
1798
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1800
// Map coordinates to the reference square
1801
if (std::abs(y - 1.0) < 1e-08)
1804
x = 2.0 *x/(1.0 - y) - 1.0;
1807
// Compute number of derivatives
1808
unsigned int num_derivatives = 1;
1810
for (unsigned int j = 0; j < n; j++)
1811
num_derivatives *= 2;
1814
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1815
unsigned int **combinations = new unsigned int *[num_derivatives];
1817
for (unsigned int j = 0; j < num_derivatives; j++)
1819
combinations[j] = new unsigned int [n];
1820
for (unsigned int k = 0; k < n; k++)
1821
combinations[j][k] = 0;
1824
// Generate combinations of derivatives
1825
for (unsigned int row = 1; row < num_derivatives; row++)
1827
for (unsigned int num = 0; num < row; num++)
1829
for (unsigned int col = n-1; col+1 > 0; col--)
1831
if (combinations[row][col] + 1 > 1)
1832
combinations[row][col] = 0;
1835
combinations[row][col] += 1;
1842
// Compute inverse of Jacobian
1843
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1845
// Declare transformation matrix
1846
// Declare pointer to two dimensional array and initialise
1847
double **transform = new double *[num_derivatives];
1849
for (unsigned int j = 0; j < num_derivatives; j++)
1851
transform[j] = new double [num_derivatives];
1852
for (unsigned int k = 0; k < num_derivatives; k++)
1853
transform[j][k] = 1;
1856
// Construct transformation matrix
1857
for (unsigned int row = 0; row < num_derivatives; row++)
1859
for (unsigned int col = 0; col < num_derivatives; col++)
1861
for (unsigned int k = 0; k < n; k++)
1862
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1867
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1870
// Map degree of freedom to element degree of freedom
1871
const unsigned int dof = i;
1873
// Generate scalings
1874
const double scalings_y_0 = 1;
1875
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1877
// Compute psitilde_a
1878
const double psitilde_a_0 = 1;
1879
const double psitilde_a_1 = x;
1881
// Compute psitilde_bs
1882
const double psitilde_bs_0_0 = 1;
1883
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1884
const double psitilde_bs_1_0 = 1;
1886
// Compute basisvalues
1887
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1888
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1889
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1891
// Table(s) of coefficients
1892
static const double coefficients0[3][3] = \
1893
{{0.471404521, -0.288675135, -0.166666667},
1894
{0.471404521, 0.288675135, -0.166666667},
1895
{0.471404521, 0, 0.333333333}};
1897
// Interesting (new) part
1898
// Tables of derivatives of the polynomial base (transpose)
1899
static const double dmats0[3][3] = \
1904
static const double dmats1[3][3] = \
1907
{4.24264069, 0, 0}};
1909
// Compute reference derivatives
1910
// Declare pointer to array of derivatives on FIAT element
1911
double *derivatives = new double [num_derivatives];
1913
// Declare coefficients
1914
double coeff0_0 = 0;
1915
double coeff0_1 = 0;
1916
double coeff0_2 = 0;
1918
// Declare new coefficients
1919
double new_coeff0_0 = 0;
1920
double new_coeff0_1 = 0;
1921
double new_coeff0_2 = 0;
1923
// Loop possible derivatives
1924
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1926
// Get values from coefficients array
1927
new_coeff0_0 = coefficients0[dof][0];
1928
new_coeff0_1 = coefficients0[dof][1];
1929
new_coeff0_2 = coefficients0[dof][2];
1931
// Loop derivative order
1932
for (unsigned int j = 0; j < n; j++)
1934
// Update old coefficients
1935
coeff0_0 = new_coeff0_0;
1936
coeff0_1 = new_coeff0_1;
1937
coeff0_2 = new_coeff0_2;
1939
if(combinations[deriv_num][j] == 0)
1941
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1942
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1943
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1945
if(combinations[deriv_num][j] == 1)
1947
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1948
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1949
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1953
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1954
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1957
// Transform derivatives back to physical element
1958
for (unsigned int row = 0; row < num_derivatives; row++)
1960
for (unsigned int col = 0; col < num_derivatives; col++)
1962
values[row] += transform[row][col]*derivatives[col];
1965
// Delete pointer to array of derivatives on FIAT element
1966
delete [] derivatives;
1968
// Delete pointer to array of combinations of derivatives and transform
1969
for (unsigned int row = 0; row < num_derivatives; row++)
1971
delete [] combinations[row];
1972
delete [] transform[row];
1975
delete [] combinations;
1976
delete [] transform;
1979
/// Evaluate order n derivatives of all basis functions at given point in cell
1980
virtual void evaluate_basis_derivatives_all(unsigned int n,
1982
const double* coordinates,
1983
const ufc::cell& c) const
1985
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1988
/// Evaluate linear functional for dof i on the function f
1989
virtual double evaluate_dof(unsigned int i,
1990
const ufc::function& f,
1991
const ufc::cell& c) const
1993
// The reference points, direction and weights:
1994
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
1995
static const double W[3][1] = {{1}, {1}, {1}};
1996
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
1998
const double * const * x = c.coordinates;
1999
double result = 0.0;
2000
// Iterate over the points:
2001
// Evaluate basis functions for affine mapping
2002
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2003
const double w1 = X[i][0][0];
2004
const double w2 = X[i][0][1];
2006
// Compute affine mapping y = F(X)
2008
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2009
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2011
// Evaluate function at physical points
2013
f.evaluate(values, y, c);
2015
// Map function values using appropriate mapping
2016
// Affine map: Do nothing
2018
// Note that we do not map the weights (yet).
2020
// Take directional components
2021
for(int k = 0; k < 1; k++)
2022
result += values[k]*D[i][0][k];
2023
// Multiply by weights
2029
/// Evaluate linear functionals for all dofs on the function f
2030
virtual void evaluate_dofs(double* values,
2031
const ufc::function& f,
2032
const ufc::cell& c) const
2034
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2037
/// Interpolate vertex values from dof values
2038
virtual void interpolate_vertex_values(double* vertex_values,
2039
const double* dof_values,
2040
const ufc::cell& c) const
2042
// Evaluate at vertices and use affine mapping
2043
vertex_values[0] = dof_values[0];
2044
vertex_values[1] = dof_values[1];
2045
vertex_values[2] = dof_values[2];
2048
/// Return the number of sub elements (for a mixed element)
2049
virtual unsigned int num_sub_elements() const
2054
/// Create a new finite element for sub element i (for a mixed element)
2055
virtual ufc::finite_element* create_sub_element(unsigned int i) const
2057
return new stokes_0_finite_element_0_1();
2062
/// This class defines the interface for a finite element.
2064
class stokes_0_finite_element_0: public ufc::finite_element
2069
stokes_0_finite_element_0() : ufc::finite_element()
2075
virtual ~stokes_0_finite_element_0()
2080
/// Return a string identifying the finite element
2081
virtual const char* signature() const
2083
return "MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) })";
2086
/// Return the cell shape
2087
virtual ufc::shape cell_shape() const
2089
return ufc::triangle;
2092
/// Return the dimension of the finite element function space
2093
virtual unsigned int space_dimension() const
2098
/// Return the rank of the value space
2099
virtual unsigned int value_rank() const
2104
/// Return the dimension of the value space for axis i
2105
virtual unsigned int value_dimension(unsigned int i) const
2110
/// Evaluate basis function i at given point in cell
2111
virtual void evaluate_basis(unsigned int i,
2113
const double* coordinates,
2114
const ufc::cell& c) const
2116
// Extract vertex coordinates
2117
const double * const * element_coordinates = c.coordinates;
2119
// Compute Jacobian of affine map from reference cell
2120
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2121
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2122
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2123
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2125
// Compute determinant of Jacobian
2126
const double detJ = J_00*J_11 - J_01*J_10;
2128
// Compute inverse of Jacobian
2130
// Get coordinates and map to the reference (UFC) element
2131
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2132
element_coordinates[0][0]*element_coordinates[2][1] +\
2133
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2134
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2135
element_coordinates[1][0]*element_coordinates[0][1] -\
2136
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2138
// Map coordinates to the reference square
2139
if (std::abs(y - 1.0) < 1e-08)
2142
x = 2.0 *x/(1.0 - y) - 1.0;
2150
if (0 <= i && i <= 5)
2152
// Map degree of freedom to element degree of freedom
2153
const unsigned int dof = i;
2155
// Generate scalings
2156
const double scalings_y_0 = 1;
2157
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2158
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
2160
// Compute psitilde_a
2161
const double psitilde_a_0 = 1;
2162
const double psitilde_a_1 = x;
2163
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
2165
// Compute psitilde_bs
2166
const double psitilde_bs_0_0 = 1;
2167
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2168
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
2169
const double psitilde_bs_1_0 = 1;
2170
const double psitilde_bs_1_1 = 2.5*y + 1.5;
2171
const double psitilde_bs_2_0 = 1;
2173
// Compute basisvalues
2174
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2175
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2176
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2177
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
2178
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
2179
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
2181
// Table(s) of coefficients
2182
static const double coefficients0[6][6] = \
2183
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
2184
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
2185
{0, 0, 0.2, 0, 0, 0.163299316},
2186
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
2187
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
2188
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
2190
// Extract relevant coefficients
2191
const double coeff0_0 = coefficients0[dof][0];
2192
const double coeff0_1 = coefficients0[dof][1];
2193
const double coeff0_2 = coefficients0[dof][2];
2194
const double coeff0_3 = coefficients0[dof][3];
2195
const double coeff0_4 = coefficients0[dof][4];
2196
const double coeff0_5 = coefficients0[dof][5];
2199
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
2202
if (6 <= i && i <= 11)
2204
// Map degree of freedom to element degree of freedom
2205
const unsigned int dof = i - 6;
2207
// Generate scalings
2208
const double scalings_y_0 = 1;
2209
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2210
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
2212
// Compute psitilde_a
2213
const double psitilde_a_0 = 1;
2214
const double psitilde_a_1 = x;
2215
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
2217
// Compute psitilde_bs
2218
const double psitilde_bs_0_0 = 1;
2219
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2220
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
2221
const double psitilde_bs_1_0 = 1;
2222
const double psitilde_bs_1_1 = 2.5*y + 1.5;
2223
const double psitilde_bs_2_0 = 1;
2225
// Compute basisvalues
2226
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2227
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2228
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2229
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
2230
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
2231
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
2233
// Table(s) of coefficients
2234
static const double coefficients0[6][6] = \
2235
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
2236
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
2237
{0, 0, 0.2, 0, 0, 0.163299316},
2238
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
2239
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
2240
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
2242
// Extract relevant coefficients
2243
const double coeff0_0 = coefficients0[dof][0];
2244
const double coeff0_1 = coefficients0[dof][1];
2245
const double coeff0_2 = coefficients0[dof][2];
2246
const double coeff0_3 = coefficients0[dof][3];
2247
const double coeff0_4 = coefficients0[dof][4];
2248
const double coeff0_5 = coefficients0[dof][5];
2251
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
2254
if (12 <= i && i <= 14)
2256
// Map degree of freedom to element degree of freedom
2257
const unsigned int dof = i - 12;
2259
// Generate scalings
2260
const double scalings_y_0 = 1;
2261
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2263
// Compute psitilde_a
2264
const double psitilde_a_0 = 1;
2265
const double psitilde_a_1 = x;
2267
// Compute psitilde_bs
2268
const double psitilde_bs_0_0 = 1;
2269
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2270
const double psitilde_bs_1_0 = 1;
2272
// Compute basisvalues
2273
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2274
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2275
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2277
// Table(s) of coefficients
2278
static const double coefficients0[3][3] = \
2279
{{0.471404521, -0.288675135, -0.166666667},
2280
{0.471404521, 0.288675135, -0.166666667},
2281
{0.471404521, 0, 0.333333333}};
2283
// Extract relevant coefficients
2284
const double coeff0_0 = coefficients0[dof][0];
2285
const double coeff0_1 = coefficients0[dof][1];
2286
const double coeff0_2 = coefficients0[dof][2];
2289
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2294
/// Evaluate all basis functions at given point in cell
2295
virtual void evaluate_basis_all(double* values,
2296
const double* coordinates,
2297
const ufc::cell& c) const
2299
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2302
/// Evaluate order n derivatives of basis function i at given point in cell
2303
virtual void evaluate_basis_derivatives(unsigned int i,
2306
const double* coordinates,
2307
const ufc::cell& c) const
2309
// Extract vertex coordinates
2310
const double * const * element_coordinates = c.coordinates;
2312
// Compute Jacobian of affine map from reference cell
2313
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2314
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2315
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2316
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2318
// Compute determinant of Jacobian
2319
const double detJ = J_00*J_11 - J_01*J_10;
2321
// Compute inverse of Jacobian
2323
// Get coordinates and map to the reference (UFC) element
2324
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2325
element_coordinates[0][0]*element_coordinates[2][1] +\
2326
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2327
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2328
element_coordinates[1][0]*element_coordinates[0][1] -\
2329
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2331
// Map coordinates to the reference square
2332
if (std::abs(y - 1.0) < 1e-08)
2335
x = 2.0 *x/(1.0 - y) - 1.0;
2338
// Compute number of derivatives
2339
unsigned int num_derivatives = 1;
2341
for (unsigned int j = 0; j < n; j++)
2342
num_derivatives *= 2;
2345
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2346
unsigned int **combinations = new unsigned int *[num_derivatives];
2348
for (unsigned int j = 0; j < num_derivatives; j++)
2350
combinations[j] = new unsigned int [n];
2351
for (unsigned int k = 0; k < n; k++)
2352
combinations[j][k] = 0;
2355
// Generate combinations of derivatives
2356
for (unsigned int row = 1; row < num_derivatives; row++)
2358
for (unsigned int num = 0; num < row; num++)
2360
for (unsigned int col = n-1; col+1 > 0; col--)
2362
if (combinations[row][col] + 1 > 1)
2363
combinations[row][col] = 0;
2366
combinations[row][col] += 1;
2373
// Compute inverse of Jacobian
2374
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2376
// Declare transformation matrix
2377
// Declare pointer to two dimensional array and initialise
2378
double **transform = new double *[num_derivatives];
2380
for (unsigned int j = 0; j < num_derivatives; j++)
2382
transform[j] = new double [num_derivatives];
2383
for (unsigned int k = 0; k < num_derivatives; k++)
2384
transform[j][k] = 1;
2387
// Construct transformation matrix
2388
for (unsigned int row = 0; row < num_derivatives; row++)
2390
for (unsigned int col = 0; col < num_derivatives; col++)
2392
for (unsigned int k = 0; k < n; k++)
2393
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2398
for (unsigned int j = 0; j < 3*num_derivatives; j++)
2401
if (0 <= i && i <= 5)
2403
// Map degree of freedom to element degree of freedom
2404
const unsigned int dof = i;
2406
// Generate scalings
2407
const double scalings_y_0 = 1;
2408
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2409
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
2411
// Compute psitilde_a
2412
const double psitilde_a_0 = 1;
2413
const double psitilde_a_1 = x;
2414
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
2416
// Compute psitilde_bs
2417
const double psitilde_bs_0_0 = 1;
2418
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2419
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
2420
const double psitilde_bs_1_0 = 1;
2421
const double psitilde_bs_1_1 = 2.5*y + 1.5;
2422
const double psitilde_bs_2_0 = 1;
2424
// Compute basisvalues
2425
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2426
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2427
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2428
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
2429
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
2430
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
2432
// Table(s) of coefficients
2433
static const double coefficients0[6][6] = \
2434
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
2435
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
2436
{0, 0, 0.2, 0, 0, 0.163299316},
2437
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
2438
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
2439
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
2441
// Interesting (new) part
2442
// Tables of derivatives of the polynomial base (transpose)
2443
static const double dmats0[6][6] = \
2444
{{0, 0, 0, 0, 0, 0},
2445
{4.89897949, 0, 0, 0, 0, 0},
2447
{0, 9.48683298, 0, 0, 0, 0},
2448
{4, 0, 7.07106781, 0, 0, 0},
2449
{0, 0, 0, 0, 0, 0}};
2451
static const double dmats1[6][6] = \
2452
{{0, 0, 0, 0, 0, 0},
2453
{2.44948974, 0, 0, 0, 0, 0},
2454
{4.24264069, 0, 0, 0, 0, 0},
2455
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
2456
{2, 6.12372436, 3.53553391, 0, 0, 0},
2457
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
2459
// Compute reference derivatives
2460
// Declare pointer to array of derivatives on FIAT element
2461
double *derivatives = new double [num_derivatives];
2463
// Declare coefficients
2464
double coeff0_0 = 0;
2465
double coeff0_1 = 0;
2466
double coeff0_2 = 0;
2467
double coeff0_3 = 0;
2468
double coeff0_4 = 0;
2469
double coeff0_5 = 0;
2471
// Declare new coefficients
2472
double new_coeff0_0 = 0;
2473
double new_coeff0_1 = 0;
2474
double new_coeff0_2 = 0;
2475
double new_coeff0_3 = 0;
2476
double new_coeff0_4 = 0;
2477
double new_coeff0_5 = 0;
2479
// Loop possible derivatives
2480
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2482
// Get values from coefficients array
2483
new_coeff0_0 = coefficients0[dof][0];
2484
new_coeff0_1 = coefficients0[dof][1];
2485
new_coeff0_2 = coefficients0[dof][2];
2486
new_coeff0_3 = coefficients0[dof][3];
2487
new_coeff0_4 = coefficients0[dof][4];
2488
new_coeff0_5 = coefficients0[dof][5];
2490
// Loop derivative order
2491
for (unsigned int j = 0; j < n; j++)
2493
// Update old coefficients
2494
coeff0_0 = new_coeff0_0;
2495
coeff0_1 = new_coeff0_1;
2496
coeff0_2 = new_coeff0_2;
2497
coeff0_3 = new_coeff0_3;
2498
coeff0_4 = new_coeff0_4;
2499
coeff0_5 = new_coeff0_5;
2501
if(combinations[deriv_num][j] == 0)
2503
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
2504
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
2505
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
2506
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
2507
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
2508
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
2510
if(combinations[deriv_num][j] == 1)
2512
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
2513
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
2514
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
2515
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
2516
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
2517
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
2521
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2522
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
2525
// Transform derivatives back to physical element
2526
for (unsigned int row = 0; row < num_derivatives; row++)
2528
for (unsigned int col = 0; col < num_derivatives; col++)
2530
values[row] += transform[row][col]*derivatives[col];
2533
// Delete pointer to array of derivatives on FIAT element
2534
delete [] derivatives;
2536
// Delete pointer to array of combinations of derivatives and transform
2537
for (unsigned int row = 0; row < num_derivatives; row++)
2539
delete [] combinations[row];
2540
delete [] transform[row];
2543
delete [] combinations;
2544
delete [] transform;
2547
if (6 <= i && i <= 11)
2549
// Map degree of freedom to element degree of freedom
2550
const unsigned int dof = i - 6;
2552
// Generate scalings
2553
const double scalings_y_0 = 1;
2554
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2555
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
2557
// Compute psitilde_a
2558
const double psitilde_a_0 = 1;
2559
const double psitilde_a_1 = x;
2560
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
2562
// Compute psitilde_bs
2563
const double psitilde_bs_0_0 = 1;
2564
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2565
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
2566
const double psitilde_bs_1_0 = 1;
2567
const double psitilde_bs_1_1 = 2.5*y + 1.5;
2568
const double psitilde_bs_2_0 = 1;
2570
// Compute basisvalues
2571
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2572
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2573
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2574
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
2575
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
2576
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
2578
// Table(s) of coefficients
2579
static const double coefficients0[6][6] = \
2580
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
2581
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
2582
{0, 0, 0.2, 0, 0, 0.163299316},
2583
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
2584
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
2585
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
2587
// Interesting (new) part
2588
// Tables of derivatives of the polynomial base (transpose)
2589
static const double dmats0[6][6] = \
2590
{{0, 0, 0, 0, 0, 0},
2591
{4.89897949, 0, 0, 0, 0, 0},
2593
{0, 9.48683298, 0, 0, 0, 0},
2594
{4, 0, 7.07106781, 0, 0, 0},
2595
{0, 0, 0, 0, 0, 0}};
2597
static const double dmats1[6][6] = \
2598
{{0, 0, 0, 0, 0, 0},
2599
{2.44948974, 0, 0, 0, 0, 0},
2600
{4.24264069, 0, 0, 0, 0, 0},
2601
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
2602
{2, 6.12372436, 3.53553391, 0, 0, 0},
2603
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
2605
// Compute reference derivatives
2606
// Declare pointer to array of derivatives on FIAT element
2607
double *derivatives = new double [num_derivatives];
2609
// Declare coefficients
2610
double coeff0_0 = 0;
2611
double coeff0_1 = 0;
2612
double coeff0_2 = 0;
2613
double coeff0_3 = 0;
2614
double coeff0_4 = 0;
2615
double coeff0_5 = 0;
2617
// Declare new coefficients
2618
double new_coeff0_0 = 0;
2619
double new_coeff0_1 = 0;
2620
double new_coeff0_2 = 0;
2621
double new_coeff0_3 = 0;
2622
double new_coeff0_4 = 0;
2623
double new_coeff0_5 = 0;
2625
// Loop possible derivatives
2626
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2628
// Get values from coefficients array
2629
new_coeff0_0 = coefficients0[dof][0];
2630
new_coeff0_1 = coefficients0[dof][1];
2631
new_coeff0_2 = coefficients0[dof][2];
2632
new_coeff0_3 = coefficients0[dof][3];
2633
new_coeff0_4 = coefficients0[dof][4];
2634
new_coeff0_5 = coefficients0[dof][5];
2636
// Loop derivative order
2637
for (unsigned int j = 0; j < n; j++)
2639
// Update old coefficients
2640
coeff0_0 = new_coeff0_0;
2641
coeff0_1 = new_coeff0_1;
2642
coeff0_2 = new_coeff0_2;
2643
coeff0_3 = new_coeff0_3;
2644
coeff0_4 = new_coeff0_4;
2645
coeff0_5 = new_coeff0_5;
2647
if(combinations[deriv_num][j] == 0)
2649
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
2650
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
2651
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
2652
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
2653
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
2654
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
2656
if(combinations[deriv_num][j] == 1)
2658
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
2659
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
2660
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
2661
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
2662
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
2663
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
2667
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2668
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
2671
// Transform derivatives back to physical element
2672
for (unsigned int row = 0; row < num_derivatives; row++)
2674
for (unsigned int col = 0; col < num_derivatives; col++)
2676
values[num_derivatives + row] += transform[row][col]*derivatives[col];
2679
// Delete pointer to array of derivatives on FIAT element
2680
delete [] derivatives;
2682
// Delete pointer to array of combinations of derivatives and transform
2683
for (unsigned int row = 0; row < num_derivatives; row++)
2685
delete [] combinations[row];
2686
delete [] transform[row];
2689
delete [] combinations;
2690
delete [] transform;
2693
if (12 <= i && i <= 14)
2695
// Map degree of freedom to element degree of freedom
2696
const unsigned int dof = i - 12;
2698
// Generate scalings
2699
const double scalings_y_0 = 1;
2700
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2702
// Compute psitilde_a
2703
const double psitilde_a_0 = 1;
2704
const double psitilde_a_1 = x;
2706
// Compute psitilde_bs
2707
const double psitilde_bs_0_0 = 1;
2708
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2709
const double psitilde_bs_1_0 = 1;
2711
// Compute basisvalues
2712
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2713
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2714
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2716
// Table(s) of coefficients
2717
static const double coefficients0[3][3] = \
2718
{{0.471404521, -0.288675135, -0.166666667},
2719
{0.471404521, 0.288675135, -0.166666667},
2720
{0.471404521, 0, 0.333333333}};
2722
// Interesting (new) part
2723
// Tables of derivatives of the polynomial base (transpose)
2724
static const double dmats0[3][3] = \
2729
static const double dmats1[3][3] = \
2732
{4.24264069, 0, 0}};
2734
// Compute reference derivatives
2735
// Declare pointer to array of derivatives on FIAT element
2736
double *derivatives = new double [num_derivatives];
2738
// Declare coefficients
2739
double coeff0_0 = 0;
2740
double coeff0_1 = 0;
2741
double coeff0_2 = 0;
2743
// Declare new coefficients
2744
double new_coeff0_0 = 0;
2745
double new_coeff0_1 = 0;
2746
double new_coeff0_2 = 0;
2748
// Loop possible derivatives
2749
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2751
// Get values from coefficients array
2752
new_coeff0_0 = coefficients0[dof][0];
2753
new_coeff0_1 = coefficients0[dof][1];
2754
new_coeff0_2 = coefficients0[dof][2];
2756
// Loop derivative order
2757
for (unsigned int j = 0; j < n; j++)
2759
// Update old coefficients
2760
coeff0_0 = new_coeff0_0;
2761
coeff0_1 = new_coeff0_1;
2762
coeff0_2 = new_coeff0_2;
2764
if(combinations[deriv_num][j] == 0)
2766
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2767
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2768
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2770
if(combinations[deriv_num][j] == 1)
2772
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2773
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2774
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2778
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2779
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2782
// Transform derivatives back to physical element
2783
for (unsigned int row = 0; row < num_derivatives; row++)
2785
for (unsigned int col = 0; col < num_derivatives; col++)
2787
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
2790
// Delete pointer to array of derivatives on FIAT element
2791
delete [] derivatives;
2793
// Delete pointer to array of combinations of derivatives and transform
2794
for (unsigned int row = 0; row < num_derivatives; row++)
2796
delete [] combinations[row];
2797
delete [] transform[row];
2800
delete [] combinations;
2801
delete [] transform;
2806
/// Evaluate order n derivatives of all basis functions at given point in cell
2807
virtual void evaluate_basis_derivatives_all(unsigned int n,
2809
const double* coordinates,
2810
const ufc::cell& c) const
2812
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2815
/// Evaluate linear functional for dof i on the function f
2816
virtual double evaluate_dof(unsigned int i,
2817
const ufc::function& f,
2818
const ufc::cell& c) const
2820
// The reference points, direction and weights:
2821
static const double X[15][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
2822
static const double W[15][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
2823
static const double D[15][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
2825
const double * const * x = c.coordinates;
2826
double result = 0.0;
2827
// Iterate over the points:
2828
// Evaluate basis functions for affine mapping
2829
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2830
const double w1 = X[i][0][0];
2831
const double w2 = X[i][0][1];
2833
// Compute affine mapping y = F(X)
2835
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2836
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2838
// Evaluate function at physical points
2840
f.evaluate(values, y, c);
2842
// Map function values using appropriate mapping
2843
// Affine map: Do nothing
2845
// Note that we do not map the weights (yet).
2847
// Take directional components
2848
for(int k = 0; k < 3; k++)
2849
result += values[k]*D[i][0][k];
2850
// Multiply by weights
2856
/// Evaluate linear functionals for all dofs on the function f
2857
virtual void evaluate_dofs(double* values,
2858
const ufc::function& f,
2859
const ufc::cell& c) const
2861
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2864
/// Interpolate vertex values from dof values
2865
virtual void interpolate_vertex_values(double* vertex_values,
2866
const double* dof_values,
2867
const ufc::cell& c) const
2869
// Evaluate at vertices and use affine mapping
2870
vertex_values[0] = dof_values[0];
2871
vertex_values[3] = dof_values[1];
2872
vertex_values[6] = dof_values[2];
2873
// Evaluate at vertices and use affine mapping
2874
vertex_values[1] = dof_values[6];
2875
vertex_values[4] = dof_values[7];
2876
vertex_values[7] = dof_values[8];
2877
// Evaluate at vertices and use affine mapping
2878
vertex_values[2] = dof_values[12];
2879
vertex_values[5] = dof_values[13];
2880
vertex_values[8] = dof_values[14];
2883
/// Return the number of sub elements (for a mixed element)
2884
virtual unsigned int num_sub_elements() const
2889
/// Create a new finite element for sub element i (for a mixed element)
2890
virtual ufc::finite_element* create_sub_element(unsigned int i) const
2895
return new stokes_0_finite_element_0_0();
2898
return new stokes_0_finite_element_0_1();
2906
/// This class defines the interface for a finite element.
2908
class stokes_0_finite_element_1_0_0: public ufc::finite_element
2913
stokes_0_finite_element_1_0_0() : ufc::finite_element()
2919
virtual ~stokes_0_finite_element_1_0_0()
2924
/// Return a string identifying the finite element
2925
virtual const char* signature() const
2927
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
2930
/// Return the cell shape
2931
virtual ufc::shape cell_shape() const
2933
return ufc::triangle;
2936
/// Return the dimension of the finite element function space
2937
virtual unsigned int space_dimension() const
2942
/// Return the rank of the value space
2943
virtual unsigned int value_rank() const
2948
/// Return the dimension of the value space for axis i
2949
virtual unsigned int value_dimension(unsigned int i) const
2954
/// Evaluate basis function i at given point in cell
2955
virtual void evaluate_basis(unsigned int i,
2957
const double* coordinates,
2958
const ufc::cell& c) const
2960
// Extract vertex coordinates
2961
const double * const * element_coordinates = c.coordinates;
2963
// Compute Jacobian of affine map from reference cell
2964
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2965
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2966
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2967
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2969
// Compute determinant of Jacobian
2970
const double detJ = J_00*J_11 - J_01*J_10;
2972
// Compute inverse of Jacobian
2974
// Get coordinates and map to the reference (UFC) element
2975
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2976
element_coordinates[0][0]*element_coordinates[2][1] +\
2977
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2978
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2979
element_coordinates[1][0]*element_coordinates[0][1] -\
2980
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2982
// Map coordinates to the reference square
2983
if (std::abs(y - 1.0) < 1e-08)
2986
x = 2.0 *x/(1.0 - y) - 1.0;
2992
// Map degree of freedom to element degree of freedom
2993
const unsigned int dof = i;
2995
// Generate scalings
2996
const double scalings_y_0 = 1;
2997
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2998
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
3000
// Compute psitilde_a
3001
const double psitilde_a_0 = 1;
3002
const double psitilde_a_1 = x;
3003
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
3005
// Compute psitilde_bs
3006
const double psitilde_bs_0_0 = 1;
3007
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3008
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
3009
const double psitilde_bs_1_0 = 1;
3010
const double psitilde_bs_1_1 = 2.5*y + 1.5;
3011
const double psitilde_bs_2_0 = 1;
3013
// Compute basisvalues
3014
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3015
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3016
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3017
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
3018
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
3019
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
3021
// Table(s) of coefficients
3022
static const double coefficients0[6][6] = \
3023
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
3024
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
3025
{0, 0, 0.2, 0, 0, 0.163299316},
3026
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
3027
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
3028
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
3030
// Extract relevant coefficients
3031
const double coeff0_0 = coefficients0[dof][0];
3032
const double coeff0_1 = coefficients0[dof][1];
3033
const double coeff0_2 = coefficients0[dof][2];
3034
const double coeff0_3 = coefficients0[dof][3];
3035
const double coeff0_4 = coefficients0[dof][4];
3036
const double coeff0_5 = coefficients0[dof][5];
3039
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
3042
/// Evaluate all basis functions at given point in cell
3043
virtual void evaluate_basis_all(double* values,
3044
const double* coordinates,
3045
const ufc::cell& c) const
3047
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3050
/// Evaluate order n derivatives of basis function i at given point in cell
3051
virtual void evaluate_basis_derivatives(unsigned int i,
3054
const double* coordinates,
3055
const ufc::cell& c) const
3057
// Extract vertex coordinates
3058
const double * const * element_coordinates = c.coordinates;
3060
// Compute Jacobian of affine map from reference cell
3061
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3062
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3063
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3064
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3066
// Compute determinant of Jacobian
3067
const double detJ = J_00*J_11 - J_01*J_10;
3069
// Compute inverse of Jacobian
3071
// Get coordinates and map to the reference (UFC) element
3072
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3073
element_coordinates[0][0]*element_coordinates[2][1] +\
3074
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3075
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3076
element_coordinates[1][0]*element_coordinates[0][1] -\
3077
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3079
// Map coordinates to the reference square
3080
if (std::abs(y - 1.0) < 1e-08)
3083
x = 2.0 *x/(1.0 - y) - 1.0;
3086
// Compute number of derivatives
3087
unsigned int num_derivatives = 1;
3089
for (unsigned int j = 0; j < n; j++)
3090
num_derivatives *= 2;
3093
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3094
unsigned int **combinations = new unsigned int *[num_derivatives];
3096
for (unsigned int j = 0; j < num_derivatives; j++)
3098
combinations[j] = new unsigned int [n];
3099
for (unsigned int k = 0; k < n; k++)
3100
combinations[j][k] = 0;
3103
// Generate combinations of derivatives
3104
for (unsigned int row = 1; row < num_derivatives; row++)
3106
for (unsigned int num = 0; num < row; num++)
3108
for (unsigned int col = n-1; col+1 > 0; col--)
3110
if (combinations[row][col] + 1 > 1)
3111
combinations[row][col] = 0;
3114
combinations[row][col] += 1;
3121
// Compute inverse of Jacobian
3122
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3124
// Declare transformation matrix
3125
// Declare pointer to two dimensional array and initialise
3126
double **transform = new double *[num_derivatives];
3128
for (unsigned int j = 0; j < num_derivatives; j++)
3130
transform[j] = new double [num_derivatives];
3131
for (unsigned int k = 0; k < num_derivatives; k++)
3132
transform[j][k] = 1;
3135
// Construct transformation matrix
3136
for (unsigned int row = 0; row < num_derivatives; row++)
3138
for (unsigned int col = 0; col < num_derivatives; col++)
3140
for (unsigned int k = 0; k < n; k++)
3141
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3146
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3149
// Map degree of freedom to element degree of freedom
3150
const unsigned int dof = i;
3152
// Generate scalings
3153
const double scalings_y_0 = 1;
3154
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3155
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
3157
// Compute psitilde_a
3158
const double psitilde_a_0 = 1;
3159
const double psitilde_a_1 = x;
3160
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
3162
// Compute psitilde_bs
3163
const double psitilde_bs_0_0 = 1;
3164
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3165
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
3166
const double psitilde_bs_1_0 = 1;
3167
const double psitilde_bs_1_1 = 2.5*y + 1.5;
3168
const double psitilde_bs_2_0 = 1;
3170
// Compute basisvalues
3171
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3172
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3173
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3174
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
3175
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
3176
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
3178
// Table(s) of coefficients
3179
static const double coefficients0[6][6] = \
3180
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
3181
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
3182
{0, 0, 0.2, 0, 0, 0.163299316},
3183
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
3184
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
3185
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
3187
// Interesting (new) part
3188
// Tables of derivatives of the polynomial base (transpose)
3189
static const double dmats0[6][6] = \
3190
{{0, 0, 0, 0, 0, 0},
3191
{4.89897949, 0, 0, 0, 0, 0},
3193
{0, 9.48683298, 0, 0, 0, 0},
3194
{4, 0, 7.07106781, 0, 0, 0},
3195
{0, 0, 0, 0, 0, 0}};
3197
static const double dmats1[6][6] = \
3198
{{0, 0, 0, 0, 0, 0},
3199
{2.44948974, 0, 0, 0, 0, 0},
3200
{4.24264069, 0, 0, 0, 0, 0},
3201
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
3202
{2, 6.12372436, 3.53553391, 0, 0, 0},
3203
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
3205
// Compute reference derivatives
3206
// Declare pointer to array of derivatives on FIAT element
3207
double *derivatives = new double [num_derivatives];
3209
// Declare coefficients
3210
double coeff0_0 = 0;
3211
double coeff0_1 = 0;
3212
double coeff0_2 = 0;
3213
double coeff0_3 = 0;
3214
double coeff0_4 = 0;
3215
double coeff0_5 = 0;
3217
// Declare new coefficients
3218
double new_coeff0_0 = 0;
3219
double new_coeff0_1 = 0;
3220
double new_coeff0_2 = 0;
3221
double new_coeff0_3 = 0;
3222
double new_coeff0_4 = 0;
3223
double new_coeff0_5 = 0;
3225
// Loop possible derivatives
3226
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3228
// Get values from coefficients array
3229
new_coeff0_0 = coefficients0[dof][0];
3230
new_coeff0_1 = coefficients0[dof][1];
3231
new_coeff0_2 = coefficients0[dof][2];
3232
new_coeff0_3 = coefficients0[dof][3];
3233
new_coeff0_4 = coefficients0[dof][4];
3234
new_coeff0_5 = coefficients0[dof][5];
3236
// Loop derivative order
3237
for (unsigned int j = 0; j < n; j++)
3239
// Update old coefficients
3240
coeff0_0 = new_coeff0_0;
3241
coeff0_1 = new_coeff0_1;
3242
coeff0_2 = new_coeff0_2;
3243
coeff0_3 = new_coeff0_3;
3244
coeff0_4 = new_coeff0_4;
3245
coeff0_5 = new_coeff0_5;
3247
if(combinations[deriv_num][j] == 0)
3249
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
3250
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
3251
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
3252
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
3253
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
3254
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
3256
if(combinations[deriv_num][j] == 1)
3258
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
3259
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
3260
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
3261
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
3262
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
3263
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
3267
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3268
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
3271
// Transform derivatives back to physical element
3272
for (unsigned int row = 0; row < num_derivatives; row++)
3274
for (unsigned int col = 0; col < num_derivatives; col++)
3276
values[row] += transform[row][col]*derivatives[col];
3279
// Delete pointer to array of derivatives on FIAT element
3280
delete [] derivatives;
3282
// Delete pointer to array of combinations of derivatives and transform
3283
for (unsigned int row = 0; row < num_derivatives; row++)
3285
delete [] combinations[row];
3286
delete [] transform[row];
3289
delete [] combinations;
3290
delete [] transform;
3293
/// Evaluate order n derivatives of all basis functions at given point in cell
3294
virtual void evaluate_basis_derivatives_all(unsigned int n,
3296
const double* coordinates,
3297
const ufc::cell& c) const
3299
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3302
/// Evaluate linear functional for dof i on the function f
3303
virtual double evaluate_dof(unsigned int i,
3304
const ufc::function& f,
3305
const ufc::cell& c) const
3307
// The reference points, direction and weights:
3308
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
3309
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
3310
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
3312
const double * const * x = c.coordinates;
3313
double result = 0.0;
3314
// Iterate over the points:
3315
// Evaluate basis functions for affine mapping
3316
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3317
const double w1 = X[i][0][0];
3318
const double w2 = X[i][0][1];
3320
// Compute affine mapping y = F(X)
3322
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3323
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3325
// Evaluate function at physical points
3327
f.evaluate(values, y, c);
3329
// Map function values using appropriate mapping
3330
// Affine map: Do nothing
3332
// Note that we do not map the weights (yet).
3334
// Take directional components
3335
for(int k = 0; k < 1; k++)
3336
result += values[k]*D[i][0][k];
3337
// Multiply by weights
3343
/// Evaluate linear functionals for all dofs on the function f
3344
virtual void evaluate_dofs(double* values,
3345
const ufc::function& f,
3346
const ufc::cell& c) const
3348
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3351
/// Interpolate vertex values from dof values
3352
virtual void interpolate_vertex_values(double* vertex_values,
3353
const double* dof_values,
3354
const ufc::cell& c) const
3356
// Evaluate at vertices and use affine mapping
3357
vertex_values[0] = dof_values[0];
3358
vertex_values[1] = dof_values[1];
3359
vertex_values[2] = dof_values[2];
3362
/// Return the number of sub elements (for a mixed element)
3363
virtual unsigned int num_sub_elements() const
3368
/// Create a new finite element for sub element i (for a mixed element)
3369
virtual ufc::finite_element* create_sub_element(unsigned int i) const
3371
return new stokes_0_finite_element_1_0_0();
3376
/// This class defines the interface for a finite element.
3378
class stokes_0_finite_element_1_0_1: public ufc::finite_element
3383
stokes_0_finite_element_1_0_1() : ufc::finite_element()
3389
virtual ~stokes_0_finite_element_1_0_1()
3394
/// Return a string identifying the finite element
3395
virtual const char* signature() const
3397
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
3400
/// Return the cell shape
3401
virtual ufc::shape cell_shape() const
3403
return ufc::triangle;
3406
/// Return the dimension of the finite element function space
3407
virtual unsigned int space_dimension() const
3412
/// Return the rank of the value space
3413
virtual unsigned int value_rank() const
3418
/// Return the dimension of the value space for axis i
3419
virtual unsigned int value_dimension(unsigned int i) const
3424
/// Evaluate basis function i at given point in cell
3425
virtual void evaluate_basis(unsigned int i,
3427
const double* coordinates,
3428
const ufc::cell& c) const
3430
// Extract vertex coordinates
3431
const double * const * element_coordinates = c.coordinates;
3433
// Compute Jacobian of affine map from reference cell
3434
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3435
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3436
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3437
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3439
// Compute determinant of Jacobian
3440
const double detJ = J_00*J_11 - J_01*J_10;
3442
// Compute inverse of Jacobian
3444
// Get coordinates and map to the reference (UFC) element
3445
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3446
element_coordinates[0][0]*element_coordinates[2][1] +\
3447
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3448
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3449
element_coordinates[1][0]*element_coordinates[0][1] -\
3450
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3452
// Map coordinates to the reference square
3453
if (std::abs(y - 1.0) < 1e-08)
3456
x = 2.0 *x/(1.0 - y) - 1.0;
3462
// Map degree of freedom to element degree of freedom
3463
const unsigned int dof = i;
3465
// Generate scalings
3466
const double scalings_y_0 = 1;
3467
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3468
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
3470
// Compute psitilde_a
3471
const double psitilde_a_0 = 1;
3472
const double psitilde_a_1 = x;
3473
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
3475
// Compute psitilde_bs
3476
const double psitilde_bs_0_0 = 1;
3477
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3478
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
3479
const double psitilde_bs_1_0 = 1;
3480
const double psitilde_bs_1_1 = 2.5*y + 1.5;
3481
const double psitilde_bs_2_0 = 1;
3483
// Compute basisvalues
3484
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3485
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3486
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3487
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
3488
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
3489
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
3491
// Table(s) of coefficients
3492
static const double coefficients0[6][6] = \
3493
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
3494
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
3495
{0, 0, 0.2, 0, 0, 0.163299316},
3496
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
3497
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
3498
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
3500
// Extract relevant coefficients
3501
const double coeff0_0 = coefficients0[dof][0];
3502
const double coeff0_1 = coefficients0[dof][1];
3503
const double coeff0_2 = coefficients0[dof][2];
3504
const double coeff0_3 = coefficients0[dof][3];
3505
const double coeff0_4 = coefficients0[dof][4];
3506
const double coeff0_5 = coefficients0[dof][5];
3509
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
3512
/// Evaluate all basis functions at given point in cell
3513
virtual void evaluate_basis_all(double* values,
3514
const double* coordinates,
3515
const ufc::cell& c) const
3517
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3520
/// Evaluate order n derivatives of basis function i at given point in cell
3521
virtual void evaluate_basis_derivatives(unsigned int i,
3524
const double* coordinates,
3525
const ufc::cell& c) const
3527
// Extract vertex coordinates
3528
const double * const * element_coordinates = c.coordinates;
3530
// Compute Jacobian of affine map from reference cell
3531
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3532
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3533
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3534
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3536
// Compute determinant of Jacobian
3537
const double detJ = J_00*J_11 - J_01*J_10;
3539
// Compute inverse of Jacobian
3541
// Get coordinates and map to the reference (UFC) element
3542
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3543
element_coordinates[0][0]*element_coordinates[2][1] +\
3544
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3545
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3546
element_coordinates[1][0]*element_coordinates[0][1] -\
3547
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3549
// Map coordinates to the reference square
3550
if (std::abs(y - 1.0) < 1e-08)
3553
x = 2.0 *x/(1.0 - y) - 1.0;
3556
// Compute number of derivatives
3557
unsigned int num_derivatives = 1;
3559
for (unsigned int j = 0; j < n; j++)
3560
num_derivatives *= 2;
3563
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3564
unsigned int **combinations = new unsigned int *[num_derivatives];
3566
for (unsigned int j = 0; j < num_derivatives; j++)
3568
combinations[j] = new unsigned int [n];
3569
for (unsigned int k = 0; k < n; k++)
3570
combinations[j][k] = 0;
3573
// Generate combinations of derivatives
3574
for (unsigned int row = 1; row < num_derivatives; row++)
3576
for (unsigned int num = 0; num < row; num++)
3578
for (unsigned int col = n-1; col+1 > 0; col--)
3580
if (combinations[row][col] + 1 > 1)
3581
combinations[row][col] = 0;
3584
combinations[row][col] += 1;
3591
// Compute inverse of Jacobian
3592
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3594
// Declare transformation matrix
3595
// Declare pointer to two dimensional array and initialise
3596
double **transform = new double *[num_derivatives];
3598
for (unsigned int j = 0; j < num_derivatives; j++)
3600
transform[j] = new double [num_derivatives];
3601
for (unsigned int k = 0; k < num_derivatives; k++)
3602
transform[j][k] = 1;
3605
// Construct transformation matrix
3606
for (unsigned int row = 0; row < num_derivatives; row++)
3608
for (unsigned int col = 0; col < num_derivatives; col++)
3610
for (unsigned int k = 0; k < n; k++)
3611
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3616
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3619
// Map degree of freedom to element degree of freedom
3620
const unsigned int dof = i;
3622
// Generate scalings
3623
const double scalings_y_0 = 1;
3624
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3625
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
3627
// Compute psitilde_a
3628
const double psitilde_a_0 = 1;
3629
const double psitilde_a_1 = x;
3630
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
3632
// Compute psitilde_bs
3633
const double psitilde_bs_0_0 = 1;
3634
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3635
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
3636
const double psitilde_bs_1_0 = 1;
3637
const double psitilde_bs_1_1 = 2.5*y + 1.5;
3638
const double psitilde_bs_2_0 = 1;
3640
// Compute basisvalues
3641
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3642
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3643
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3644
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
3645
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
3646
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
3648
// Table(s) of coefficients
3649
static const double coefficients0[6][6] = \
3650
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
3651
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
3652
{0, 0, 0.2, 0, 0, 0.163299316},
3653
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
3654
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
3655
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
3657
// Interesting (new) part
3658
// Tables of derivatives of the polynomial base (transpose)
3659
static const double dmats0[6][6] = \
3660
{{0, 0, 0, 0, 0, 0},
3661
{4.89897949, 0, 0, 0, 0, 0},
3663
{0, 9.48683298, 0, 0, 0, 0},
3664
{4, 0, 7.07106781, 0, 0, 0},
3665
{0, 0, 0, 0, 0, 0}};
3667
static const double dmats1[6][6] = \
3668
{{0, 0, 0, 0, 0, 0},
3669
{2.44948974, 0, 0, 0, 0, 0},
3670
{4.24264069, 0, 0, 0, 0, 0},
3671
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
3672
{2, 6.12372436, 3.53553391, 0, 0, 0},
3673
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
3675
// Compute reference derivatives
3676
// Declare pointer to array of derivatives on FIAT element
3677
double *derivatives = new double [num_derivatives];
3679
// Declare coefficients
3680
double coeff0_0 = 0;
3681
double coeff0_1 = 0;
3682
double coeff0_2 = 0;
3683
double coeff0_3 = 0;
3684
double coeff0_4 = 0;
3685
double coeff0_5 = 0;
3687
// Declare new coefficients
3688
double new_coeff0_0 = 0;
3689
double new_coeff0_1 = 0;
3690
double new_coeff0_2 = 0;
3691
double new_coeff0_3 = 0;
3692
double new_coeff0_4 = 0;
3693
double new_coeff0_5 = 0;
3695
// Loop possible derivatives
3696
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3698
// Get values from coefficients array
3699
new_coeff0_0 = coefficients0[dof][0];
3700
new_coeff0_1 = coefficients0[dof][1];
3701
new_coeff0_2 = coefficients0[dof][2];
3702
new_coeff0_3 = coefficients0[dof][3];
3703
new_coeff0_4 = coefficients0[dof][4];
3704
new_coeff0_5 = coefficients0[dof][5];
3706
// Loop derivative order
3707
for (unsigned int j = 0; j < n; j++)
3709
// Update old coefficients
3710
coeff0_0 = new_coeff0_0;
3711
coeff0_1 = new_coeff0_1;
3712
coeff0_2 = new_coeff0_2;
3713
coeff0_3 = new_coeff0_3;
3714
coeff0_4 = new_coeff0_4;
3715
coeff0_5 = new_coeff0_5;
3717
if(combinations[deriv_num][j] == 0)
3719
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
3720
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
3721
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
3722
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
3723
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
3724
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
3726
if(combinations[deriv_num][j] == 1)
3728
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
3729
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
3730
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
3731
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
3732
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
3733
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
3737
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3738
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
3741
// Transform derivatives back to physical element
3742
for (unsigned int row = 0; row < num_derivatives; row++)
3744
for (unsigned int col = 0; col < num_derivatives; col++)
3746
values[row] += transform[row][col]*derivatives[col];
3749
// Delete pointer to array of derivatives on FIAT element
3750
delete [] derivatives;
3752
// Delete pointer to array of combinations of derivatives and transform
3753
for (unsigned int row = 0; row < num_derivatives; row++)
3755
delete [] combinations[row];
3756
delete [] transform[row];
3759
delete [] combinations;
3760
delete [] transform;
3763
/// Evaluate order n derivatives of all basis functions at given point in cell
3764
virtual void evaluate_basis_derivatives_all(unsigned int n,
3766
const double* coordinates,
3767
const ufc::cell& c) const
3769
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3772
/// Evaluate linear functional for dof i on the function f
3773
virtual double evaluate_dof(unsigned int i,
3774
const ufc::function& f,
3775
const ufc::cell& c) const
3777
// The reference points, direction and weights:
3778
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
3779
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
3780
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
3782
const double * const * x = c.coordinates;
3783
double result = 0.0;
3784
// Iterate over the points:
3785
// Evaluate basis functions for affine mapping
3786
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3787
const double w1 = X[i][0][0];
3788
const double w2 = X[i][0][1];
3790
// Compute affine mapping y = F(X)
3792
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3793
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3795
// Evaluate function at physical points
3797
f.evaluate(values, y, c);
3799
// Map function values using appropriate mapping
3800
// Affine map: Do nothing
3802
// Note that we do not map the weights (yet).
3804
// Take directional components
3805
for(int k = 0; k < 1; k++)
3806
result += values[k]*D[i][0][k];
3807
// Multiply by weights
3813
/// Evaluate linear functionals for all dofs on the function f
3814
virtual void evaluate_dofs(double* values,
3815
const ufc::function& f,
3816
const ufc::cell& c) const
3818
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3821
/// Interpolate vertex values from dof values
3822
virtual void interpolate_vertex_values(double* vertex_values,
3823
const double* dof_values,
3824
const ufc::cell& c) const
3826
// Evaluate at vertices and use affine mapping
3827
vertex_values[0] = dof_values[0];
3828
vertex_values[1] = dof_values[1];
3829
vertex_values[2] = dof_values[2];
3832
/// Return the number of sub elements (for a mixed element)
3833
virtual unsigned int num_sub_elements() const
3838
/// Create a new finite element for sub element i (for a mixed element)
3839
virtual ufc::finite_element* create_sub_element(unsigned int i) const
3841
return new stokes_0_finite_element_1_0_1();
3846
/// This class defines the interface for a finite element.
3848
class stokes_0_finite_element_1_0: public ufc::finite_element
3853
stokes_0_finite_element_1_0() : ufc::finite_element()
3859
virtual ~stokes_0_finite_element_1_0()
3864
/// Return a string identifying the finite element
3865
virtual const char* signature() const
3867
return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
3870
/// Return the cell shape
3871
virtual ufc::shape cell_shape() const
3873
return ufc::triangle;
3876
/// Return the dimension of the finite element function space
3877
virtual unsigned int space_dimension() const
3882
/// Return the rank of the value space
3883
virtual unsigned int value_rank() const
3888
/// Return the dimension of the value space for axis i
3889
virtual unsigned int value_dimension(unsigned int i) const
3894
/// Evaluate basis function i at given point in cell
3895
virtual void evaluate_basis(unsigned int i,
3897
const double* coordinates,
3898
const ufc::cell& c) const
3900
// Extract vertex coordinates
3901
const double * const * element_coordinates = c.coordinates;
3903
// Compute Jacobian of affine map from reference cell
3904
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3905
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3906
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3907
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3909
// Compute determinant of Jacobian
3910
const double detJ = J_00*J_11 - J_01*J_10;
3912
// Compute inverse of Jacobian
3914
// Get coordinates and map to the reference (UFC) element
3915
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3916
element_coordinates[0][0]*element_coordinates[2][1] +\
3917
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3918
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3919
element_coordinates[1][0]*element_coordinates[0][1] -\
3920
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3922
// Map coordinates to the reference square
3923
if (std::abs(y - 1.0) < 1e-08)
3926
x = 2.0 *x/(1.0 - y) - 1.0;
3933
if (0 <= i && i <= 5)
3935
// Map degree of freedom to element degree of freedom
3936
const unsigned int dof = i;
3938
// Generate scalings
3939
const double scalings_y_0 = 1;
3940
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3941
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
3943
// Compute psitilde_a
3944
const double psitilde_a_0 = 1;
3945
const double psitilde_a_1 = x;
3946
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
3948
// Compute psitilde_bs
3949
const double psitilde_bs_0_0 = 1;
3950
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3951
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
3952
const double psitilde_bs_1_0 = 1;
3953
const double psitilde_bs_1_1 = 2.5*y + 1.5;
3954
const double psitilde_bs_2_0 = 1;
3956
// Compute basisvalues
3957
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3958
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3959
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3960
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
3961
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
3962
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
3964
// Table(s) of coefficients
3965
static const double coefficients0[6][6] = \
3966
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
3967
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
3968
{0, 0, 0.2, 0, 0, 0.163299316},
3969
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
3970
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
3971
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
3973
// Extract relevant coefficients
3974
const double coeff0_0 = coefficients0[dof][0];
3975
const double coeff0_1 = coefficients0[dof][1];
3976
const double coeff0_2 = coefficients0[dof][2];
3977
const double coeff0_3 = coefficients0[dof][3];
3978
const double coeff0_4 = coefficients0[dof][4];
3979
const double coeff0_5 = coefficients0[dof][5];
3982
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
3985
if (6 <= i && i <= 11)
3987
// Map degree of freedom to element degree of freedom
3988
const unsigned int dof = i - 6;
3990
// Generate scalings
3991
const double scalings_y_0 = 1;
3992
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3993
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
3995
// Compute psitilde_a
3996
const double psitilde_a_0 = 1;
3997
const double psitilde_a_1 = x;
3998
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
4000
// Compute psitilde_bs
4001
const double psitilde_bs_0_0 = 1;
4002
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4003
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
4004
const double psitilde_bs_1_0 = 1;
4005
const double psitilde_bs_1_1 = 2.5*y + 1.5;
4006
const double psitilde_bs_2_0 = 1;
4008
// Compute basisvalues
4009
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4010
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4011
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4012
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
4013
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
4014
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
4016
// Table(s) of coefficients
4017
static const double coefficients0[6][6] = \
4018
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
4019
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
4020
{0, 0, 0.2, 0, 0, 0.163299316},
4021
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
4022
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
4023
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
4025
// Extract relevant coefficients
4026
const double coeff0_0 = coefficients0[dof][0];
4027
const double coeff0_1 = coefficients0[dof][1];
4028
const double coeff0_2 = coefficients0[dof][2];
4029
const double coeff0_3 = coefficients0[dof][3];
4030
const double coeff0_4 = coefficients0[dof][4];
4031
const double coeff0_5 = coefficients0[dof][5];
4034
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
4039
/// Evaluate all basis functions at given point in cell
4040
virtual void evaluate_basis_all(double* values,
4041
const double* coordinates,
4042
const ufc::cell& c) const
4044
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4047
/// Evaluate order n derivatives of basis function i at given point in cell
4048
virtual void evaluate_basis_derivatives(unsigned int i,
4051
const double* coordinates,
4052
const ufc::cell& c) const
4054
// Extract vertex coordinates
4055
const double * const * element_coordinates = c.coordinates;
4057
// Compute Jacobian of affine map from reference cell
4058
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4059
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4060
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4061
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4063
// Compute determinant of Jacobian
4064
const double detJ = J_00*J_11 - J_01*J_10;
4066
// Compute inverse of Jacobian
4068
// Get coordinates and map to the reference (UFC) element
4069
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4070
element_coordinates[0][0]*element_coordinates[2][1] +\
4071
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4072
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4073
element_coordinates[1][0]*element_coordinates[0][1] -\
4074
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4076
// Map coordinates to the reference square
4077
if (std::abs(y - 1.0) < 1e-08)
4080
x = 2.0 *x/(1.0 - y) - 1.0;
4083
// Compute number of derivatives
4084
unsigned int num_derivatives = 1;
4086
for (unsigned int j = 0; j < n; j++)
4087
num_derivatives *= 2;
4090
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4091
unsigned int **combinations = new unsigned int *[num_derivatives];
4093
for (unsigned int j = 0; j < num_derivatives; j++)
4095
combinations[j] = new unsigned int [n];
4096
for (unsigned int k = 0; k < n; k++)
4097
combinations[j][k] = 0;
4100
// Generate combinations of derivatives
4101
for (unsigned int row = 1; row < num_derivatives; row++)
4103
for (unsigned int num = 0; num < row; num++)
4105
for (unsigned int col = n-1; col+1 > 0; col--)
4107
if (combinations[row][col] + 1 > 1)
4108
combinations[row][col] = 0;
4111
combinations[row][col] += 1;
4118
// Compute inverse of Jacobian
4119
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4121
// Declare transformation matrix
4122
// Declare pointer to two dimensional array and initialise
4123
double **transform = new double *[num_derivatives];
4125
for (unsigned int j = 0; j < num_derivatives; j++)
4127
transform[j] = new double [num_derivatives];
4128
for (unsigned int k = 0; k < num_derivatives; k++)
4129
transform[j][k] = 1;
4132
// Construct transformation matrix
4133
for (unsigned int row = 0; row < num_derivatives; row++)
4135
for (unsigned int col = 0; col < num_derivatives; col++)
4137
for (unsigned int k = 0; k < n; k++)
4138
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4143
for (unsigned int j = 0; j < 2*num_derivatives; j++)
4146
if (0 <= i && i <= 5)
4148
// Map degree of freedom to element degree of freedom
4149
const unsigned int dof = i;
4151
// Generate scalings
4152
const double scalings_y_0 = 1;
4153
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4154
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
4156
// Compute psitilde_a
4157
const double psitilde_a_0 = 1;
4158
const double psitilde_a_1 = x;
4159
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
4161
// Compute psitilde_bs
4162
const double psitilde_bs_0_0 = 1;
4163
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4164
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
4165
const double psitilde_bs_1_0 = 1;
4166
const double psitilde_bs_1_1 = 2.5*y + 1.5;
4167
const double psitilde_bs_2_0 = 1;
4169
// Compute basisvalues
4170
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4171
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4172
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4173
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
4174
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
4175
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
4177
// Table(s) of coefficients
4178
static const double coefficients0[6][6] = \
4179
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
4180
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
4181
{0, 0, 0.2, 0, 0, 0.163299316},
4182
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
4183
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
4184
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
4186
// Interesting (new) part
4187
// Tables of derivatives of the polynomial base (transpose)
4188
static const double dmats0[6][6] = \
4189
{{0, 0, 0, 0, 0, 0},
4190
{4.89897949, 0, 0, 0, 0, 0},
4192
{0, 9.48683298, 0, 0, 0, 0},
4193
{4, 0, 7.07106781, 0, 0, 0},
4194
{0, 0, 0, 0, 0, 0}};
4196
static const double dmats1[6][6] = \
4197
{{0, 0, 0, 0, 0, 0},
4198
{2.44948974, 0, 0, 0, 0, 0},
4199
{4.24264069, 0, 0, 0, 0, 0},
4200
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
4201
{2, 6.12372436, 3.53553391, 0, 0, 0},
4202
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
4204
// Compute reference derivatives
4205
// Declare pointer to array of derivatives on FIAT element
4206
double *derivatives = new double [num_derivatives];
4208
// Declare coefficients
4209
double coeff0_0 = 0;
4210
double coeff0_1 = 0;
4211
double coeff0_2 = 0;
4212
double coeff0_3 = 0;
4213
double coeff0_4 = 0;
4214
double coeff0_5 = 0;
4216
// Declare new coefficients
4217
double new_coeff0_0 = 0;
4218
double new_coeff0_1 = 0;
4219
double new_coeff0_2 = 0;
4220
double new_coeff0_3 = 0;
4221
double new_coeff0_4 = 0;
4222
double new_coeff0_5 = 0;
4224
// Loop possible derivatives
4225
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4227
// Get values from coefficients array
4228
new_coeff0_0 = coefficients0[dof][0];
4229
new_coeff0_1 = coefficients0[dof][1];
4230
new_coeff0_2 = coefficients0[dof][2];
4231
new_coeff0_3 = coefficients0[dof][3];
4232
new_coeff0_4 = coefficients0[dof][4];
4233
new_coeff0_5 = coefficients0[dof][5];
4235
// Loop derivative order
4236
for (unsigned int j = 0; j < n; j++)
4238
// Update old coefficients
4239
coeff0_0 = new_coeff0_0;
4240
coeff0_1 = new_coeff0_1;
4241
coeff0_2 = new_coeff0_2;
4242
coeff0_3 = new_coeff0_3;
4243
coeff0_4 = new_coeff0_4;
4244
coeff0_5 = new_coeff0_5;
4246
if(combinations[deriv_num][j] == 0)
4248
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
4249
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
4250
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
4251
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
4252
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
4253
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
4255
if(combinations[deriv_num][j] == 1)
4257
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
4258
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
4259
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
4260
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
4261
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
4262
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
4266
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4267
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
4270
// Transform derivatives back to physical element
4271
for (unsigned int row = 0; row < num_derivatives; row++)
4273
for (unsigned int col = 0; col < num_derivatives; col++)
4275
values[row] += transform[row][col]*derivatives[col];
4278
// Delete pointer to array of derivatives on FIAT element
4279
delete [] derivatives;
4281
// Delete pointer to array of combinations of derivatives and transform
4282
for (unsigned int row = 0; row < num_derivatives; row++)
4284
delete [] combinations[row];
4285
delete [] transform[row];
4288
delete [] combinations;
4289
delete [] transform;
4292
if (6 <= i && i <= 11)
4294
// Map degree of freedom to element degree of freedom
4295
const unsigned int dof = i - 6;
4297
// Generate scalings
4298
const double scalings_y_0 = 1;
4299
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4300
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
4302
// Compute psitilde_a
4303
const double psitilde_a_0 = 1;
4304
const double psitilde_a_1 = x;
4305
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
4307
// Compute psitilde_bs
4308
const double psitilde_bs_0_0 = 1;
4309
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4310
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
4311
const double psitilde_bs_1_0 = 1;
4312
const double psitilde_bs_1_1 = 2.5*y + 1.5;
4313
const double psitilde_bs_2_0 = 1;
4315
// Compute basisvalues
4316
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4317
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4318
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4319
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
4320
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
4321
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
4323
// Table(s) of coefficients
4324
static const double coefficients0[6][6] = \
4325
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
4326
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
4327
{0, 0, 0.2, 0, 0, 0.163299316},
4328
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
4329
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
4330
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
4332
// Interesting (new) part
4333
// Tables of derivatives of the polynomial base (transpose)
4334
static const double dmats0[6][6] = \
4335
{{0, 0, 0, 0, 0, 0},
4336
{4.89897949, 0, 0, 0, 0, 0},
4338
{0, 9.48683298, 0, 0, 0, 0},
4339
{4, 0, 7.07106781, 0, 0, 0},
4340
{0, 0, 0, 0, 0, 0}};
4342
static const double dmats1[6][6] = \
4343
{{0, 0, 0, 0, 0, 0},
4344
{2.44948974, 0, 0, 0, 0, 0},
4345
{4.24264069, 0, 0, 0, 0, 0},
4346
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
4347
{2, 6.12372436, 3.53553391, 0, 0, 0},
4348
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
4350
// Compute reference derivatives
4351
// Declare pointer to array of derivatives on FIAT element
4352
double *derivatives = new double [num_derivatives];
4354
// Declare coefficients
4355
double coeff0_0 = 0;
4356
double coeff0_1 = 0;
4357
double coeff0_2 = 0;
4358
double coeff0_3 = 0;
4359
double coeff0_4 = 0;
4360
double coeff0_5 = 0;
4362
// Declare new coefficients
4363
double new_coeff0_0 = 0;
4364
double new_coeff0_1 = 0;
4365
double new_coeff0_2 = 0;
4366
double new_coeff0_3 = 0;
4367
double new_coeff0_4 = 0;
4368
double new_coeff0_5 = 0;
4370
// Loop possible derivatives
4371
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4373
// Get values from coefficients array
4374
new_coeff0_0 = coefficients0[dof][0];
4375
new_coeff0_1 = coefficients0[dof][1];
4376
new_coeff0_2 = coefficients0[dof][2];
4377
new_coeff0_3 = coefficients0[dof][3];
4378
new_coeff0_4 = coefficients0[dof][4];
4379
new_coeff0_5 = coefficients0[dof][5];
4381
// Loop derivative order
4382
for (unsigned int j = 0; j < n; j++)
4384
// Update old coefficients
4385
coeff0_0 = new_coeff0_0;
4386
coeff0_1 = new_coeff0_1;
4387
coeff0_2 = new_coeff0_2;
4388
coeff0_3 = new_coeff0_3;
4389
coeff0_4 = new_coeff0_4;
4390
coeff0_5 = new_coeff0_5;
4392
if(combinations[deriv_num][j] == 0)
4394
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
4395
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
4396
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
4397
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
4398
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
4399
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
4401
if(combinations[deriv_num][j] == 1)
4403
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
4404
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
4405
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
4406
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
4407
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
4408
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
4412
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4413
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
4416
// Transform derivatives back to physical element
4417
for (unsigned int row = 0; row < num_derivatives; row++)
4419
for (unsigned int col = 0; col < num_derivatives; col++)
4421
values[num_derivatives + row] += transform[row][col]*derivatives[col];
4424
// Delete pointer to array of derivatives on FIAT element
4425
delete [] derivatives;
4427
// Delete pointer to array of combinations of derivatives and transform
4428
for (unsigned int row = 0; row < num_derivatives; row++)
4430
delete [] combinations[row];
4431
delete [] transform[row];
4434
delete [] combinations;
4435
delete [] transform;
4440
/// Evaluate order n derivatives of all basis functions at given point in cell
4441
virtual void evaluate_basis_derivatives_all(unsigned int n,
4443
const double* coordinates,
4444
const ufc::cell& c) const
4446
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4449
/// Evaluate linear functional for dof i on the function f
4450
virtual double evaluate_dof(unsigned int i,
4451
const ufc::function& f,
4452
const ufc::cell& c) const
4454
// The reference points, direction and weights:
4455
static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
4456
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
4457
static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
4459
const double * const * x = c.coordinates;
4460
double result = 0.0;
4461
// Iterate over the points:
4462
// Evaluate basis functions for affine mapping
4463
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4464
const double w1 = X[i][0][0];
4465
const double w2 = X[i][0][1];
4467
// Compute affine mapping y = F(X)
4469
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4470
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4472
// Evaluate function at physical points
4474
f.evaluate(values, y, c);
4476
// Map function values using appropriate mapping
4477
// Affine map: Do nothing
4479
// Note that we do not map the weights (yet).
4481
// Take directional components
4482
for(int k = 0; k < 2; k++)
4483
result += values[k]*D[i][0][k];
4484
// Multiply by weights
4490
/// Evaluate linear functionals for all dofs on the function f
4491
virtual void evaluate_dofs(double* values,
4492
const ufc::function& f,
4493
const ufc::cell& c) const
4495
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4498
/// Interpolate vertex values from dof values
4499
virtual void interpolate_vertex_values(double* vertex_values,
4500
const double* dof_values,
4501
const ufc::cell& c) const
4503
// Evaluate at vertices and use affine mapping
4504
vertex_values[0] = dof_values[0];
4505
vertex_values[2] = dof_values[1];
4506
vertex_values[4] = dof_values[2];
4507
// Evaluate at vertices and use affine mapping
4508
vertex_values[1] = dof_values[6];
4509
vertex_values[3] = dof_values[7];
4510
vertex_values[5] = dof_values[8];
4513
/// Return the number of sub elements (for a mixed element)
4514
virtual unsigned int num_sub_elements() const
4519
/// Create a new finite element for sub element i (for a mixed element)
4520
virtual ufc::finite_element* create_sub_element(unsigned int i) const
4525
return new stokes_0_finite_element_1_0_0();
4528
return new stokes_0_finite_element_1_0_1();
4536
/// This class defines the interface for a finite element.
4538
class stokes_0_finite_element_1_1: public ufc::finite_element
4543
stokes_0_finite_element_1_1() : ufc::finite_element()
4549
virtual ~stokes_0_finite_element_1_1()
4554
/// Return a string identifying the finite element
4555
virtual const char* signature() const
4557
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
4560
/// Return the cell shape
4561
virtual ufc::shape cell_shape() const
4563
return ufc::triangle;
4566
/// Return the dimension of the finite element function space
4567
virtual unsigned int space_dimension() const
4572
/// Return the rank of the value space
4573
virtual unsigned int value_rank() const
4578
/// Return the dimension of the value space for axis i
4579
virtual unsigned int value_dimension(unsigned int i) const
4584
/// Evaluate basis function i at given point in cell
4585
virtual void evaluate_basis(unsigned int i,
4587
const double* coordinates,
4588
const ufc::cell& c) const
4590
// Extract vertex coordinates
4591
const double * const * element_coordinates = c.coordinates;
4593
// Compute Jacobian of affine map from reference cell
4594
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4595
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4596
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4597
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4599
// Compute determinant of Jacobian
4600
const double detJ = J_00*J_11 - J_01*J_10;
4602
// Compute inverse of Jacobian
4604
// Get coordinates and map to the reference (UFC) element
4605
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4606
element_coordinates[0][0]*element_coordinates[2][1] +\
4607
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4608
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4609
element_coordinates[1][0]*element_coordinates[0][1] -\
4610
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4612
// Map coordinates to the reference square
4613
if (std::abs(y - 1.0) < 1e-08)
4616
x = 2.0 *x/(1.0 - y) - 1.0;
4622
// Map degree of freedom to element degree of freedom
4623
const unsigned int dof = i;
4625
// Generate scalings
4626
const double scalings_y_0 = 1;
4627
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4629
// Compute psitilde_a
4630
const double psitilde_a_0 = 1;
4631
const double psitilde_a_1 = x;
4633
// Compute psitilde_bs
4634
const double psitilde_bs_0_0 = 1;
4635
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4636
const double psitilde_bs_1_0 = 1;
4638
// Compute basisvalues
4639
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4640
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4641
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4643
// Table(s) of coefficients
4644
static const double coefficients0[3][3] = \
4645
{{0.471404521, -0.288675135, -0.166666667},
4646
{0.471404521, 0.288675135, -0.166666667},
4647
{0.471404521, 0, 0.333333333}};
4649
// Extract relevant coefficients
4650
const double coeff0_0 = coefficients0[dof][0];
4651
const double coeff0_1 = coefficients0[dof][1];
4652
const double coeff0_2 = coefficients0[dof][2];
4655
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
4658
/// Evaluate all basis functions at given point in cell
4659
virtual void evaluate_basis_all(double* values,
4660
const double* coordinates,
4661
const ufc::cell& c) const
4663
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4666
/// Evaluate order n derivatives of basis function i at given point in cell
4667
virtual void evaluate_basis_derivatives(unsigned int i,
4670
const double* coordinates,
4671
const ufc::cell& c) const
4673
// Extract vertex coordinates
4674
const double * const * element_coordinates = c.coordinates;
4676
// Compute Jacobian of affine map from reference cell
4677
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4678
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4679
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4680
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4682
// Compute determinant of Jacobian
4683
const double detJ = J_00*J_11 - J_01*J_10;
4685
// Compute inverse of Jacobian
4687
// Get coordinates and map to the reference (UFC) element
4688
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4689
element_coordinates[0][0]*element_coordinates[2][1] +\
4690
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4691
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4692
element_coordinates[1][0]*element_coordinates[0][1] -\
4693
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4695
// Map coordinates to the reference square
4696
if (std::abs(y - 1.0) < 1e-08)
4699
x = 2.0 *x/(1.0 - y) - 1.0;
4702
// Compute number of derivatives
4703
unsigned int num_derivatives = 1;
4705
for (unsigned int j = 0; j < n; j++)
4706
num_derivatives *= 2;
4709
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4710
unsigned int **combinations = new unsigned int *[num_derivatives];
4712
for (unsigned int j = 0; j < num_derivatives; j++)
4714
combinations[j] = new unsigned int [n];
4715
for (unsigned int k = 0; k < n; k++)
4716
combinations[j][k] = 0;
4719
// Generate combinations of derivatives
4720
for (unsigned int row = 1; row < num_derivatives; row++)
4722
for (unsigned int num = 0; num < row; num++)
4724
for (unsigned int col = n-1; col+1 > 0; col--)
4726
if (combinations[row][col] + 1 > 1)
4727
combinations[row][col] = 0;
4730
combinations[row][col] += 1;
4737
// Compute inverse of Jacobian
4738
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4740
// Declare transformation matrix
4741
// Declare pointer to two dimensional array and initialise
4742
double **transform = new double *[num_derivatives];
4744
for (unsigned int j = 0; j < num_derivatives; j++)
4746
transform[j] = new double [num_derivatives];
4747
for (unsigned int k = 0; k < num_derivatives; k++)
4748
transform[j][k] = 1;
4751
// Construct transformation matrix
4752
for (unsigned int row = 0; row < num_derivatives; row++)
4754
for (unsigned int col = 0; col < num_derivatives; col++)
4756
for (unsigned int k = 0; k < n; k++)
4757
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4762
for (unsigned int j = 0; j < 1*num_derivatives; j++)
4765
// Map degree of freedom to element degree of freedom
4766
const unsigned int dof = i;
4768
// Generate scalings
4769
const double scalings_y_0 = 1;
4770
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4772
// Compute psitilde_a
4773
const double psitilde_a_0 = 1;
4774
const double psitilde_a_1 = x;
4776
// Compute psitilde_bs
4777
const double psitilde_bs_0_0 = 1;
4778
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4779
const double psitilde_bs_1_0 = 1;
4781
// Compute basisvalues
4782
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4783
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4784
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4786
// Table(s) of coefficients
4787
static const double coefficients0[3][3] = \
4788
{{0.471404521, -0.288675135, -0.166666667},
4789
{0.471404521, 0.288675135, -0.166666667},
4790
{0.471404521, 0, 0.333333333}};
4792
// Interesting (new) part
4793
// Tables of derivatives of the polynomial base (transpose)
4794
static const double dmats0[3][3] = \
4799
static const double dmats1[3][3] = \
4802
{4.24264069, 0, 0}};
4804
// Compute reference derivatives
4805
// Declare pointer to array of derivatives on FIAT element
4806
double *derivatives = new double [num_derivatives];
4808
// Declare coefficients
4809
double coeff0_0 = 0;
4810
double coeff0_1 = 0;
4811
double coeff0_2 = 0;
4813
// Declare new coefficients
4814
double new_coeff0_0 = 0;
4815
double new_coeff0_1 = 0;
4816
double new_coeff0_2 = 0;
4818
// Loop possible derivatives
4819
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4821
// Get values from coefficients array
4822
new_coeff0_0 = coefficients0[dof][0];
4823
new_coeff0_1 = coefficients0[dof][1];
4824
new_coeff0_2 = coefficients0[dof][2];
4826
// Loop derivative order
4827
for (unsigned int j = 0; j < n; j++)
4829
// Update old coefficients
4830
coeff0_0 = new_coeff0_0;
4831
coeff0_1 = new_coeff0_1;
4832
coeff0_2 = new_coeff0_2;
4834
if(combinations[deriv_num][j] == 0)
4836
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
4837
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
4838
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
4840
if(combinations[deriv_num][j] == 1)
4842
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
4843
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
4844
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
4848
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4849
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
4852
// Transform derivatives back to physical element
4853
for (unsigned int row = 0; row < num_derivatives; row++)
4855
for (unsigned int col = 0; col < num_derivatives; col++)
4857
values[row] += transform[row][col]*derivatives[col];
4860
// Delete pointer to array of derivatives on FIAT element
4861
delete [] derivatives;
4863
// Delete pointer to array of combinations of derivatives and transform
4864
for (unsigned int row = 0; row < num_derivatives; row++)
4866
delete [] combinations[row];
4867
delete [] transform[row];
4870
delete [] combinations;
4871
delete [] transform;
4874
/// Evaluate order n derivatives of all basis functions at given point in cell
4875
virtual void evaluate_basis_derivatives_all(unsigned int n,
4877
const double* coordinates,
4878
const ufc::cell& c) const
4880
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4883
/// Evaluate linear functional for dof i on the function f
4884
virtual double evaluate_dof(unsigned int i,
4885
const ufc::function& f,
4886
const ufc::cell& c) const
4888
// The reference points, direction and weights:
4889
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
4890
static const double W[3][1] = {{1}, {1}, {1}};
4891
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
4893
const double * const * x = c.coordinates;
4894
double result = 0.0;
4895
// Iterate over the points:
4896
// Evaluate basis functions for affine mapping
4897
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4898
const double w1 = X[i][0][0];
4899
const double w2 = X[i][0][1];
4901
// Compute affine mapping y = F(X)
4903
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4904
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4906
// Evaluate function at physical points
4908
f.evaluate(values, y, c);
4910
// Map function values using appropriate mapping
4911
// Affine map: Do nothing
4913
// Note that we do not map the weights (yet).
4915
// Take directional components
4916
for(int k = 0; k < 1; k++)
4917
result += values[k]*D[i][0][k];
4918
// Multiply by weights
4924
/// Evaluate linear functionals for all dofs on the function f
4925
virtual void evaluate_dofs(double* values,
4926
const ufc::function& f,
4927
const ufc::cell& c) const
4929
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4932
/// Interpolate vertex values from dof values
4933
virtual void interpolate_vertex_values(double* vertex_values,
4934
const double* dof_values,
4935
const ufc::cell& c) const
4937
// Evaluate at vertices and use affine mapping
4938
vertex_values[0] = dof_values[0];
4939
vertex_values[1] = dof_values[1];
4940
vertex_values[2] = dof_values[2];
4943
/// Return the number of sub elements (for a mixed element)
4944
virtual unsigned int num_sub_elements() const
4949
/// Create a new finite element for sub element i (for a mixed element)
4950
virtual ufc::finite_element* create_sub_element(unsigned int i) const
4952
return new stokes_0_finite_element_1_1();
4957
/// This class defines the interface for a finite element.
4959
class stokes_0_finite_element_1: public ufc::finite_element
4964
stokes_0_finite_element_1() : ufc::finite_element()
4970
virtual ~stokes_0_finite_element_1()
4975
/// Return a string identifying the finite element
4976
virtual const char* signature() const
4978
return "MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) })";
4981
/// Return the cell shape
4982
virtual ufc::shape cell_shape() const
4984
return ufc::triangle;
4987
/// Return the dimension of the finite element function space
4988
virtual unsigned int space_dimension() const
4993
/// Return the rank of the value space
4994
virtual unsigned int value_rank() const
4999
/// Return the dimension of the value space for axis i
5000
virtual unsigned int value_dimension(unsigned int i) const
5005
/// Evaluate basis function i at given point in cell
5006
virtual void evaluate_basis(unsigned int i,
5008
const double* coordinates,
5009
const ufc::cell& c) const
5011
// Extract vertex coordinates
5012
const double * const * element_coordinates = c.coordinates;
5014
// Compute Jacobian of affine map from reference cell
5015
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5016
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5017
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5018
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5020
// Compute determinant of Jacobian
5021
const double detJ = J_00*J_11 - J_01*J_10;
5023
// Compute inverse of Jacobian
5025
// Get coordinates and map to the reference (UFC) element
5026
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5027
element_coordinates[0][0]*element_coordinates[2][1] +\
5028
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5029
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5030
element_coordinates[1][0]*element_coordinates[0][1] -\
5031
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5033
// Map coordinates to the reference square
5034
if (std::abs(y - 1.0) < 1e-08)
5037
x = 2.0 *x/(1.0 - y) - 1.0;
5045
if (0 <= i && i <= 5)
5047
// Map degree of freedom to element degree of freedom
5048
const unsigned int dof = i;
5050
// Generate scalings
5051
const double scalings_y_0 = 1;
5052
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5053
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
5055
// Compute psitilde_a
5056
const double psitilde_a_0 = 1;
5057
const double psitilde_a_1 = x;
5058
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
5060
// Compute psitilde_bs
5061
const double psitilde_bs_0_0 = 1;
5062
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5063
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
5064
const double psitilde_bs_1_0 = 1;
5065
const double psitilde_bs_1_1 = 2.5*y + 1.5;
5066
const double psitilde_bs_2_0 = 1;
5068
// Compute basisvalues
5069
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5070
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
5071
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
5072
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
5073
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
5074
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
5076
// Table(s) of coefficients
5077
static const double coefficients0[6][6] = \
5078
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
5079
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
5080
{0, 0, 0.2, 0, 0, 0.163299316},
5081
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
5082
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
5083
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
5085
// Extract relevant coefficients
5086
const double coeff0_0 = coefficients0[dof][0];
5087
const double coeff0_1 = coefficients0[dof][1];
5088
const double coeff0_2 = coefficients0[dof][2];
5089
const double coeff0_3 = coefficients0[dof][3];
5090
const double coeff0_4 = coefficients0[dof][4];
5091
const double coeff0_5 = coefficients0[dof][5];
5094
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
5097
if (6 <= i && i <= 11)
5099
// Map degree of freedom to element degree of freedom
5100
const unsigned int dof = i - 6;
5102
// Generate scalings
5103
const double scalings_y_0 = 1;
5104
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5105
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
5107
// Compute psitilde_a
5108
const double psitilde_a_0 = 1;
5109
const double psitilde_a_1 = x;
5110
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
5112
// Compute psitilde_bs
5113
const double psitilde_bs_0_0 = 1;
5114
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5115
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
5116
const double psitilde_bs_1_0 = 1;
5117
const double psitilde_bs_1_1 = 2.5*y + 1.5;
5118
const double psitilde_bs_2_0 = 1;
5120
// Compute basisvalues
5121
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5122
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
5123
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
5124
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
5125
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
5126
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
5128
// Table(s) of coefficients
5129
static const double coefficients0[6][6] = \
5130
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
5131
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
5132
{0, 0, 0.2, 0, 0, 0.163299316},
5133
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
5134
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
5135
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
5137
// Extract relevant coefficients
5138
const double coeff0_0 = coefficients0[dof][0];
5139
const double coeff0_1 = coefficients0[dof][1];
5140
const double coeff0_2 = coefficients0[dof][2];
5141
const double coeff0_3 = coefficients0[dof][3];
5142
const double coeff0_4 = coefficients0[dof][4];
5143
const double coeff0_5 = coefficients0[dof][5];
5146
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
5149
if (12 <= i && i <= 14)
5151
// Map degree of freedom to element degree of freedom
5152
const unsigned int dof = i - 12;
5154
// Generate scalings
5155
const double scalings_y_0 = 1;
5156
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5158
// Compute psitilde_a
5159
const double psitilde_a_0 = 1;
5160
const double psitilde_a_1 = x;
5162
// Compute psitilde_bs
5163
const double psitilde_bs_0_0 = 1;
5164
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5165
const double psitilde_bs_1_0 = 1;
5167
// Compute basisvalues
5168
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5169
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
5170
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
5172
// Table(s) of coefficients
5173
static const double coefficients0[3][3] = \
5174
{{0.471404521, -0.288675135, -0.166666667},
5175
{0.471404521, 0.288675135, -0.166666667},
5176
{0.471404521, 0, 0.333333333}};
5178
// Extract relevant coefficients
5179
const double coeff0_0 = coefficients0[dof][0];
5180
const double coeff0_1 = coefficients0[dof][1];
5181
const double coeff0_2 = coefficients0[dof][2];
5184
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
5189
/// Evaluate all basis functions at given point in cell
5190
virtual void evaluate_basis_all(double* values,
5191
const double* coordinates,
5192
const ufc::cell& c) const
5194
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5197
/// Evaluate order n derivatives of basis function i at given point in cell
5198
virtual void evaluate_basis_derivatives(unsigned int i,
5201
const double* coordinates,
5202
const ufc::cell& c) const
5204
// Extract vertex coordinates
5205
const double * const * element_coordinates = c.coordinates;
5207
// Compute Jacobian of affine map from reference cell
5208
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5209
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5210
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5211
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5213
// Compute determinant of Jacobian
5214
const double detJ = J_00*J_11 - J_01*J_10;
5216
// Compute inverse of Jacobian
5218
// Get coordinates and map to the reference (UFC) element
5219
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5220
element_coordinates[0][0]*element_coordinates[2][1] +\
5221
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5222
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5223
element_coordinates[1][0]*element_coordinates[0][1] -\
5224
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5226
// Map coordinates to the reference square
5227
if (std::abs(y - 1.0) < 1e-08)
5230
x = 2.0 *x/(1.0 - y) - 1.0;
5233
// Compute number of derivatives
5234
unsigned int num_derivatives = 1;
5236
for (unsigned int j = 0; j < n; j++)
5237
num_derivatives *= 2;
5240
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5241
unsigned int **combinations = new unsigned int *[num_derivatives];
5243
for (unsigned int j = 0; j < num_derivatives; j++)
5245
combinations[j] = new unsigned int [n];
5246
for (unsigned int k = 0; k < n; k++)
5247
combinations[j][k] = 0;
5250
// Generate combinations of derivatives
5251
for (unsigned int row = 1; row < num_derivatives; row++)
5253
for (unsigned int num = 0; num < row; num++)
5255
for (unsigned int col = n-1; col+1 > 0; col--)
5257
if (combinations[row][col] + 1 > 1)
5258
combinations[row][col] = 0;
5261
combinations[row][col] += 1;
5268
// Compute inverse of Jacobian
5269
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
5271
// Declare transformation matrix
5272
// Declare pointer to two dimensional array and initialise
5273
double **transform = new double *[num_derivatives];
5275
for (unsigned int j = 0; j < num_derivatives; j++)
5277
transform[j] = new double [num_derivatives];
5278
for (unsigned int k = 0; k < num_derivatives; k++)
5279
transform[j][k] = 1;
5282
// Construct transformation matrix
5283
for (unsigned int row = 0; row < num_derivatives; row++)
5285
for (unsigned int col = 0; col < num_derivatives; col++)
5287
for (unsigned int k = 0; k < n; k++)
5288
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5293
for (unsigned int j = 0; j < 3*num_derivatives; j++)
5296
if (0 <= i && i <= 5)
5298
// Map degree of freedom to element degree of freedom
5299
const unsigned int dof = i;
5301
// Generate scalings
5302
const double scalings_y_0 = 1;
5303
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5304
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
5306
// Compute psitilde_a
5307
const double psitilde_a_0 = 1;
5308
const double psitilde_a_1 = x;
5309
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
5311
// Compute psitilde_bs
5312
const double psitilde_bs_0_0 = 1;
5313
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5314
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
5315
const double psitilde_bs_1_0 = 1;
5316
const double psitilde_bs_1_1 = 2.5*y + 1.5;
5317
const double psitilde_bs_2_0 = 1;
5319
// Compute basisvalues
5320
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5321
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
5322
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
5323
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
5324
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
5325
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
5327
// Table(s) of coefficients
5328
static const double coefficients0[6][6] = \
5329
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
5330
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
5331
{0, 0, 0.2, 0, 0, 0.163299316},
5332
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
5333
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
5334
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
5336
// Interesting (new) part
5337
// Tables of derivatives of the polynomial base (transpose)
5338
static const double dmats0[6][6] = \
5339
{{0, 0, 0, 0, 0, 0},
5340
{4.89897949, 0, 0, 0, 0, 0},
5342
{0, 9.48683298, 0, 0, 0, 0},
5343
{4, 0, 7.07106781, 0, 0, 0},
5344
{0, 0, 0, 0, 0, 0}};
5346
static const double dmats1[6][6] = \
5347
{{0, 0, 0, 0, 0, 0},
5348
{2.44948974, 0, 0, 0, 0, 0},
5349
{4.24264069, 0, 0, 0, 0, 0},
5350
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
5351
{2, 6.12372436, 3.53553391, 0, 0, 0},
5352
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
5354
// Compute reference derivatives
5355
// Declare pointer to array of derivatives on FIAT element
5356
double *derivatives = new double [num_derivatives];
5358
// Declare coefficients
5359
double coeff0_0 = 0;
5360
double coeff0_1 = 0;
5361
double coeff0_2 = 0;
5362
double coeff0_3 = 0;
5363
double coeff0_4 = 0;
5364
double coeff0_5 = 0;
5366
// Declare new coefficients
5367
double new_coeff0_0 = 0;
5368
double new_coeff0_1 = 0;
5369
double new_coeff0_2 = 0;
5370
double new_coeff0_3 = 0;
5371
double new_coeff0_4 = 0;
5372
double new_coeff0_5 = 0;
5374
// Loop possible derivatives
5375
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5377
// Get values from coefficients array
5378
new_coeff0_0 = coefficients0[dof][0];
5379
new_coeff0_1 = coefficients0[dof][1];
5380
new_coeff0_2 = coefficients0[dof][2];
5381
new_coeff0_3 = coefficients0[dof][3];
5382
new_coeff0_4 = coefficients0[dof][4];
5383
new_coeff0_5 = coefficients0[dof][5];
5385
// Loop derivative order
5386
for (unsigned int j = 0; j < n; j++)
5388
// Update old coefficients
5389
coeff0_0 = new_coeff0_0;
5390
coeff0_1 = new_coeff0_1;
5391
coeff0_2 = new_coeff0_2;
5392
coeff0_3 = new_coeff0_3;
5393
coeff0_4 = new_coeff0_4;
5394
coeff0_5 = new_coeff0_5;
5396
if(combinations[deriv_num][j] == 0)
5398
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
5399
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
5400
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
5401
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
5402
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
5403
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
5405
if(combinations[deriv_num][j] == 1)
5407
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
5408
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
5409
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
5410
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
5411
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
5412
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
5416
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5417
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
5420
// Transform derivatives back to physical element
5421
for (unsigned int row = 0; row < num_derivatives; row++)
5423
for (unsigned int col = 0; col < num_derivatives; col++)
5425
values[row] += transform[row][col]*derivatives[col];
5428
// Delete pointer to array of derivatives on FIAT element
5429
delete [] derivatives;
5431
// Delete pointer to array of combinations of derivatives and transform
5432
for (unsigned int row = 0; row < num_derivatives; row++)
5434
delete [] combinations[row];
5435
delete [] transform[row];
5438
delete [] combinations;
5439
delete [] transform;
5442
if (6 <= i && i <= 11)
5444
// Map degree of freedom to element degree of freedom
5445
const unsigned int dof = i - 6;
5447
// Generate scalings
5448
const double scalings_y_0 = 1;
5449
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5450
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
5452
// Compute psitilde_a
5453
const double psitilde_a_0 = 1;
5454
const double psitilde_a_1 = x;
5455
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
5457
// Compute psitilde_bs
5458
const double psitilde_bs_0_0 = 1;
5459
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5460
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
5461
const double psitilde_bs_1_0 = 1;
5462
const double psitilde_bs_1_1 = 2.5*y + 1.5;
5463
const double psitilde_bs_2_0 = 1;
5465
// Compute basisvalues
5466
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5467
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
5468
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
5469
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
5470
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
5471
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
5473
// Table(s) of coefficients
5474
static const double coefficients0[6][6] = \
5475
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
5476
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
5477
{0, 0, 0.2, 0, 0, 0.163299316},
5478
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
5479
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
5480
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
5482
// Interesting (new) part
5483
// Tables of derivatives of the polynomial base (transpose)
5484
static const double dmats0[6][6] = \
5485
{{0, 0, 0, 0, 0, 0},
5486
{4.89897949, 0, 0, 0, 0, 0},
5488
{0, 9.48683298, 0, 0, 0, 0},
5489
{4, 0, 7.07106781, 0, 0, 0},
5490
{0, 0, 0, 0, 0, 0}};
5492
static const double dmats1[6][6] = \
5493
{{0, 0, 0, 0, 0, 0},
5494
{2.44948974, 0, 0, 0, 0, 0},
5495
{4.24264069, 0, 0, 0, 0, 0},
5496
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
5497
{2, 6.12372436, 3.53553391, 0, 0, 0},
5498
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
5500
// Compute reference derivatives
5501
// Declare pointer to array of derivatives on FIAT element
5502
double *derivatives = new double [num_derivatives];
5504
// Declare coefficients
5505
double coeff0_0 = 0;
5506
double coeff0_1 = 0;
5507
double coeff0_2 = 0;
5508
double coeff0_3 = 0;
5509
double coeff0_4 = 0;
5510
double coeff0_5 = 0;
5512
// Declare new coefficients
5513
double new_coeff0_0 = 0;
5514
double new_coeff0_1 = 0;
5515
double new_coeff0_2 = 0;
5516
double new_coeff0_3 = 0;
5517
double new_coeff0_4 = 0;
5518
double new_coeff0_5 = 0;
5520
// Loop possible derivatives
5521
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5523
// Get values from coefficients array
5524
new_coeff0_0 = coefficients0[dof][0];
5525
new_coeff0_1 = coefficients0[dof][1];
5526
new_coeff0_2 = coefficients0[dof][2];
5527
new_coeff0_3 = coefficients0[dof][3];
5528
new_coeff0_4 = coefficients0[dof][4];
5529
new_coeff0_5 = coefficients0[dof][5];
5531
// Loop derivative order
5532
for (unsigned int j = 0; j < n; j++)
5534
// Update old coefficients
5535
coeff0_0 = new_coeff0_0;
5536
coeff0_1 = new_coeff0_1;
5537
coeff0_2 = new_coeff0_2;
5538
coeff0_3 = new_coeff0_3;
5539
coeff0_4 = new_coeff0_4;
5540
coeff0_5 = new_coeff0_5;
5542
if(combinations[deriv_num][j] == 0)
5544
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
5545
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
5546
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
5547
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
5548
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
5549
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
5551
if(combinations[deriv_num][j] == 1)
5553
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
5554
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
5555
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
5556
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
5557
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
5558
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
5562
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5563
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
5566
// Transform derivatives back to physical element
5567
for (unsigned int row = 0; row < num_derivatives; row++)
5569
for (unsigned int col = 0; col < num_derivatives; col++)
5571
values[num_derivatives + row] += transform[row][col]*derivatives[col];
5574
// Delete pointer to array of derivatives on FIAT element
5575
delete [] derivatives;
5577
// Delete pointer to array of combinations of derivatives and transform
5578
for (unsigned int row = 0; row < num_derivatives; row++)
5580
delete [] combinations[row];
5581
delete [] transform[row];
5584
delete [] combinations;
5585
delete [] transform;
5588
if (12 <= i && i <= 14)
5590
// Map degree of freedom to element degree of freedom
5591
const unsigned int dof = i - 12;
5593
// Generate scalings
5594
const double scalings_y_0 = 1;
5595
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5597
// Compute psitilde_a
5598
const double psitilde_a_0 = 1;
5599
const double psitilde_a_1 = x;
5601
// Compute psitilde_bs
5602
const double psitilde_bs_0_0 = 1;
5603
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5604
const double psitilde_bs_1_0 = 1;
5606
// Compute basisvalues
5607
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5608
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
5609
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
5611
// Table(s) of coefficients
5612
static const double coefficients0[3][3] = \
5613
{{0.471404521, -0.288675135, -0.166666667},
5614
{0.471404521, 0.288675135, -0.166666667},
5615
{0.471404521, 0, 0.333333333}};
5617
// Interesting (new) part
5618
// Tables of derivatives of the polynomial base (transpose)
5619
static const double dmats0[3][3] = \
5624
static const double dmats1[3][3] = \
5627
{4.24264069, 0, 0}};
5629
// Compute reference derivatives
5630
// Declare pointer to array of derivatives on FIAT element
5631
double *derivatives = new double [num_derivatives];
5633
// Declare coefficients
5634
double coeff0_0 = 0;
5635
double coeff0_1 = 0;
5636
double coeff0_2 = 0;
5638
// Declare new coefficients
5639
double new_coeff0_0 = 0;
5640
double new_coeff0_1 = 0;
5641
double new_coeff0_2 = 0;
5643
// Loop possible derivatives
5644
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5646
// Get values from coefficients array
5647
new_coeff0_0 = coefficients0[dof][0];
5648
new_coeff0_1 = coefficients0[dof][1];
5649
new_coeff0_2 = coefficients0[dof][2];
5651
// Loop derivative order
5652
for (unsigned int j = 0; j < n; j++)
5654
// Update old coefficients
5655
coeff0_0 = new_coeff0_0;
5656
coeff0_1 = new_coeff0_1;
5657
coeff0_2 = new_coeff0_2;
5659
if(combinations[deriv_num][j] == 0)
5661
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
5662
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
5663
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
5665
if(combinations[deriv_num][j] == 1)
5667
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
5668
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
5669
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
5673
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5674
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
5677
// Transform derivatives back to physical element
5678
for (unsigned int row = 0; row < num_derivatives; row++)
5680
for (unsigned int col = 0; col < num_derivatives; col++)
5682
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
5685
// Delete pointer to array of derivatives on FIAT element
5686
delete [] derivatives;
5688
// Delete pointer to array of combinations of derivatives and transform
5689
for (unsigned int row = 0; row < num_derivatives; row++)
5691
delete [] combinations[row];
5692
delete [] transform[row];
5695
delete [] combinations;
5696
delete [] transform;
5701
/// Evaluate order n derivatives of all basis functions at given point in cell
5702
virtual void evaluate_basis_derivatives_all(unsigned int n,
5704
const double* coordinates,
5705
const ufc::cell& c) const
5707
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5710
/// Evaluate linear functional for dof i on the function f
5711
virtual double evaluate_dof(unsigned int i,
5712
const ufc::function& f,
5713
const ufc::cell& c) const
5715
// The reference points, direction and weights:
5716
static const double X[15][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
5717
static const double W[15][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
5718
static const double D[15][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
5720
const double * const * x = c.coordinates;
5721
double result = 0.0;
5722
// Iterate over the points:
5723
// Evaluate basis functions for affine mapping
5724
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
5725
const double w1 = X[i][0][0];
5726
const double w2 = X[i][0][1];
5728
// Compute affine mapping y = F(X)
5730
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
5731
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
5733
// Evaluate function at physical points
5735
f.evaluate(values, y, c);
5737
// Map function values using appropriate mapping
5738
// Affine map: Do nothing
5740
// Note that we do not map the weights (yet).
5742
// Take directional components
5743
for(int k = 0; k < 3; k++)
5744
result += values[k]*D[i][0][k];
5745
// Multiply by weights
5751
/// Evaluate linear functionals for all dofs on the function f
5752
virtual void evaluate_dofs(double* values,
5753
const ufc::function& f,
5754
const ufc::cell& c) const
5756
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5759
/// Interpolate vertex values from dof values
5760
virtual void interpolate_vertex_values(double* vertex_values,
5761
const double* dof_values,
5762
const ufc::cell& c) const
5764
// Evaluate at vertices and use affine mapping
5765
vertex_values[0] = dof_values[0];
5766
vertex_values[3] = dof_values[1];
5767
vertex_values[6] = dof_values[2];
5768
// Evaluate at vertices and use affine mapping
5769
vertex_values[1] = dof_values[6];
5770
vertex_values[4] = dof_values[7];
5771
vertex_values[7] = dof_values[8];
5772
// Evaluate at vertices and use affine mapping
5773
vertex_values[2] = dof_values[12];
5774
vertex_values[5] = dof_values[13];
5775
vertex_values[8] = dof_values[14];
5778
/// Return the number of sub elements (for a mixed element)
5779
virtual unsigned int num_sub_elements() const
5784
/// Create a new finite element for sub element i (for a mixed element)
5785
virtual ufc::finite_element* create_sub_element(unsigned int i) const
5790
return new stokes_0_finite_element_1_0();
5793
return new stokes_0_finite_element_1_1();
5801
/// This class defines the interface for a local-to-global mapping of
5802
/// degrees of freedom (dofs).
5804
class stokes_0_dof_map_0_0_0: public ufc::dof_map
5808
unsigned int __global_dimension;
5813
stokes_0_dof_map_0_0_0() : ufc::dof_map()
5815
__global_dimension = 0;
5819
virtual ~stokes_0_dof_map_0_0_0()
5824
/// Return a string identifying the dof map
5825
virtual const char* signature() const
5827
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
5830
/// Return true iff mesh entities of topological dimension d are needed
5831
virtual bool needs_mesh_entities(unsigned int d) const
5848
/// Initialize dof map for mesh (return true iff init_cell() is needed)
5849
virtual bool init_mesh(const ufc::mesh& m)
5851
__global_dimension = m.num_entities[0] + m.num_entities[1];
5855
/// Initialize dof map for given cell
5856
virtual void init_cell(const ufc::mesh& m,
5862
/// Finish initialization of dof map for cells
5863
virtual void init_cell_finalize()
5868
/// Return the dimension of the global finite element function space
5869
virtual unsigned int global_dimension() const
5871
return __global_dimension;
5874
/// Return the dimension of the local finite element function space for a cell
5875
virtual unsigned int local_dimension(const ufc::cell& c) const
5880
/// Return the maximum dimension of the local finite element function space
5881
virtual unsigned int max_local_dimension() const
5886
// Return the geometric dimension of the coordinates this dof map provides
5887
virtual unsigned int geometric_dimension() const
5892
/// Return the number of dofs on each cell facet
5893
virtual unsigned int num_facet_dofs() const
5898
/// Return the number of dofs associated with each cell entity of dimension d
5899
virtual unsigned int num_entity_dofs(unsigned int d) const
5901
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5904
/// Tabulate the local-to-global mapping of dofs on a cell
5905
virtual void tabulate_dofs(unsigned int* dofs,
5907
const ufc::cell& c) const
5909
dofs[0] = c.entity_indices[0][0];
5910
dofs[1] = c.entity_indices[0][1];
5911
dofs[2] = c.entity_indices[0][2];
5912
unsigned int offset = m.num_entities[0];
5913
dofs[3] = offset + c.entity_indices[1][0];
5914
dofs[4] = offset + c.entity_indices[1][1];
5915
dofs[5] = offset + c.entity_indices[1][2];
5918
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
5919
virtual void tabulate_facet_dofs(unsigned int* dofs,
5920
unsigned int facet) const
5942
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
5943
virtual void tabulate_entity_dofs(unsigned int* dofs,
5944
unsigned int d, unsigned int i) const
5946
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5949
/// Tabulate the coordinates of all dofs on a cell
5950
virtual void tabulate_coordinates(double** coordinates,
5951
const ufc::cell& c) const
5953
const double * const * x = c.coordinates;
5954
coordinates[0][0] = x[0][0];
5955
coordinates[0][1] = x[0][1];
5956
coordinates[1][0] = x[1][0];
5957
coordinates[1][1] = x[1][1];
5958
coordinates[2][0] = x[2][0];
5959
coordinates[2][1] = x[2][1];
5960
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
5961
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
5962
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
5963
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
5964
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
5965
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
5968
/// Return the number of sub dof maps (for a mixed element)
5969
virtual unsigned int num_sub_dof_maps() const
5974
/// Create a new dof_map for sub dof map i (for a mixed element)
5975
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
5977
return new stokes_0_dof_map_0_0_0();
5982
/// This class defines the interface for a local-to-global mapping of
5983
/// degrees of freedom (dofs).
5985
class stokes_0_dof_map_0_0_1: public ufc::dof_map
5989
unsigned int __global_dimension;
5994
stokes_0_dof_map_0_0_1() : ufc::dof_map()
5996
__global_dimension = 0;
6000
virtual ~stokes_0_dof_map_0_0_1()
6005
/// Return a string identifying the dof map
6006
virtual const char* signature() const
6008
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
6011
/// Return true iff mesh entities of topological dimension d are needed
6012
virtual bool needs_mesh_entities(unsigned int d) const
6029
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6030
virtual bool init_mesh(const ufc::mesh& m)
6032
__global_dimension = m.num_entities[0] + m.num_entities[1];
6036
/// Initialize dof map for given cell
6037
virtual void init_cell(const ufc::mesh& m,
6043
/// Finish initialization of dof map for cells
6044
virtual void init_cell_finalize()
6049
/// Return the dimension of the global finite element function space
6050
virtual unsigned int global_dimension() const
6052
return __global_dimension;
6055
/// Return the dimension of the local finite element function space for a cell
6056
virtual unsigned int local_dimension(const ufc::cell& c) const
6061
/// Return the maximum dimension of the local finite element function space
6062
virtual unsigned int max_local_dimension() const
6067
// Return the geometric dimension of the coordinates this dof map provides
6068
virtual unsigned int geometric_dimension() const
6073
/// Return the number of dofs on each cell facet
6074
virtual unsigned int num_facet_dofs() const
6079
/// Return the number of dofs associated with each cell entity of dimension d
6080
virtual unsigned int num_entity_dofs(unsigned int d) const
6082
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6085
/// Tabulate the local-to-global mapping of dofs on a cell
6086
virtual void tabulate_dofs(unsigned int* dofs,
6088
const ufc::cell& c) const
6090
dofs[0] = c.entity_indices[0][0];
6091
dofs[1] = c.entity_indices[0][1];
6092
dofs[2] = c.entity_indices[0][2];
6093
unsigned int offset = m.num_entities[0];
6094
dofs[3] = offset + c.entity_indices[1][0];
6095
dofs[4] = offset + c.entity_indices[1][1];
6096
dofs[5] = offset + c.entity_indices[1][2];
6099
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6100
virtual void tabulate_facet_dofs(unsigned int* dofs,
6101
unsigned int facet) const
6123
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6124
virtual void tabulate_entity_dofs(unsigned int* dofs,
6125
unsigned int d, unsigned int i) const
6127
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6130
/// Tabulate the coordinates of all dofs on a cell
6131
virtual void tabulate_coordinates(double** coordinates,
6132
const ufc::cell& c) const
6134
const double * const * x = c.coordinates;
6135
coordinates[0][0] = x[0][0];
6136
coordinates[0][1] = x[0][1];
6137
coordinates[1][0] = x[1][0];
6138
coordinates[1][1] = x[1][1];
6139
coordinates[2][0] = x[2][0];
6140
coordinates[2][1] = x[2][1];
6141
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
6142
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
6143
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
6144
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
6145
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
6146
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
6149
/// Return the number of sub dof maps (for a mixed element)
6150
virtual unsigned int num_sub_dof_maps() const
6155
/// Create a new dof_map for sub dof map i (for a mixed element)
6156
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
6158
return new stokes_0_dof_map_0_0_1();
6163
/// This class defines the interface for a local-to-global mapping of
6164
/// degrees of freedom (dofs).
6166
class stokes_0_dof_map_0_0: public ufc::dof_map
6170
unsigned int __global_dimension;
6175
stokes_0_dof_map_0_0() : ufc::dof_map()
6177
__global_dimension = 0;
6181
virtual ~stokes_0_dof_map_0_0()
6186
/// Return a string identifying the dof map
6187
virtual const char* signature() const
6189
return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
6192
/// Return true iff mesh entities of topological dimension d are needed
6193
virtual bool needs_mesh_entities(unsigned int d) const
6210
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6211
virtual bool init_mesh(const ufc::mesh& m)
6213
__global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
6217
/// Initialize dof map for given cell
6218
virtual void init_cell(const ufc::mesh& m,
6224
/// Finish initialization of dof map for cells
6225
virtual void init_cell_finalize()
6230
/// Return the dimension of the global finite element function space
6231
virtual unsigned int global_dimension() const
6233
return __global_dimension;
6236
/// Return the dimension of the local finite element function space for a cell
6237
virtual unsigned int local_dimension(const ufc::cell& c) const
6242
/// Return the maximum dimension of the local finite element function space
6243
virtual unsigned int max_local_dimension() const
6248
// Return the geometric dimension of the coordinates this dof map provides
6249
virtual unsigned int geometric_dimension() const
6254
/// Return the number of dofs on each cell facet
6255
virtual unsigned int num_facet_dofs() const
6260
/// Return the number of dofs associated with each cell entity of dimension d
6261
virtual unsigned int num_entity_dofs(unsigned int d) const
6263
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6266
/// Tabulate the local-to-global mapping of dofs on a cell
6267
virtual void tabulate_dofs(unsigned int* dofs,
6269
const ufc::cell& c) const
6271
dofs[0] = c.entity_indices[0][0];
6272
dofs[1] = c.entity_indices[0][1];
6273
dofs[2] = c.entity_indices[0][2];
6274
unsigned int offset = m.num_entities[0];
6275
dofs[3] = offset + c.entity_indices[1][0];
6276
dofs[4] = offset + c.entity_indices[1][1];
6277
dofs[5] = offset + c.entity_indices[1][2];
6278
offset = offset + m.num_entities[1];
6279
dofs[6] = offset + c.entity_indices[0][0];
6280
dofs[7] = offset + c.entity_indices[0][1];
6281
dofs[8] = offset + c.entity_indices[0][2];
6282
offset = offset + m.num_entities[0];
6283
dofs[9] = offset + c.entity_indices[1][0];
6284
dofs[10] = offset + c.entity_indices[1][1];
6285
dofs[11] = offset + c.entity_indices[1][2];
6288
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6289
virtual void tabulate_facet_dofs(unsigned int* dofs,
6290
unsigned int facet) const
6321
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6322
virtual void tabulate_entity_dofs(unsigned int* dofs,
6323
unsigned int d, unsigned int i) const
6325
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6328
/// Tabulate the coordinates of all dofs on a cell
6329
virtual void tabulate_coordinates(double** coordinates,
6330
const ufc::cell& c) const
6332
const double * const * x = c.coordinates;
6333
coordinates[0][0] = x[0][0];
6334
coordinates[0][1] = x[0][1];
6335
coordinates[1][0] = x[1][0];
6336
coordinates[1][1] = x[1][1];
6337
coordinates[2][0] = x[2][0];
6338
coordinates[2][1] = x[2][1];
6339
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
6340
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
6341
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
6342
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
6343
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
6344
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
6345
coordinates[6][0] = x[0][0];
6346
coordinates[6][1] = x[0][1];
6347
coordinates[7][0] = x[1][0];
6348
coordinates[7][1] = x[1][1];
6349
coordinates[8][0] = x[2][0];
6350
coordinates[8][1] = x[2][1];
6351
coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
6352
coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
6353
coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
6354
coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
6355
coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
6356
coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
6359
/// Return the number of sub dof maps (for a mixed element)
6360
virtual unsigned int num_sub_dof_maps() const
6365
/// Create a new dof_map for sub dof map i (for a mixed element)
6366
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
6371
return new stokes_0_dof_map_0_0_0();
6374
return new stokes_0_dof_map_0_0_1();
6382
/// This class defines the interface for a local-to-global mapping of
6383
/// degrees of freedom (dofs).
6385
class stokes_0_dof_map_0_1: public ufc::dof_map
6389
unsigned int __global_dimension;
6394
stokes_0_dof_map_0_1() : ufc::dof_map()
6396
__global_dimension = 0;
6400
virtual ~stokes_0_dof_map_0_1()
6405
/// Return a string identifying the dof map
6406
virtual const char* signature() const
6408
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
6411
/// Return true iff mesh entities of topological dimension d are needed
6412
virtual bool needs_mesh_entities(unsigned int d) const
6429
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6430
virtual bool init_mesh(const ufc::mesh& m)
6432
__global_dimension = m.num_entities[0];
6436
/// Initialize dof map for given cell
6437
virtual void init_cell(const ufc::mesh& m,
6443
/// Finish initialization of dof map for cells
6444
virtual void init_cell_finalize()
6449
/// Return the dimension of the global finite element function space
6450
virtual unsigned int global_dimension() const
6452
return __global_dimension;
6455
/// Return the dimension of the local finite element function space for a cell
6456
virtual unsigned int local_dimension(const ufc::cell& c) const
6461
/// Return the maximum dimension of the local finite element function space
6462
virtual unsigned int max_local_dimension() const
6467
// Return the geometric dimension of the coordinates this dof map provides
6468
virtual unsigned int geometric_dimension() const
6473
/// Return the number of dofs on each cell facet
6474
virtual unsigned int num_facet_dofs() const
6479
/// Return the number of dofs associated with each cell entity of dimension d
6480
virtual unsigned int num_entity_dofs(unsigned int d) const
6482
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6485
/// Tabulate the local-to-global mapping of dofs on a cell
6486
virtual void tabulate_dofs(unsigned int* dofs,
6488
const ufc::cell& c) const
6490
dofs[0] = c.entity_indices[0][0];
6491
dofs[1] = c.entity_indices[0][1];
6492
dofs[2] = c.entity_indices[0][2];
6495
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6496
virtual void tabulate_facet_dofs(unsigned int* dofs,
6497
unsigned int facet) const
6516
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6517
virtual void tabulate_entity_dofs(unsigned int* dofs,
6518
unsigned int d, unsigned int i) const
6520
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6523
/// Tabulate the coordinates of all dofs on a cell
6524
virtual void tabulate_coordinates(double** coordinates,
6525
const ufc::cell& c) const
6527
const double * const * x = c.coordinates;
6528
coordinates[0][0] = x[0][0];
6529
coordinates[0][1] = x[0][1];
6530
coordinates[1][0] = x[1][0];
6531
coordinates[1][1] = x[1][1];
6532
coordinates[2][0] = x[2][0];
6533
coordinates[2][1] = x[2][1];
6536
/// Return the number of sub dof maps (for a mixed element)
6537
virtual unsigned int num_sub_dof_maps() const
6542
/// Create a new dof_map for sub dof map i (for a mixed element)
6543
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
6545
return new stokes_0_dof_map_0_1();
6550
/// This class defines the interface for a local-to-global mapping of
6551
/// degrees of freedom (dofs).
6553
class stokes_0_dof_map_0: public ufc::dof_map
6557
unsigned int __global_dimension;
6562
stokes_0_dof_map_0() : ufc::dof_map()
6564
__global_dimension = 0;
6568
virtual ~stokes_0_dof_map_0()
6573
/// Return a string identifying the dof map
6574
virtual const char* signature() const
6576
return "FFC dof map for MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) })";
6579
/// Return true iff mesh entities of topological dimension d are needed
6580
virtual bool needs_mesh_entities(unsigned int d) const
6597
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6598
virtual bool init_mesh(const ufc::mesh& m)
6600
__global_dimension = 3*m.num_entities[0] + 2*m.num_entities[1];
6604
/// Initialize dof map for given cell
6605
virtual void init_cell(const ufc::mesh& m,
6611
/// Finish initialization of dof map for cells
6612
virtual void init_cell_finalize()
6617
/// Return the dimension of the global finite element function space
6618
virtual unsigned int global_dimension() const
6620
return __global_dimension;
6623
/// Return the dimension of the local finite element function space for a cell
6624
virtual unsigned int local_dimension(const ufc::cell& c) const
6629
/// Return the maximum dimension of the local finite element function space
6630
virtual unsigned int max_local_dimension() const
6635
// Return the geometric dimension of the coordinates this dof map provides
6636
virtual unsigned int geometric_dimension() const
6641
/// Return the number of dofs on each cell facet
6642
virtual unsigned int num_facet_dofs() const
6647
/// Return the number of dofs associated with each cell entity of dimension d
6648
virtual unsigned int num_entity_dofs(unsigned int d) const
6650
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6653
/// Tabulate the local-to-global mapping of dofs on a cell
6654
virtual void tabulate_dofs(unsigned int* dofs,
6656
const ufc::cell& c) const
6658
dofs[0] = c.entity_indices[0][0];
6659
dofs[1] = c.entity_indices[0][1];
6660
dofs[2] = c.entity_indices[0][2];
6661
unsigned int offset = m.num_entities[0];
6662
dofs[3] = offset + c.entity_indices[1][0];
6663
dofs[4] = offset + c.entity_indices[1][1];
6664
dofs[5] = offset + c.entity_indices[1][2];
6665
offset = offset + m.num_entities[1];
6666
dofs[6] = offset + c.entity_indices[0][0];
6667
dofs[7] = offset + c.entity_indices[0][1];
6668
dofs[8] = offset + c.entity_indices[0][2];
6669
offset = offset + m.num_entities[0];
6670
dofs[9] = offset + c.entity_indices[1][0];
6671
dofs[10] = offset + c.entity_indices[1][1];
6672
dofs[11] = offset + c.entity_indices[1][2];
6673
offset = offset + m.num_entities[1];
6674
dofs[12] = offset + c.entity_indices[0][0];
6675
dofs[13] = offset + c.entity_indices[0][1];
6676
dofs[14] = offset + c.entity_indices[0][2];
6679
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6680
virtual void tabulate_facet_dofs(unsigned int* dofs,
6681
unsigned int facet) const
6718
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6719
virtual void tabulate_entity_dofs(unsigned int* dofs,
6720
unsigned int d, unsigned int i) const
6722
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6725
/// Tabulate the coordinates of all dofs on a cell
6726
virtual void tabulate_coordinates(double** coordinates,
6727
const ufc::cell& c) const
6729
const double * const * x = c.coordinates;
6730
coordinates[0][0] = x[0][0];
6731
coordinates[0][1] = x[0][1];
6732
coordinates[1][0] = x[1][0];
6733
coordinates[1][1] = x[1][1];
6734
coordinates[2][0] = x[2][0];
6735
coordinates[2][1] = x[2][1];
6736
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
6737
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
6738
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
6739
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
6740
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
6741
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
6742
coordinates[6][0] = x[0][0];
6743
coordinates[6][1] = x[0][1];
6744
coordinates[7][0] = x[1][0];
6745
coordinates[7][1] = x[1][1];
6746
coordinates[8][0] = x[2][0];
6747
coordinates[8][1] = x[2][1];
6748
coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
6749
coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
6750
coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
6751
coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
6752
coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
6753
coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
6754
coordinates[12][0] = x[0][0];
6755
coordinates[12][1] = x[0][1];
6756
coordinates[13][0] = x[1][0];
6757
coordinates[13][1] = x[1][1];
6758
coordinates[14][0] = x[2][0];
6759
coordinates[14][1] = x[2][1];
6762
/// Return the number of sub dof maps (for a mixed element)
6763
virtual unsigned int num_sub_dof_maps() const
6768
/// Create a new dof_map for sub dof map i (for a mixed element)
6769
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
6774
return new stokes_0_dof_map_0_0();
6777
return new stokes_0_dof_map_0_1();
6785
/// This class defines the interface for a local-to-global mapping of
6786
/// degrees of freedom (dofs).
6788
class stokes_0_dof_map_1_0_0: public ufc::dof_map
6792
unsigned int __global_dimension;
6797
stokes_0_dof_map_1_0_0() : ufc::dof_map()
6799
__global_dimension = 0;
6803
virtual ~stokes_0_dof_map_1_0_0()
6808
/// Return a string identifying the dof map
6809
virtual const char* signature() const
6811
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
6814
/// Return true iff mesh entities of topological dimension d are needed
6815
virtual bool needs_mesh_entities(unsigned int d) const
6832
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6833
virtual bool init_mesh(const ufc::mesh& m)
6835
__global_dimension = m.num_entities[0] + m.num_entities[1];
6839
/// Initialize dof map for given cell
6840
virtual void init_cell(const ufc::mesh& m,
6846
/// Finish initialization of dof map for cells
6847
virtual void init_cell_finalize()
6852
/// Return the dimension of the global finite element function space
6853
virtual unsigned int global_dimension() const
6855
return __global_dimension;
6858
/// Return the dimension of the local finite element function space for a cell
6859
virtual unsigned int local_dimension(const ufc::cell& c) const
6864
/// Return the maximum dimension of the local finite element function space
6865
virtual unsigned int max_local_dimension() const
6870
// Return the geometric dimension of the coordinates this dof map provides
6871
virtual unsigned int geometric_dimension() const
6876
/// Return the number of dofs on each cell facet
6877
virtual unsigned int num_facet_dofs() const
6882
/// Return the number of dofs associated with each cell entity of dimension d
6883
virtual unsigned int num_entity_dofs(unsigned int d) const
6885
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6888
/// Tabulate the local-to-global mapping of dofs on a cell
6889
virtual void tabulate_dofs(unsigned int* dofs,
6891
const ufc::cell& c) const
6893
dofs[0] = c.entity_indices[0][0];
6894
dofs[1] = c.entity_indices[0][1];
6895
dofs[2] = c.entity_indices[0][2];
6896
unsigned int offset = m.num_entities[0];
6897
dofs[3] = offset + c.entity_indices[1][0];
6898
dofs[4] = offset + c.entity_indices[1][1];
6899
dofs[5] = offset + c.entity_indices[1][2];
6902
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6903
virtual void tabulate_facet_dofs(unsigned int* dofs,
6904
unsigned int facet) const
6926
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6927
virtual void tabulate_entity_dofs(unsigned int* dofs,
6928
unsigned int d, unsigned int i) const
6930
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6933
/// Tabulate the coordinates of all dofs on a cell
6934
virtual void tabulate_coordinates(double** coordinates,
6935
const ufc::cell& c) const
6937
const double * const * x = c.coordinates;
6938
coordinates[0][0] = x[0][0];
6939
coordinates[0][1] = x[0][1];
6940
coordinates[1][0] = x[1][0];
6941
coordinates[1][1] = x[1][1];
6942
coordinates[2][0] = x[2][0];
6943
coordinates[2][1] = x[2][1];
6944
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
6945
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
6946
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
6947
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
6948
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
6949
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
6952
/// Return the number of sub dof maps (for a mixed element)
6953
virtual unsigned int num_sub_dof_maps() const
6958
/// Create a new dof_map for sub dof map i (for a mixed element)
6959
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
6961
return new stokes_0_dof_map_1_0_0();
6966
/// This class defines the interface for a local-to-global mapping of
6967
/// degrees of freedom (dofs).
6969
class stokes_0_dof_map_1_0_1: public ufc::dof_map
6973
unsigned int __global_dimension;
6978
stokes_0_dof_map_1_0_1() : ufc::dof_map()
6980
__global_dimension = 0;
6984
virtual ~stokes_0_dof_map_1_0_1()
6989
/// Return a string identifying the dof map
6990
virtual const char* signature() const
6992
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
6995
/// Return true iff mesh entities of topological dimension d are needed
6996
virtual bool needs_mesh_entities(unsigned int d) const
7013
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7014
virtual bool init_mesh(const ufc::mesh& m)
7016
__global_dimension = m.num_entities[0] + m.num_entities[1];
7020
/// Initialize dof map for given cell
7021
virtual void init_cell(const ufc::mesh& m,
7027
/// Finish initialization of dof map for cells
7028
virtual void init_cell_finalize()
7033
/// Return the dimension of the global finite element function space
7034
virtual unsigned int global_dimension() const
7036
return __global_dimension;
7039
/// Return the dimension of the local finite element function space for a cell
7040
virtual unsigned int local_dimension(const ufc::cell& c) const
7045
/// Return the maximum dimension of the local finite element function space
7046
virtual unsigned int max_local_dimension() const
7051
// Return the geometric dimension of the coordinates this dof map provides
7052
virtual unsigned int geometric_dimension() const
7057
/// Return the number of dofs on each cell facet
7058
virtual unsigned int num_facet_dofs() const
7063
/// Return the number of dofs associated with each cell entity of dimension d
7064
virtual unsigned int num_entity_dofs(unsigned int d) const
7066
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7069
/// Tabulate the local-to-global mapping of dofs on a cell
7070
virtual void tabulate_dofs(unsigned int* dofs,
7072
const ufc::cell& c) const
7074
dofs[0] = c.entity_indices[0][0];
7075
dofs[1] = c.entity_indices[0][1];
7076
dofs[2] = c.entity_indices[0][2];
7077
unsigned int offset = m.num_entities[0];
7078
dofs[3] = offset + c.entity_indices[1][0];
7079
dofs[4] = offset + c.entity_indices[1][1];
7080
dofs[5] = offset + c.entity_indices[1][2];
7083
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7084
virtual void tabulate_facet_dofs(unsigned int* dofs,
7085
unsigned int facet) const
7107
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7108
virtual void tabulate_entity_dofs(unsigned int* dofs,
7109
unsigned int d, unsigned int i) const
7111
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7114
/// Tabulate the coordinates of all dofs on a cell
7115
virtual void tabulate_coordinates(double** coordinates,
7116
const ufc::cell& c) const
7118
const double * const * x = c.coordinates;
7119
coordinates[0][0] = x[0][0];
7120
coordinates[0][1] = x[0][1];
7121
coordinates[1][0] = x[1][0];
7122
coordinates[1][1] = x[1][1];
7123
coordinates[2][0] = x[2][0];
7124
coordinates[2][1] = x[2][1];
7125
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
7126
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
7127
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
7128
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
7129
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
7130
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
7133
/// Return the number of sub dof maps (for a mixed element)
7134
virtual unsigned int num_sub_dof_maps() const
7139
/// Create a new dof_map for sub dof map i (for a mixed element)
7140
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
7142
return new stokes_0_dof_map_1_0_1();
7147
/// This class defines the interface for a local-to-global mapping of
7148
/// degrees of freedom (dofs).
7150
class stokes_0_dof_map_1_0: public ufc::dof_map
7154
unsigned int __global_dimension;
7159
stokes_0_dof_map_1_0() : ufc::dof_map()
7161
__global_dimension = 0;
7165
virtual ~stokes_0_dof_map_1_0()
7170
/// Return a string identifying the dof map
7171
virtual const char* signature() const
7173
return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
7176
/// Return true iff mesh entities of topological dimension d are needed
7177
virtual bool needs_mesh_entities(unsigned int d) const
7194
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7195
virtual bool init_mesh(const ufc::mesh& m)
7197
__global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
7201
/// Initialize dof map for given cell
7202
virtual void init_cell(const ufc::mesh& m,
7208
/// Finish initialization of dof map for cells
7209
virtual void init_cell_finalize()
7214
/// Return the dimension of the global finite element function space
7215
virtual unsigned int global_dimension() const
7217
return __global_dimension;
7220
/// Return the dimension of the local finite element function space for a cell
7221
virtual unsigned int local_dimension(const ufc::cell& c) const
7226
/// Return the maximum dimension of the local finite element function space
7227
virtual unsigned int max_local_dimension() const
7232
// Return the geometric dimension of the coordinates this dof map provides
7233
virtual unsigned int geometric_dimension() const
7238
/// Return the number of dofs on each cell facet
7239
virtual unsigned int num_facet_dofs() const
7244
/// Return the number of dofs associated with each cell entity of dimension d
7245
virtual unsigned int num_entity_dofs(unsigned int d) const
7247
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7250
/// Tabulate the local-to-global mapping of dofs on a cell
7251
virtual void tabulate_dofs(unsigned int* dofs,
7253
const ufc::cell& c) const
7255
dofs[0] = c.entity_indices[0][0];
7256
dofs[1] = c.entity_indices[0][1];
7257
dofs[2] = c.entity_indices[0][2];
7258
unsigned int offset = m.num_entities[0];
7259
dofs[3] = offset + c.entity_indices[1][0];
7260
dofs[4] = offset + c.entity_indices[1][1];
7261
dofs[5] = offset + c.entity_indices[1][2];
7262
offset = offset + m.num_entities[1];
7263
dofs[6] = offset + c.entity_indices[0][0];
7264
dofs[7] = offset + c.entity_indices[0][1];
7265
dofs[8] = offset + c.entity_indices[0][2];
7266
offset = offset + m.num_entities[0];
7267
dofs[9] = offset + c.entity_indices[1][0];
7268
dofs[10] = offset + c.entity_indices[1][1];
7269
dofs[11] = offset + c.entity_indices[1][2];
7272
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7273
virtual void tabulate_facet_dofs(unsigned int* dofs,
7274
unsigned int facet) const
7305
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7306
virtual void tabulate_entity_dofs(unsigned int* dofs,
7307
unsigned int d, unsigned int i) const
7309
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7312
/// Tabulate the coordinates of all dofs on a cell
7313
virtual void tabulate_coordinates(double** coordinates,
7314
const ufc::cell& c) const
7316
const double * const * x = c.coordinates;
7317
coordinates[0][0] = x[0][0];
7318
coordinates[0][1] = x[0][1];
7319
coordinates[1][0] = x[1][0];
7320
coordinates[1][1] = x[1][1];
7321
coordinates[2][0] = x[2][0];
7322
coordinates[2][1] = x[2][1];
7323
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
7324
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
7325
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
7326
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
7327
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
7328
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
7329
coordinates[6][0] = x[0][0];
7330
coordinates[6][1] = x[0][1];
7331
coordinates[7][0] = x[1][0];
7332
coordinates[7][1] = x[1][1];
7333
coordinates[8][0] = x[2][0];
7334
coordinates[8][1] = x[2][1];
7335
coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
7336
coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
7337
coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
7338
coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
7339
coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
7340
coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
7343
/// Return the number of sub dof maps (for a mixed element)
7344
virtual unsigned int num_sub_dof_maps() const
7349
/// Create a new dof_map for sub dof map i (for a mixed element)
7350
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
7355
return new stokes_0_dof_map_1_0_0();
7358
return new stokes_0_dof_map_1_0_1();
7366
/// This class defines the interface for a local-to-global mapping of
7367
/// degrees of freedom (dofs).
7369
class stokes_0_dof_map_1_1: public ufc::dof_map
7373
unsigned int __global_dimension;
7378
stokes_0_dof_map_1_1() : ufc::dof_map()
7380
__global_dimension = 0;
7384
virtual ~stokes_0_dof_map_1_1()
7389
/// Return a string identifying the dof map
7390
virtual const char* signature() const
7392
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
7395
/// Return true iff mesh entities of topological dimension d are needed
7396
virtual bool needs_mesh_entities(unsigned int d) const
7413
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7414
virtual bool init_mesh(const ufc::mesh& m)
7416
__global_dimension = m.num_entities[0];
7420
/// Initialize dof map for given cell
7421
virtual void init_cell(const ufc::mesh& m,
7427
/// Finish initialization of dof map for cells
7428
virtual void init_cell_finalize()
7433
/// Return the dimension of the global finite element function space
7434
virtual unsigned int global_dimension() const
7436
return __global_dimension;
7439
/// Return the dimension of the local finite element function space for a cell
7440
virtual unsigned int local_dimension(const ufc::cell& c) const
7445
/// Return the maximum dimension of the local finite element function space
7446
virtual unsigned int max_local_dimension() const
7451
// Return the geometric dimension of the coordinates this dof map provides
7452
virtual unsigned int geometric_dimension() const
7457
/// Return the number of dofs on each cell facet
7458
virtual unsigned int num_facet_dofs() const
7463
/// Return the number of dofs associated with each cell entity of dimension d
7464
virtual unsigned int num_entity_dofs(unsigned int d) const
7466
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7469
/// Tabulate the local-to-global mapping of dofs on a cell
7470
virtual void tabulate_dofs(unsigned int* dofs,
7472
const ufc::cell& c) const
7474
dofs[0] = c.entity_indices[0][0];
7475
dofs[1] = c.entity_indices[0][1];
7476
dofs[2] = c.entity_indices[0][2];
7479
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7480
virtual void tabulate_facet_dofs(unsigned int* dofs,
7481
unsigned int facet) const
7500
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7501
virtual void tabulate_entity_dofs(unsigned int* dofs,
7502
unsigned int d, unsigned int i) const
7504
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7507
/// Tabulate the coordinates of all dofs on a cell
7508
virtual void tabulate_coordinates(double** coordinates,
7509
const ufc::cell& c) const
7511
const double * const * x = c.coordinates;
7512
coordinates[0][0] = x[0][0];
7513
coordinates[0][1] = x[0][1];
7514
coordinates[1][0] = x[1][0];
7515
coordinates[1][1] = x[1][1];
7516
coordinates[2][0] = x[2][0];
7517
coordinates[2][1] = x[2][1];
7520
/// Return the number of sub dof maps (for a mixed element)
7521
virtual unsigned int num_sub_dof_maps() const
7526
/// Create a new dof_map for sub dof map i (for a mixed element)
7527
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
7529
return new stokes_0_dof_map_1_1();
7534
/// This class defines the interface for a local-to-global mapping of
7535
/// degrees of freedom (dofs).
7537
class stokes_0_dof_map_1: public ufc::dof_map
7541
unsigned int __global_dimension;
7546
stokes_0_dof_map_1() : ufc::dof_map()
7548
__global_dimension = 0;
7552
virtual ~stokes_0_dof_map_1()
7557
/// Return a string identifying the dof map
7558
virtual const char* signature() const
7560
return "FFC dof map for MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) })";
7563
/// Return true iff mesh entities of topological dimension d are needed
7564
virtual bool needs_mesh_entities(unsigned int d) const
7581
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7582
virtual bool init_mesh(const ufc::mesh& m)
7584
__global_dimension = 3*m.num_entities[0] + 2*m.num_entities[1];
7588
/// Initialize dof map for given cell
7589
virtual void init_cell(const ufc::mesh& m,
7595
/// Finish initialization of dof map for cells
7596
virtual void init_cell_finalize()
7601
/// Return the dimension of the global finite element function space
7602
virtual unsigned int global_dimension() const
7604
return __global_dimension;
7607
/// Return the dimension of the local finite element function space for a cell
7608
virtual unsigned int local_dimension(const ufc::cell& c) const
7613
/// Return the maximum dimension of the local finite element function space
7614
virtual unsigned int max_local_dimension() const
7619
// Return the geometric dimension of the coordinates this dof map provides
7620
virtual unsigned int geometric_dimension() const
7625
/// Return the number of dofs on each cell facet
7626
virtual unsigned int num_facet_dofs() const
7631
/// Return the number of dofs associated with each cell entity of dimension d
7632
virtual unsigned int num_entity_dofs(unsigned int d) const
7634
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7637
/// Tabulate the local-to-global mapping of dofs on a cell
7638
virtual void tabulate_dofs(unsigned int* dofs,
7640
const ufc::cell& c) const
7642
dofs[0] = c.entity_indices[0][0];
7643
dofs[1] = c.entity_indices[0][1];
7644
dofs[2] = c.entity_indices[0][2];
7645
unsigned int offset = m.num_entities[0];
7646
dofs[3] = offset + c.entity_indices[1][0];
7647
dofs[4] = offset + c.entity_indices[1][1];
7648
dofs[5] = offset + c.entity_indices[1][2];
7649
offset = offset + m.num_entities[1];
7650
dofs[6] = offset + c.entity_indices[0][0];
7651
dofs[7] = offset + c.entity_indices[0][1];
7652
dofs[8] = offset + c.entity_indices[0][2];
7653
offset = offset + m.num_entities[0];
7654
dofs[9] = offset + c.entity_indices[1][0];
7655
dofs[10] = offset + c.entity_indices[1][1];
7656
dofs[11] = offset + c.entity_indices[1][2];
7657
offset = offset + m.num_entities[1];
7658
dofs[12] = offset + c.entity_indices[0][0];
7659
dofs[13] = offset + c.entity_indices[0][1];
7660
dofs[14] = offset + c.entity_indices[0][2];
7663
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7664
virtual void tabulate_facet_dofs(unsigned int* dofs,
7665
unsigned int facet) const
7702
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7703
virtual void tabulate_entity_dofs(unsigned int* dofs,
7704
unsigned int d, unsigned int i) const
7706
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7709
/// Tabulate the coordinates of all dofs on a cell
7710
virtual void tabulate_coordinates(double** coordinates,
7711
const ufc::cell& c) const
7713
const double * const * x = c.coordinates;
7714
coordinates[0][0] = x[0][0];
7715
coordinates[0][1] = x[0][1];
7716
coordinates[1][0] = x[1][0];
7717
coordinates[1][1] = x[1][1];
7718
coordinates[2][0] = x[2][0];
7719
coordinates[2][1] = x[2][1];
7720
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
7721
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
7722
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
7723
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
7724
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
7725
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
7726
coordinates[6][0] = x[0][0];
7727
coordinates[6][1] = x[0][1];
7728
coordinates[7][0] = x[1][0];
7729
coordinates[7][1] = x[1][1];
7730
coordinates[8][0] = x[2][0];
7731
coordinates[8][1] = x[2][1];
7732
coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
7733
coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
7734
coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
7735
coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
7736
coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
7737
coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
7738
coordinates[12][0] = x[0][0];
7739
coordinates[12][1] = x[0][1];
7740
coordinates[13][0] = x[1][0];
7741
coordinates[13][1] = x[1][1];
7742
coordinates[14][0] = x[2][0];
7743
coordinates[14][1] = x[2][1];
7746
/// Return the number of sub dof maps (for a mixed element)
7747
virtual unsigned int num_sub_dof_maps() const
7752
/// Create a new dof_map for sub dof map i (for a mixed element)
7753
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
7758
return new stokes_0_dof_map_1_0();
7761
return new stokes_0_dof_map_1_1();
7769
/// This class defines the interface for the tabulation of the cell
7770
/// tensor corresponding to the local contribution to a form from
7771
/// the integral over a cell.
7773
class stokes_0_cell_integral_0_tensor: public ufc::cell_integral
7778
stokes_0_cell_integral_0_tensor() : ufc::cell_integral()
7784
virtual ~stokes_0_cell_integral_0_tensor()
7789
/// Tabulate the tensor for the contribution from a local cell
7790
virtual void tabulate_tensor(double* A,
7791
const double * const * w,
7792
const ufc::cell& c) const
7794
// Number of operations to compute geometry tensor: 40
7795
// Number of operations to compute tensor contraction: 564
7796
// Total number of operations to compute cell tensor: 604
7798
// Extract vertex coordinates
7799
const double * const * x = c.coordinates;
7801
// Compute Jacobian of affine map from reference cell
7802
const double J_00 = x[1][0] - x[0][0];
7803
const double J_01 = x[2][0] - x[0][0];
7804
const double J_10 = x[1][1] - x[0][1];
7805
const double J_11 = x[2][1] - x[0][1];
7807
// Compute determinant of Jacobian
7808
double detJ = J_00*J_11 - J_01*J_10;
7810
// Compute inverse of Jacobian
7811
const double Jinv_00 = J_11 / detJ;
7812
const double Jinv_01 = -J_01 / detJ;
7813
const double Jinv_10 = -J_10 / detJ;
7814
const double Jinv_11 = J_00 / detJ;
7817
const double det = std::abs(detJ);
7819
// Compute geometry tensor
7820
const double G0_0 = det*Jinv_00;
7821
const double G0_1 = det*Jinv_10;
7822
const double G1_0 = det*Jinv_01;
7823
const double G1_1 = det*Jinv_11;
7824
const double G2_0 = det*Jinv_00;
7825
const double G2_1 = det*Jinv_10;
7826
const double G3_0 = det*Jinv_01;
7827
const double G3_1 = det*Jinv_11;
7828
const double G4_0_0 = det*Jinv_00*Jinv_00;
7829
const double G4_0_1 = det*Jinv_00*Jinv_10;
7830
const double G4_1_0 = det*Jinv_10*Jinv_00;
7831
const double G4_1_1 = det*Jinv_10*Jinv_10;
7832
const double G5_0_0 = det*Jinv_00*Jinv_00;
7833
const double G5_0_1 = det*Jinv_00*Jinv_10;
7834
const double G5_1_0 = det*Jinv_10*Jinv_00;
7835
const double G5_1_1 = det*Jinv_10*Jinv_10;
7836
const double G6_0_0 = det*Jinv_01*Jinv_01;
7837
const double G6_0_1 = det*Jinv_01*Jinv_11;
7838
const double G6_1_0 = det*Jinv_11*Jinv_01;
7839
const double G6_1_1 = det*Jinv_11*Jinv_11;
7840
const double G7_0_0 = det*Jinv_01*Jinv_01;
7841
const double G7_0_1 = det*Jinv_01*Jinv_11;
7842
const double G7_1_0 = det*Jinv_11*Jinv_01;
7843
const double G7_1_1 = det*Jinv_11*Jinv_11;
7845
// Compute element tensor
7846
A[0] += 0.5*G4_0_0 + 0.5*G4_0_1 + 0.5*G4_1_0 + 0.5*G4_1_1 + 0.5*G6_0_0 + 0.5*G6_0_1 + 0.5*G6_1_0 + 0.5*G6_1_1;
7847
A[1] += 0.166666667*G4_0_0 + 0.166666667*G4_1_0 + 0.166666667*G6_0_0 + 0.166666667*G6_1_0;
7848
A[2] += 0.166666667*G4_0_1 + 0.166666667*G4_1_1 + 0.166666667*G6_0_1 + 0.166666667*G6_1_1;
7850
A[4] += -0.666666667*G4_0_1 - 0.666666667*G4_1_1 - 0.666666667*G6_0_1 - 0.666666667*G6_1_1;
7851
A[5] += -0.666666667*G4_0_0 - 0.666666667*G4_1_0 - 0.666666667*G6_0_0 - 0.666666667*G6_1_0;
7858
A[12] += 0.166666667*G2_0 + 0.166666667*G2_1;
7861
A[15] += 0.166666667*G4_0_0 + 0.166666667*G4_0_1 + 0.166666667*G6_0_0 + 0.166666667*G6_0_1;
7862
A[16] += 0.5*G4_0_0 + 0.5*G6_0_0;
7863
A[17] += -0.166666667*G4_0_1 - 0.166666667*G6_0_1;
7864
A[18] += 0.666666667*G4_0_1 + 0.666666667*G6_0_1;
7866
A[20] += -0.666666667*G4_0_0 - 0.666666667*G4_0_1 - 0.666666667*G6_0_0 - 0.666666667*G6_0_1;
7874
A[28] += -0.166666667*G2_0;
7876
A[30] += 0.166666667*G4_1_0 + 0.166666667*G4_1_1 + 0.166666667*G6_1_0 + 0.166666667*G6_1_1;
7877
A[31] += -0.166666667*G4_1_0 - 0.166666667*G6_1_0;
7878
A[32] += 0.5*G4_1_1 + 0.5*G6_1_1;
7879
A[33] += 0.666666667*G4_1_0 + 0.666666667*G6_1_0;
7880
A[34] += -0.666666667*G4_1_0 - 0.666666667*G4_1_1 - 0.666666667*G6_1_0 - 0.666666667*G6_1_1;
7890
A[44] += -0.166666667*G2_1;
7892
A[46] += 0.666666667*G4_1_0 + 0.666666667*G6_1_0;
7893
A[47] += 0.666666667*G4_0_1 + 0.666666667*G6_0_1;
7894
A[48] += 1.33333333*G4_0_0 + 0.666666667*G4_0_1 + 0.666666667*G4_1_0 + 1.33333333*G4_1_1 + 1.33333333*G6_0_0 + 0.666666667*G6_0_1 + 0.666666667*G6_1_0 + 1.33333333*G6_1_1;
7895
A[49] += -1.33333333*G4_0_0 - 0.666666667*G4_0_1 - 0.666666667*G4_1_0 - 1.33333333*G6_0_0 - 0.666666667*G6_0_1 - 0.666666667*G6_1_0;
7896
A[50] += -0.666666667*G4_0_1 - 0.666666667*G4_1_0 - 1.33333333*G4_1_1 - 0.666666667*G6_0_1 - 0.666666667*G6_1_0 - 1.33333333*G6_1_1;
7903
A[57] += -0.166666667*G2_0 - 0.166666667*G2_1;
7904
A[58] += -0.166666667*G2_0 - 0.333333333*G2_1;
7905
A[59] += -0.333333333*G2_0 - 0.166666667*G2_1;
7906
A[60] += -0.666666667*G4_1_0 - 0.666666667*G4_1_1 - 0.666666667*G6_1_0 - 0.666666667*G6_1_1;
7908
A[62] += -0.666666667*G4_0_1 - 0.666666667*G4_1_1 - 0.666666667*G6_0_1 - 0.666666667*G6_1_1;
7909
A[63] += -1.33333333*G4_0_0 - 0.666666667*G4_0_1 - 0.666666667*G4_1_0 - 1.33333333*G6_0_0 - 0.666666667*G6_0_1 - 0.666666667*G6_1_0;
7910
A[64] += 1.33333333*G4_0_0 + 0.666666667*G4_0_1 + 0.666666667*G4_1_0 + 1.33333333*G4_1_1 + 1.33333333*G6_0_0 + 0.666666667*G6_0_1 + 0.666666667*G6_1_0 + 1.33333333*G6_1_1;
7911
A[65] += 0.666666667*G4_0_1 + 0.666666667*G4_1_0 + 0.666666667*G6_0_1 + 0.666666667*G6_1_0;
7918
A[72] += 0.166666667*G2_0 - 0.166666667*G2_1;
7919
A[73] += 0.166666667*G2_0;
7920
A[74] += 0.333333333*G2_0 + 0.166666667*G2_1;
7921
A[75] += -0.666666667*G4_0_0 - 0.666666667*G4_0_1 - 0.666666667*G6_0_0 - 0.666666667*G6_0_1;
7922
A[76] += -0.666666667*G4_0_0 - 0.666666667*G4_1_0 - 0.666666667*G6_0_0 - 0.666666667*G6_1_0;
7924
A[78] += -0.666666667*G4_0_1 - 0.666666667*G4_1_0 - 1.33333333*G4_1_1 - 0.666666667*G6_0_1 - 0.666666667*G6_1_0 - 1.33333333*G6_1_1;
7925
A[79] += 0.666666667*G4_0_1 + 0.666666667*G4_1_0 + 0.666666667*G6_0_1 + 0.666666667*G6_1_0;
7926
A[80] += 1.33333333*G4_0_0 + 0.666666667*G4_0_1 + 0.666666667*G4_1_0 + 1.33333333*G4_1_1 + 1.33333333*G6_0_0 + 0.666666667*G6_0_1 + 0.666666667*G6_1_0 + 1.33333333*G6_1_1;
7933
A[87] += -0.166666667*G2_0 + 0.166666667*G2_1;
7934
A[88] += 0.166666667*G2_0 + 0.333333333*G2_1;
7935
A[89] += 0.166666667*G2_1;
7942
A[96] += 0.5*G5_0_0 + 0.5*G5_0_1 + 0.5*G5_1_0 + 0.5*G5_1_1 + 0.5*G7_0_0 + 0.5*G7_0_1 + 0.5*G7_1_0 + 0.5*G7_1_1;
7943
A[97] += 0.166666667*G5_0_0 + 0.166666667*G5_1_0 + 0.166666667*G7_0_0 + 0.166666667*G7_1_0;
7944
A[98] += 0.166666667*G5_0_1 + 0.166666667*G5_1_1 + 0.166666667*G7_0_1 + 0.166666667*G7_1_1;
7946
A[100] += -0.666666667*G5_0_1 - 0.666666667*G5_1_1 - 0.666666667*G7_0_1 - 0.666666667*G7_1_1;
7947
A[101] += -0.666666667*G5_0_0 - 0.666666667*G5_1_0 - 0.666666667*G7_0_0 - 0.666666667*G7_1_0;
7948
A[102] += 0.166666667*G3_0 + 0.166666667*G3_1;
7957
A[111] += 0.166666667*G5_0_0 + 0.166666667*G5_0_1 + 0.166666667*G7_0_0 + 0.166666667*G7_0_1;
7958
A[112] += 0.5*G5_0_0 + 0.5*G7_0_0;
7959
A[113] += -0.166666667*G5_0_1 - 0.166666667*G7_0_1;
7960
A[114] += 0.666666667*G5_0_1 + 0.666666667*G7_0_1;
7962
A[116] += -0.666666667*G5_0_0 - 0.666666667*G5_0_1 - 0.666666667*G7_0_0 - 0.666666667*G7_0_1;
7964
A[118] += -0.166666667*G3_0;
7972
A[126] += 0.166666667*G5_1_0 + 0.166666667*G5_1_1 + 0.166666667*G7_1_0 + 0.166666667*G7_1_1;
7973
A[127] += -0.166666667*G5_1_0 - 0.166666667*G7_1_0;
7974
A[128] += 0.5*G5_1_1 + 0.5*G7_1_1;
7975
A[129] += 0.666666667*G5_1_0 + 0.666666667*G7_1_0;
7976
A[130] += -0.666666667*G5_1_0 - 0.666666667*G5_1_1 - 0.666666667*G7_1_0 - 0.666666667*G7_1_1;
7980
A[134] += -0.166666667*G3_1;
7988
A[142] += 0.666666667*G5_1_0 + 0.666666667*G7_1_0;
7989
A[143] += 0.666666667*G5_0_1 + 0.666666667*G7_0_1;
7990
A[144] += 1.33333333*G5_0_0 + 0.666666667*G5_0_1 + 0.666666667*G5_1_0 + 1.33333333*G5_1_1 + 1.33333333*G7_0_0 + 0.666666667*G7_0_1 + 0.666666667*G7_1_0 + 1.33333333*G7_1_1;
7991
A[145] += -1.33333333*G5_0_0 - 0.666666667*G5_0_1 - 0.666666667*G5_1_0 - 1.33333333*G7_0_0 - 0.666666667*G7_0_1 - 0.666666667*G7_1_0;
7992
A[146] += -0.666666667*G5_0_1 - 0.666666667*G5_1_0 - 1.33333333*G5_1_1 - 0.666666667*G7_0_1 - 0.666666667*G7_1_0 - 1.33333333*G7_1_1;
7993
A[147] += -0.166666667*G3_0 - 0.166666667*G3_1;
7994
A[148] += -0.166666667*G3_0 - 0.333333333*G3_1;
7995
A[149] += -0.333333333*G3_0 - 0.166666667*G3_1;
8002
A[156] += -0.666666667*G5_1_0 - 0.666666667*G5_1_1 - 0.666666667*G7_1_0 - 0.666666667*G7_1_1;
8004
A[158] += -0.666666667*G5_0_1 - 0.666666667*G5_1_1 - 0.666666667*G7_0_1 - 0.666666667*G7_1_1;
8005
A[159] += -1.33333333*G5_0_0 - 0.666666667*G5_0_1 - 0.666666667*G5_1_0 - 1.33333333*G7_0_0 - 0.666666667*G7_0_1 - 0.666666667*G7_1_0;
8006
A[160] += 1.33333333*G5_0_0 + 0.666666667*G5_0_1 + 0.666666667*G5_1_0 + 1.33333333*G5_1_1 + 1.33333333*G7_0_0 + 0.666666667*G7_0_1 + 0.666666667*G7_1_0 + 1.33333333*G7_1_1;
8007
A[161] += 0.666666667*G5_0_1 + 0.666666667*G5_1_0 + 0.666666667*G7_0_1 + 0.666666667*G7_1_0;
8008
A[162] += 0.166666667*G3_0 - 0.166666667*G3_1;
8009
A[163] += 0.166666667*G3_0;
8010
A[164] += 0.333333333*G3_0 + 0.166666667*G3_1;
8017
A[171] += -0.666666667*G5_0_0 - 0.666666667*G5_0_1 - 0.666666667*G7_0_0 - 0.666666667*G7_0_1;
8018
A[172] += -0.666666667*G5_0_0 - 0.666666667*G5_1_0 - 0.666666667*G7_0_0 - 0.666666667*G7_1_0;
8020
A[174] += -0.666666667*G5_0_1 - 0.666666667*G5_1_0 - 1.33333333*G5_1_1 - 0.666666667*G7_0_1 - 0.666666667*G7_1_0 - 1.33333333*G7_1_1;
8021
A[175] += 0.666666667*G5_0_1 + 0.666666667*G5_1_0 + 0.666666667*G7_0_1 + 0.666666667*G7_1_0;
8022
A[176] += 1.33333333*G5_0_0 + 0.666666667*G5_0_1 + 0.666666667*G5_1_0 + 1.33333333*G5_1_1 + 1.33333333*G7_0_0 + 0.666666667*G7_0_1 + 0.666666667*G7_1_0 + 1.33333333*G7_1_1;
8023
A[177] += -0.166666667*G3_0 + 0.166666667*G3_1;
8024
A[178] += 0.166666667*G3_0 + 0.333333333*G3_1;
8025
A[179] += 0.166666667*G3_1;
8026
A[180] += -0.166666667*G0_0 - 0.166666667*G0_1;
8029
A[183] += 0.166666667*G0_0 + 0.166666667*G0_1;
8030
A[184] += -0.166666667*G0_0 + 0.166666667*G0_1;
8031
A[185] += 0.166666667*G0_0 - 0.166666667*G0_1;
8032
A[186] += -0.166666667*G1_0 - 0.166666667*G1_1;
8035
A[189] += 0.166666667*G1_0 + 0.166666667*G1_1;
8036
A[190] += -0.166666667*G1_0 + 0.166666667*G1_1;
8037
A[191] += 0.166666667*G1_0 - 0.166666667*G1_1;
8042
A[196] += 0.166666667*G0_0;
8044
A[198] += 0.166666667*G0_0 + 0.333333333*G0_1;
8045
A[199] += -0.166666667*G0_0;
8046
A[200] += -0.166666667*G0_0 - 0.333333333*G0_1;
8048
A[202] += 0.166666667*G1_0;
8050
A[204] += 0.166666667*G1_0 + 0.333333333*G1_1;
8051
A[205] += -0.166666667*G1_0;
8052
A[206] += -0.166666667*G1_0 - 0.333333333*G1_1;
8058
A[212] += 0.166666667*G0_1;
8059
A[213] += 0.333333333*G0_0 + 0.166666667*G0_1;
8060
A[214] += -0.333333333*G0_0 - 0.166666667*G0_1;
8061
A[215] += -0.166666667*G0_1;
8064
A[218] += 0.166666667*G1_1;
8065
A[219] += 0.333333333*G1_0 + 0.166666667*G1_1;
8066
A[220] += -0.333333333*G1_0 - 0.166666667*G1_1;
8067
A[221] += -0.166666667*G1_1;
8075
/// This class defines the interface for the tabulation of the cell
8076
/// tensor corresponding to the local contribution to a form from
8077
/// the integral over a cell.
8079
class stokes_0_cell_integral_0: public ufc::cell_integral
8083
stokes_0_cell_integral_0_tensor integral_0_tensor;
8088
stokes_0_cell_integral_0() : ufc::cell_integral()
8094
virtual ~stokes_0_cell_integral_0()
8099
/// Tabulate the tensor for the contribution from a local cell
8100
virtual void tabulate_tensor(double* A,
8101
const double * const * w,
8102
const ufc::cell& c) const
8104
// Reset values of the element tensor block
8105
for (unsigned int j = 0; j < 225; j++)
8108
// Add all contributions to element tensor
8109
integral_0_tensor.tabulate_tensor(A, w, c);
8114
/// This class defines the interface for the assembly of the global
8115
/// tensor corresponding to a form with r + n arguments, that is, a
8118
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
8120
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
8121
/// global tensor A is defined by
8123
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
8125
/// where each argument Vj represents the application to the
8126
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
8127
/// fixed functions (coefficients).
8129
class stokes_form_0: public ufc::form
8134
stokes_form_0() : ufc::form()
8140
virtual ~stokes_form_0()
8145
/// Return a string identifying the form
8146
virtual const char* signature() const
8148
return "Form([Integral(Sum(Product(IndexSum(Indexed(ListTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 1), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(0),), {})), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 1), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(1),), {}))), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(0),), {Index(0): 2})), Indexed(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 0), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3}))), Sum(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(ListTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 0), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((FixedIndex(0),), {})), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 0), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((FixedIndex(1),), {}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2), Index(1)), {Index(2): 2, Index(1): 2})), MultiIndex((Index(3), Index(4)), {Index(4): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(ListTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 1), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(0),), {})), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 1), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(1),), {}))), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6), Index(5)), {Index(5): 2, Index(6): 2})), MultiIndex((Index(3), Index(4)), {Index(4): 2, Index(3): 2}))), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((Index(4),), {Index(4): 2})), Product(IntValue(-1, (), (), {}), Product(IndexSum(Indexed(ListTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 0), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((FixedIndex(0),), {})), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 0), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((FixedIndex(1),), {}))), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), Indexed(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 1), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3})))))), Measure('cell', 0, None))])";
8151
/// Return the rank of the global tensor (r)
8152
virtual unsigned int rank() const
8157
/// Return the number of coefficients (n)
8158
virtual unsigned int num_coefficients() const
8163
/// Return the number of cell integrals
8164
virtual unsigned int num_cell_integrals() const
8169
/// Return the number of exterior facet integrals
8170
virtual unsigned int num_exterior_facet_integrals() const
8175
/// Return the number of interior facet integrals
8176
virtual unsigned int num_interior_facet_integrals() const
8181
/// Create a new finite element for argument function i
8182
virtual ufc::finite_element* create_finite_element(unsigned int i) const
8187
return new stokes_0_finite_element_0();
8190
return new stokes_0_finite_element_1();
8196
/// Create a new dof map for argument function i
8197
virtual ufc::dof_map* create_dof_map(unsigned int i) const
8202
return new stokes_0_dof_map_0();
8205
return new stokes_0_dof_map_1();
8211
/// Create a new cell integral on sub domain i
8212
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
8214
return new stokes_0_cell_integral_0();
8217
/// Create a new exterior facet integral on sub domain i
8218
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
8223
/// Create a new interior facet integral on sub domain i
8224
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
8231
/// This class defines the interface for a finite element.
8233
class stokes_1_finite_element_0_0_0: public ufc::finite_element
8238
stokes_1_finite_element_0_0_0() : ufc::finite_element()
8244
virtual ~stokes_1_finite_element_0_0_0()
8249
/// Return a string identifying the finite element
8250
virtual const char* signature() const
8252
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
8255
/// Return the cell shape
8256
virtual ufc::shape cell_shape() const
8258
return ufc::triangle;
8261
/// Return the dimension of the finite element function space
8262
virtual unsigned int space_dimension() const
8267
/// Return the rank of the value space
8268
virtual unsigned int value_rank() const
8273
/// Return the dimension of the value space for axis i
8274
virtual unsigned int value_dimension(unsigned int i) const
8279
/// Evaluate basis function i at given point in cell
8280
virtual void evaluate_basis(unsigned int i,
8282
const double* coordinates,
8283
const ufc::cell& c) const
8285
// Extract vertex coordinates
8286
const double * const * element_coordinates = c.coordinates;
8288
// Compute Jacobian of affine map from reference cell
8289
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8290
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8291
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8292
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8294
// Compute determinant of Jacobian
8295
const double detJ = J_00*J_11 - J_01*J_10;
8297
// Compute inverse of Jacobian
8299
// Get coordinates and map to the reference (UFC) element
8300
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8301
element_coordinates[0][0]*element_coordinates[2][1] +\
8302
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8303
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8304
element_coordinates[1][0]*element_coordinates[0][1] -\
8305
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8307
// Map coordinates to the reference square
8308
if (std::abs(y - 1.0) < 1e-08)
8311
x = 2.0 *x/(1.0 - y) - 1.0;
8317
// Map degree of freedom to element degree of freedom
8318
const unsigned int dof = i;
8320
// Generate scalings
8321
const double scalings_y_0 = 1;
8322
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8323
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
8325
// Compute psitilde_a
8326
const double psitilde_a_0 = 1;
8327
const double psitilde_a_1 = x;
8328
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
8330
// Compute psitilde_bs
8331
const double psitilde_bs_0_0 = 1;
8332
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8333
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
8334
const double psitilde_bs_1_0 = 1;
8335
const double psitilde_bs_1_1 = 2.5*y + 1.5;
8336
const double psitilde_bs_2_0 = 1;
8338
// Compute basisvalues
8339
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8340
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8341
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8342
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
8343
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
8344
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
8346
// Table(s) of coefficients
8347
static const double coefficients0[6][6] = \
8348
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
8349
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
8350
{0, 0, 0.2, 0, 0, 0.163299316},
8351
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
8352
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
8353
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
8355
// Extract relevant coefficients
8356
const double coeff0_0 = coefficients0[dof][0];
8357
const double coeff0_1 = coefficients0[dof][1];
8358
const double coeff0_2 = coefficients0[dof][2];
8359
const double coeff0_3 = coefficients0[dof][3];
8360
const double coeff0_4 = coefficients0[dof][4];
8361
const double coeff0_5 = coefficients0[dof][5];
8364
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
8367
/// Evaluate all basis functions at given point in cell
8368
virtual void evaluate_basis_all(double* values,
8369
const double* coordinates,
8370
const ufc::cell& c) const
8372
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8375
/// Evaluate order n derivatives of basis function i at given point in cell
8376
virtual void evaluate_basis_derivatives(unsigned int i,
8379
const double* coordinates,
8380
const ufc::cell& c) const
8382
// Extract vertex coordinates
8383
const double * const * element_coordinates = c.coordinates;
8385
// Compute Jacobian of affine map from reference cell
8386
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8387
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8388
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8389
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8391
// Compute determinant of Jacobian
8392
const double detJ = J_00*J_11 - J_01*J_10;
8394
// Compute inverse of Jacobian
8396
// Get coordinates and map to the reference (UFC) element
8397
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8398
element_coordinates[0][0]*element_coordinates[2][1] +\
8399
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8400
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8401
element_coordinates[1][0]*element_coordinates[0][1] -\
8402
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8404
// Map coordinates to the reference square
8405
if (std::abs(y - 1.0) < 1e-08)
8408
x = 2.0 *x/(1.0 - y) - 1.0;
8411
// Compute number of derivatives
8412
unsigned int num_derivatives = 1;
8414
for (unsigned int j = 0; j < n; j++)
8415
num_derivatives *= 2;
8418
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8419
unsigned int **combinations = new unsigned int *[num_derivatives];
8421
for (unsigned int j = 0; j < num_derivatives; j++)
8423
combinations[j] = new unsigned int [n];
8424
for (unsigned int k = 0; k < n; k++)
8425
combinations[j][k] = 0;
8428
// Generate combinations of derivatives
8429
for (unsigned int row = 1; row < num_derivatives; row++)
8431
for (unsigned int num = 0; num < row; num++)
8433
for (unsigned int col = n-1; col+1 > 0; col--)
8435
if (combinations[row][col] + 1 > 1)
8436
combinations[row][col] = 0;
8439
combinations[row][col] += 1;
8446
// Compute inverse of Jacobian
8447
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8449
// Declare transformation matrix
8450
// Declare pointer to two dimensional array and initialise
8451
double **transform = new double *[num_derivatives];
8453
for (unsigned int j = 0; j < num_derivatives; j++)
8455
transform[j] = new double [num_derivatives];
8456
for (unsigned int k = 0; k < num_derivatives; k++)
8457
transform[j][k] = 1;
8460
// Construct transformation matrix
8461
for (unsigned int row = 0; row < num_derivatives; row++)
8463
for (unsigned int col = 0; col < num_derivatives; col++)
8465
for (unsigned int k = 0; k < n; k++)
8466
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8471
for (unsigned int j = 0; j < 1*num_derivatives; j++)
8474
// Map degree of freedom to element degree of freedom
8475
const unsigned int dof = i;
8477
// Generate scalings
8478
const double scalings_y_0 = 1;
8479
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8480
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
8482
// Compute psitilde_a
8483
const double psitilde_a_0 = 1;
8484
const double psitilde_a_1 = x;
8485
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
8487
// Compute psitilde_bs
8488
const double psitilde_bs_0_0 = 1;
8489
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8490
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
8491
const double psitilde_bs_1_0 = 1;
8492
const double psitilde_bs_1_1 = 2.5*y + 1.5;
8493
const double psitilde_bs_2_0 = 1;
8495
// Compute basisvalues
8496
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8497
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8498
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8499
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
8500
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
8501
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
8503
// Table(s) of coefficients
8504
static const double coefficients0[6][6] = \
8505
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
8506
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
8507
{0, 0, 0.2, 0, 0, 0.163299316},
8508
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
8509
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
8510
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
8512
// Interesting (new) part
8513
// Tables of derivatives of the polynomial base (transpose)
8514
static const double dmats0[6][6] = \
8515
{{0, 0, 0, 0, 0, 0},
8516
{4.89897949, 0, 0, 0, 0, 0},
8518
{0, 9.48683298, 0, 0, 0, 0},
8519
{4, 0, 7.07106781, 0, 0, 0},
8520
{0, 0, 0, 0, 0, 0}};
8522
static const double dmats1[6][6] = \
8523
{{0, 0, 0, 0, 0, 0},
8524
{2.44948974, 0, 0, 0, 0, 0},
8525
{4.24264069, 0, 0, 0, 0, 0},
8526
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
8527
{2, 6.12372436, 3.53553391, 0, 0, 0},
8528
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
8530
// Compute reference derivatives
8531
// Declare pointer to array of derivatives on FIAT element
8532
double *derivatives = new double [num_derivatives];
8534
// Declare coefficients
8535
double coeff0_0 = 0;
8536
double coeff0_1 = 0;
8537
double coeff0_2 = 0;
8538
double coeff0_3 = 0;
8539
double coeff0_4 = 0;
8540
double coeff0_5 = 0;
8542
// Declare new coefficients
8543
double new_coeff0_0 = 0;
8544
double new_coeff0_1 = 0;
8545
double new_coeff0_2 = 0;
8546
double new_coeff0_3 = 0;
8547
double new_coeff0_4 = 0;
8548
double new_coeff0_5 = 0;
8550
// Loop possible derivatives
8551
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8553
// Get values from coefficients array
8554
new_coeff0_0 = coefficients0[dof][0];
8555
new_coeff0_1 = coefficients0[dof][1];
8556
new_coeff0_2 = coefficients0[dof][2];
8557
new_coeff0_3 = coefficients0[dof][3];
8558
new_coeff0_4 = coefficients0[dof][4];
8559
new_coeff0_5 = coefficients0[dof][5];
8561
// Loop derivative order
8562
for (unsigned int j = 0; j < n; j++)
8564
// Update old coefficients
8565
coeff0_0 = new_coeff0_0;
8566
coeff0_1 = new_coeff0_1;
8567
coeff0_2 = new_coeff0_2;
8568
coeff0_3 = new_coeff0_3;
8569
coeff0_4 = new_coeff0_4;
8570
coeff0_5 = new_coeff0_5;
8572
if(combinations[deriv_num][j] == 0)
8574
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
8575
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
8576
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
8577
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
8578
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
8579
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
8581
if(combinations[deriv_num][j] == 1)
8583
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
8584
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
8585
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
8586
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
8587
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
8588
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
8592
// Compute derivatives on reference element as dot product of coefficients and basisvalues
8593
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
8596
// Transform derivatives back to physical element
8597
for (unsigned int row = 0; row < num_derivatives; row++)
8599
for (unsigned int col = 0; col < num_derivatives; col++)
8601
values[row] += transform[row][col]*derivatives[col];
8604
// Delete pointer to array of derivatives on FIAT element
8605
delete [] derivatives;
8607
// Delete pointer to array of combinations of derivatives and transform
8608
for (unsigned int row = 0; row < num_derivatives; row++)
8610
delete [] combinations[row];
8611
delete [] transform[row];
8614
delete [] combinations;
8615
delete [] transform;
8618
/// Evaluate order n derivatives of all basis functions at given point in cell
8619
virtual void evaluate_basis_derivatives_all(unsigned int n,
8621
const double* coordinates,
8622
const ufc::cell& c) const
8624
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8627
/// Evaluate linear functional for dof i on the function f
8628
virtual double evaluate_dof(unsigned int i,
8629
const ufc::function& f,
8630
const ufc::cell& c) const
8632
// The reference points, direction and weights:
8633
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
8634
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
8635
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
8637
const double * const * x = c.coordinates;
8638
double result = 0.0;
8639
// Iterate over the points:
8640
// Evaluate basis functions for affine mapping
8641
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
8642
const double w1 = X[i][0][0];
8643
const double w2 = X[i][0][1];
8645
// Compute affine mapping y = F(X)
8647
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
8648
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
8650
// Evaluate function at physical points
8652
f.evaluate(values, y, c);
8654
// Map function values using appropriate mapping
8655
// Affine map: Do nothing
8657
// Note that we do not map the weights (yet).
8659
// Take directional components
8660
for(int k = 0; k < 1; k++)
8661
result += values[k]*D[i][0][k];
8662
// Multiply by weights
8668
/// Evaluate linear functionals for all dofs on the function f
8669
virtual void evaluate_dofs(double* values,
8670
const ufc::function& f,
8671
const ufc::cell& c) const
8673
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8676
/// Interpolate vertex values from dof values
8677
virtual void interpolate_vertex_values(double* vertex_values,
8678
const double* dof_values,
8679
const ufc::cell& c) const
8681
// Evaluate at vertices and use affine mapping
8682
vertex_values[0] = dof_values[0];
8683
vertex_values[1] = dof_values[1];
8684
vertex_values[2] = dof_values[2];
8687
/// Return the number of sub elements (for a mixed element)
8688
virtual unsigned int num_sub_elements() const
8693
/// Create a new finite element for sub element i (for a mixed element)
8694
virtual ufc::finite_element* create_sub_element(unsigned int i) const
8696
return new stokes_1_finite_element_0_0_0();
8701
/// This class defines the interface for a finite element.
8703
class stokes_1_finite_element_0_0_1: public ufc::finite_element
8708
stokes_1_finite_element_0_0_1() : ufc::finite_element()
8714
virtual ~stokes_1_finite_element_0_0_1()
8719
/// Return a string identifying the finite element
8720
virtual const char* signature() const
8722
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
8725
/// Return the cell shape
8726
virtual ufc::shape cell_shape() const
8728
return ufc::triangle;
8731
/// Return the dimension of the finite element function space
8732
virtual unsigned int space_dimension() const
8737
/// Return the rank of the value space
8738
virtual unsigned int value_rank() const
8743
/// Return the dimension of the value space for axis i
8744
virtual unsigned int value_dimension(unsigned int i) const
8749
/// Evaluate basis function i at given point in cell
8750
virtual void evaluate_basis(unsigned int i,
8752
const double* coordinates,
8753
const ufc::cell& c) const
8755
// Extract vertex coordinates
8756
const double * const * element_coordinates = c.coordinates;
8758
// Compute Jacobian of affine map from reference cell
8759
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8760
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8761
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8762
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8764
// Compute determinant of Jacobian
8765
const double detJ = J_00*J_11 - J_01*J_10;
8767
// Compute inverse of Jacobian
8769
// Get coordinates and map to the reference (UFC) element
8770
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8771
element_coordinates[0][0]*element_coordinates[2][1] +\
8772
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8773
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8774
element_coordinates[1][0]*element_coordinates[0][1] -\
8775
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8777
// Map coordinates to the reference square
8778
if (std::abs(y - 1.0) < 1e-08)
8781
x = 2.0 *x/(1.0 - y) - 1.0;
8787
// Map degree of freedom to element degree of freedom
8788
const unsigned int dof = i;
8790
// Generate scalings
8791
const double scalings_y_0 = 1;
8792
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8793
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
8795
// Compute psitilde_a
8796
const double psitilde_a_0 = 1;
8797
const double psitilde_a_1 = x;
8798
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
8800
// Compute psitilde_bs
8801
const double psitilde_bs_0_0 = 1;
8802
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8803
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
8804
const double psitilde_bs_1_0 = 1;
8805
const double psitilde_bs_1_1 = 2.5*y + 1.5;
8806
const double psitilde_bs_2_0 = 1;
8808
// Compute basisvalues
8809
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8810
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8811
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8812
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
8813
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
8814
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
8816
// Table(s) of coefficients
8817
static const double coefficients0[6][6] = \
8818
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
8819
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
8820
{0, 0, 0.2, 0, 0, 0.163299316},
8821
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
8822
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
8823
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
8825
// Extract relevant coefficients
8826
const double coeff0_0 = coefficients0[dof][0];
8827
const double coeff0_1 = coefficients0[dof][1];
8828
const double coeff0_2 = coefficients0[dof][2];
8829
const double coeff0_3 = coefficients0[dof][3];
8830
const double coeff0_4 = coefficients0[dof][4];
8831
const double coeff0_5 = coefficients0[dof][5];
8834
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
8837
/// Evaluate all basis functions at given point in cell
8838
virtual void evaluate_basis_all(double* values,
8839
const double* coordinates,
8840
const ufc::cell& c) const
8842
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8845
/// Evaluate order n derivatives of basis function i at given point in cell
8846
virtual void evaluate_basis_derivatives(unsigned int i,
8849
const double* coordinates,
8850
const ufc::cell& c) const
8852
// Extract vertex coordinates
8853
const double * const * element_coordinates = c.coordinates;
8855
// Compute Jacobian of affine map from reference cell
8856
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8857
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8858
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8859
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8861
// Compute determinant of Jacobian
8862
const double detJ = J_00*J_11 - J_01*J_10;
8864
// Compute inverse of Jacobian
8866
// Get coordinates and map to the reference (UFC) element
8867
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8868
element_coordinates[0][0]*element_coordinates[2][1] +\
8869
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8870
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8871
element_coordinates[1][0]*element_coordinates[0][1] -\
8872
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8874
// Map coordinates to the reference square
8875
if (std::abs(y - 1.0) < 1e-08)
8878
x = 2.0 *x/(1.0 - y) - 1.0;
8881
// Compute number of derivatives
8882
unsigned int num_derivatives = 1;
8884
for (unsigned int j = 0; j < n; j++)
8885
num_derivatives *= 2;
8888
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8889
unsigned int **combinations = new unsigned int *[num_derivatives];
8891
for (unsigned int j = 0; j < num_derivatives; j++)
8893
combinations[j] = new unsigned int [n];
8894
for (unsigned int k = 0; k < n; k++)
8895
combinations[j][k] = 0;
8898
// Generate combinations of derivatives
8899
for (unsigned int row = 1; row < num_derivatives; row++)
8901
for (unsigned int num = 0; num < row; num++)
8903
for (unsigned int col = n-1; col+1 > 0; col--)
8905
if (combinations[row][col] + 1 > 1)
8906
combinations[row][col] = 0;
8909
combinations[row][col] += 1;
8916
// Compute inverse of Jacobian
8917
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8919
// Declare transformation matrix
8920
// Declare pointer to two dimensional array and initialise
8921
double **transform = new double *[num_derivatives];
8923
for (unsigned int j = 0; j < num_derivatives; j++)
8925
transform[j] = new double [num_derivatives];
8926
for (unsigned int k = 0; k < num_derivatives; k++)
8927
transform[j][k] = 1;
8930
// Construct transformation matrix
8931
for (unsigned int row = 0; row < num_derivatives; row++)
8933
for (unsigned int col = 0; col < num_derivatives; col++)
8935
for (unsigned int k = 0; k < n; k++)
8936
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8941
for (unsigned int j = 0; j < 1*num_derivatives; j++)
8944
// Map degree of freedom to element degree of freedom
8945
const unsigned int dof = i;
8947
// Generate scalings
8948
const double scalings_y_0 = 1;
8949
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8950
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
8952
// Compute psitilde_a
8953
const double psitilde_a_0 = 1;
8954
const double psitilde_a_1 = x;
8955
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
8957
// Compute psitilde_bs
8958
const double psitilde_bs_0_0 = 1;
8959
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8960
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
8961
const double psitilde_bs_1_0 = 1;
8962
const double psitilde_bs_1_1 = 2.5*y + 1.5;
8963
const double psitilde_bs_2_0 = 1;
8965
// Compute basisvalues
8966
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8967
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8968
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8969
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
8970
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
8971
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
8973
// Table(s) of coefficients
8974
static const double coefficients0[6][6] = \
8975
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
8976
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
8977
{0, 0, 0.2, 0, 0, 0.163299316},
8978
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
8979
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
8980
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
8982
// Interesting (new) part
8983
// Tables of derivatives of the polynomial base (transpose)
8984
static const double dmats0[6][6] = \
8985
{{0, 0, 0, 0, 0, 0},
8986
{4.89897949, 0, 0, 0, 0, 0},
8988
{0, 9.48683298, 0, 0, 0, 0},
8989
{4, 0, 7.07106781, 0, 0, 0},
8990
{0, 0, 0, 0, 0, 0}};
8992
static const double dmats1[6][6] = \
8993
{{0, 0, 0, 0, 0, 0},
8994
{2.44948974, 0, 0, 0, 0, 0},
8995
{4.24264069, 0, 0, 0, 0, 0},
8996
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
8997
{2, 6.12372436, 3.53553391, 0, 0, 0},
8998
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
9000
// Compute reference derivatives
9001
// Declare pointer to array of derivatives on FIAT element
9002
double *derivatives = new double [num_derivatives];
9004
// Declare coefficients
9005
double coeff0_0 = 0;
9006
double coeff0_1 = 0;
9007
double coeff0_2 = 0;
9008
double coeff0_3 = 0;
9009
double coeff0_4 = 0;
9010
double coeff0_5 = 0;
9012
// Declare new coefficients
9013
double new_coeff0_0 = 0;
9014
double new_coeff0_1 = 0;
9015
double new_coeff0_2 = 0;
9016
double new_coeff0_3 = 0;
9017
double new_coeff0_4 = 0;
9018
double new_coeff0_5 = 0;
9020
// Loop possible derivatives
9021
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9023
// Get values from coefficients array
9024
new_coeff0_0 = coefficients0[dof][0];
9025
new_coeff0_1 = coefficients0[dof][1];
9026
new_coeff0_2 = coefficients0[dof][2];
9027
new_coeff0_3 = coefficients0[dof][3];
9028
new_coeff0_4 = coefficients0[dof][4];
9029
new_coeff0_5 = coefficients0[dof][5];
9031
// Loop derivative order
9032
for (unsigned int j = 0; j < n; j++)
9034
// Update old coefficients
9035
coeff0_0 = new_coeff0_0;
9036
coeff0_1 = new_coeff0_1;
9037
coeff0_2 = new_coeff0_2;
9038
coeff0_3 = new_coeff0_3;
9039
coeff0_4 = new_coeff0_4;
9040
coeff0_5 = new_coeff0_5;
9042
if(combinations[deriv_num][j] == 0)
9044
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
9045
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
9046
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
9047
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
9048
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
9049
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
9051
if(combinations[deriv_num][j] == 1)
9053
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
9054
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
9055
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
9056
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
9057
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
9058
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
9062
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9063
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
9066
// Transform derivatives back to physical element
9067
for (unsigned int row = 0; row < num_derivatives; row++)
9069
for (unsigned int col = 0; col < num_derivatives; col++)
9071
values[row] += transform[row][col]*derivatives[col];
9074
// Delete pointer to array of derivatives on FIAT element
9075
delete [] derivatives;
9077
// Delete pointer to array of combinations of derivatives and transform
9078
for (unsigned int row = 0; row < num_derivatives; row++)
9080
delete [] combinations[row];
9081
delete [] transform[row];
9084
delete [] combinations;
9085
delete [] transform;
9088
/// Evaluate order n derivatives of all basis functions at given point in cell
9089
virtual void evaluate_basis_derivatives_all(unsigned int n,
9091
const double* coordinates,
9092
const ufc::cell& c) const
9094
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9097
/// Evaluate linear functional for dof i on the function f
9098
virtual double evaluate_dof(unsigned int i,
9099
const ufc::function& f,
9100
const ufc::cell& c) const
9102
// The reference points, direction and weights:
9103
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
9104
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
9105
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
9107
const double * const * x = c.coordinates;
9108
double result = 0.0;
9109
// Iterate over the points:
9110
// Evaluate basis functions for affine mapping
9111
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9112
const double w1 = X[i][0][0];
9113
const double w2 = X[i][0][1];
9115
// Compute affine mapping y = F(X)
9117
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9118
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9120
// Evaluate function at physical points
9122
f.evaluate(values, y, c);
9124
// Map function values using appropriate mapping
9125
// Affine map: Do nothing
9127
// Note that we do not map the weights (yet).
9129
// Take directional components
9130
for(int k = 0; k < 1; k++)
9131
result += values[k]*D[i][0][k];
9132
// Multiply by weights
9138
/// Evaluate linear functionals for all dofs on the function f
9139
virtual void evaluate_dofs(double* values,
9140
const ufc::function& f,
9141
const ufc::cell& c) const
9143
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9146
/// Interpolate vertex values from dof values
9147
virtual void interpolate_vertex_values(double* vertex_values,
9148
const double* dof_values,
9149
const ufc::cell& c) const
9151
// Evaluate at vertices and use affine mapping
9152
vertex_values[0] = dof_values[0];
9153
vertex_values[1] = dof_values[1];
9154
vertex_values[2] = dof_values[2];
9157
/// Return the number of sub elements (for a mixed element)
9158
virtual unsigned int num_sub_elements() const
9163
/// Create a new finite element for sub element i (for a mixed element)
9164
virtual ufc::finite_element* create_sub_element(unsigned int i) const
9166
return new stokes_1_finite_element_0_0_1();
9171
/// This class defines the interface for a finite element.
9173
class stokes_1_finite_element_0_0: public ufc::finite_element
9178
stokes_1_finite_element_0_0() : ufc::finite_element()
9184
virtual ~stokes_1_finite_element_0_0()
9189
/// Return a string identifying the finite element
9190
virtual const char* signature() const
9192
return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
9195
/// Return the cell shape
9196
virtual ufc::shape cell_shape() const
9198
return ufc::triangle;
9201
/// Return the dimension of the finite element function space
9202
virtual unsigned int space_dimension() const
9207
/// Return the rank of the value space
9208
virtual unsigned int value_rank() const
9213
/// Return the dimension of the value space for axis i
9214
virtual unsigned int value_dimension(unsigned int i) const
9219
/// Evaluate basis function i at given point in cell
9220
virtual void evaluate_basis(unsigned int i,
9222
const double* coordinates,
9223
const ufc::cell& c) const
9225
// Extract vertex coordinates
9226
const double * const * element_coordinates = c.coordinates;
9228
// Compute Jacobian of affine map from reference cell
9229
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9230
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9231
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9232
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9234
// Compute determinant of Jacobian
9235
const double detJ = J_00*J_11 - J_01*J_10;
9237
// Compute inverse of Jacobian
9239
// Get coordinates and map to the reference (UFC) element
9240
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9241
element_coordinates[0][0]*element_coordinates[2][1] +\
9242
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9243
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9244
element_coordinates[1][0]*element_coordinates[0][1] -\
9245
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9247
// Map coordinates to the reference square
9248
if (std::abs(y - 1.0) < 1e-08)
9251
x = 2.0 *x/(1.0 - y) - 1.0;
9258
if (0 <= i && i <= 5)
9260
// Map degree of freedom to element degree of freedom
9261
const unsigned int dof = i;
9263
// Generate scalings
9264
const double scalings_y_0 = 1;
9265
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9266
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
9268
// Compute psitilde_a
9269
const double psitilde_a_0 = 1;
9270
const double psitilde_a_1 = x;
9271
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
9273
// Compute psitilde_bs
9274
const double psitilde_bs_0_0 = 1;
9275
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9276
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
9277
const double psitilde_bs_1_0 = 1;
9278
const double psitilde_bs_1_1 = 2.5*y + 1.5;
9279
const double psitilde_bs_2_0 = 1;
9281
// Compute basisvalues
9282
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9283
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9284
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9285
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
9286
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
9287
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
9289
// Table(s) of coefficients
9290
static const double coefficients0[6][6] = \
9291
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
9292
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
9293
{0, 0, 0.2, 0, 0, 0.163299316},
9294
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
9295
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
9296
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
9298
// Extract relevant coefficients
9299
const double coeff0_0 = coefficients0[dof][0];
9300
const double coeff0_1 = coefficients0[dof][1];
9301
const double coeff0_2 = coefficients0[dof][2];
9302
const double coeff0_3 = coefficients0[dof][3];
9303
const double coeff0_4 = coefficients0[dof][4];
9304
const double coeff0_5 = coefficients0[dof][5];
9307
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
9310
if (6 <= i && i <= 11)
9312
// Map degree of freedom to element degree of freedom
9313
const unsigned int dof = i - 6;
9315
// Generate scalings
9316
const double scalings_y_0 = 1;
9317
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9318
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
9320
// Compute psitilde_a
9321
const double psitilde_a_0 = 1;
9322
const double psitilde_a_1 = x;
9323
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
9325
// Compute psitilde_bs
9326
const double psitilde_bs_0_0 = 1;
9327
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9328
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
9329
const double psitilde_bs_1_0 = 1;
9330
const double psitilde_bs_1_1 = 2.5*y + 1.5;
9331
const double psitilde_bs_2_0 = 1;
9333
// Compute basisvalues
9334
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9335
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9336
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9337
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
9338
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
9339
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
9341
// Table(s) of coefficients
9342
static const double coefficients0[6][6] = \
9343
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
9344
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
9345
{0, 0, 0.2, 0, 0, 0.163299316},
9346
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
9347
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
9348
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
9350
// Extract relevant coefficients
9351
const double coeff0_0 = coefficients0[dof][0];
9352
const double coeff0_1 = coefficients0[dof][1];
9353
const double coeff0_2 = coefficients0[dof][2];
9354
const double coeff0_3 = coefficients0[dof][3];
9355
const double coeff0_4 = coefficients0[dof][4];
9356
const double coeff0_5 = coefficients0[dof][5];
9359
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
9364
/// Evaluate all basis functions at given point in cell
9365
virtual void evaluate_basis_all(double* values,
9366
const double* coordinates,
9367
const ufc::cell& c) const
9369
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9372
/// Evaluate order n derivatives of basis function i at given point in cell
9373
virtual void evaluate_basis_derivatives(unsigned int i,
9376
const double* coordinates,
9377
const ufc::cell& c) const
9379
// Extract vertex coordinates
9380
const double * const * element_coordinates = c.coordinates;
9382
// Compute Jacobian of affine map from reference cell
9383
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9384
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9385
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9386
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9388
// Compute determinant of Jacobian
9389
const double detJ = J_00*J_11 - J_01*J_10;
9391
// Compute inverse of Jacobian
9393
// Get coordinates and map to the reference (UFC) element
9394
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9395
element_coordinates[0][0]*element_coordinates[2][1] +\
9396
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9397
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9398
element_coordinates[1][0]*element_coordinates[0][1] -\
9399
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9401
// Map coordinates to the reference square
9402
if (std::abs(y - 1.0) < 1e-08)
9405
x = 2.0 *x/(1.0 - y) - 1.0;
9408
// Compute number of derivatives
9409
unsigned int num_derivatives = 1;
9411
for (unsigned int j = 0; j < n; j++)
9412
num_derivatives *= 2;
9415
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9416
unsigned int **combinations = new unsigned int *[num_derivatives];
9418
for (unsigned int j = 0; j < num_derivatives; j++)
9420
combinations[j] = new unsigned int [n];
9421
for (unsigned int k = 0; k < n; k++)
9422
combinations[j][k] = 0;
9425
// Generate combinations of derivatives
9426
for (unsigned int row = 1; row < num_derivatives; row++)
9428
for (unsigned int num = 0; num < row; num++)
9430
for (unsigned int col = n-1; col+1 > 0; col--)
9432
if (combinations[row][col] + 1 > 1)
9433
combinations[row][col] = 0;
9436
combinations[row][col] += 1;
9443
// Compute inverse of Jacobian
9444
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
9446
// Declare transformation matrix
9447
// Declare pointer to two dimensional array and initialise
9448
double **transform = new double *[num_derivatives];
9450
for (unsigned int j = 0; j < num_derivatives; j++)
9452
transform[j] = new double [num_derivatives];
9453
for (unsigned int k = 0; k < num_derivatives; k++)
9454
transform[j][k] = 1;
9457
// Construct transformation matrix
9458
for (unsigned int row = 0; row < num_derivatives; row++)
9460
for (unsigned int col = 0; col < num_derivatives; col++)
9462
for (unsigned int k = 0; k < n; k++)
9463
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
9468
for (unsigned int j = 0; j < 2*num_derivatives; j++)
9471
if (0 <= i && i <= 5)
9473
// Map degree of freedom to element degree of freedom
9474
const unsigned int dof = i;
9476
// Generate scalings
9477
const double scalings_y_0 = 1;
9478
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9479
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
9481
// Compute psitilde_a
9482
const double psitilde_a_0 = 1;
9483
const double psitilde_a_1 = x;
9484
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
9486
// Compute psitilde_bs
9487
const double psitilde_bs_0_0 = 1;
9488
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9489
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
9490
const double psitilde_bs_1_0 = 1;
9491
const double psitilde_bs_1_1 = 2.5*y + 1.5;
9492
const double psitilde_bs_2_0 = 1;
9494
// Compute basisvalues
9495
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9496
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9497
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9498
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
9499
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
9500
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
9502
// Table(s) of coefficients
9503
static const double coefficients0[6][6] = \
9504
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
9505
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
9506
{0, 0, 0.2, 0, 0, 0.163299316},
9507
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
9508
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
9509
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
9511
// Interesting (new) part
9512
// Tables of derivatives of the polynomial base (transpose)
9513
static const double dmats0[6][6] = \
9514
{{0, 0, 0, 0, 0, 0},
9515
{4.89897949, 0, 0, 0, 0, 0},
9517
{0, 9.48683298, 0, 0, 0, 0},
9518
{4, 0, 7.07106781, 0, 0, 0},
9519
{0, 0, 0, 0, 0, 0}};
9521
static const double dmats1[6][6] = \
9522
{{0, 0, 0, 0, 0, 0},
9523
{2.44948974, 0, 0, 0, 0, 0},
9524
{4.24264069, 0, 0, 0, 0, 0},
9525
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
9526
{2, 6.12372436, 3.53553391, 0, 0, 0},
9527
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
9529
// Compute reference derivatives
9530
// Declare pointer to array of derivatives on FIAT element
9531
double *derivatives = new double [num_derivatives];
9533
// Declare coefficients
9534
double coeff0_0 = 0;
9535
double coeff0_1 = 0;
9536
double coeff0_2 = 0;
9537
double coeff0_3 = 0;
9538
double coeff0_4 = 0;
9539
double coeff0_5 = 0;
9541
// Declare new coefficients
9542
double new_coeff0_0 = 0;
9543
double new_coeff0_1 = 0;
9544
double new_coeff0_2 = 0;
9545
double new_coeff0_3 = 0;
9546
double new_coeff0_4 = 0;
9547
double new_coeff0_5 = 0;
9549
// Loop possible derivatives
9550
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9552
// Get values from coefficients array
9553
new_coeff0_0 = coefficients0[dof][0];
9554
new_coeff0_1 = coefficients0[dof][1];
9555
new_coeff0_2 = coefficients0[dof][2];
9556
new_coeff0_3 = coefficients0[dof][3];
9557
new_coeff0_4 = coefficients0[dof][4];
9558
new_coeff0_5 = coefficients0[dof][5];
9560
// Loop derivative order
9561
for (unsigned int j = 0; j < n; j++)
9563
// Update old coefficients
9564
coeff0_0 = new_coeff0_0;
9565
coeff0_1 = new_coeff0_1;
9566
coeff0_2 = new_coeff0_2;
9567
coeff0_3 = new_coeff0_3;
9568
coeff0_4 = new_coeff0_4;
9569
coeff0_5 = new_coeff0_5;
9571
if(combinations[deriv_num][j] == 0)
9573
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
9574
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
9575
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
9576
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
9577
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
9578
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
9580
if(combinations[deriv_num][j] == 1)
9582
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
9583
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
9584
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
9585
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
9586
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
9587
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
9591
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9592
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
9595
// Transform derivatives back to physical element
9596
for (unsigned int row = 0; row < num_derivatives; row++)
9598
for (unsigned int col = 0; col < num_derivatives; col++)
9600
values[row] += transform[row][col]*derivatives[col];
9603
// Delete pointer to array of derivatives on FIAT element
9604
delete [] derivatives;
9606
// Delete pointer to array of combinations of derivatives and transform
9607
for (unsigned int row = 0; row < num_derivatives; row++)
9609
delete [] combinations[row];
9610
delete [] transform[row];
9613
delete [] combinations;
9614
delete [] transform;
9617
if (6 <= i && i <= 11)
9619
// Map degree of freedom to element degree of freedom
9620
const unsigned int dof = i - 6;
9622
// Generate scalings
9623
const double scalings_y_0 = 1;
9624
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9625
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
9627
// Compute psitilde_a
9628
const double psitilde_a_0 = 1;
9629
const double psitilde_a_1 = x;
9630
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
9632
// Compute psitilde_bs
9633
const double psitilde_bs_0_0 = 1;
9634
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9635
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
9636
const double psitilde_bs_1_0 = 1;
9637
const double psitilde_bs_1_1 = 2.5*y + 1.5;
9638
const double psitilde_bs_2_0 = 1;
9640
// Compute basisvalues
9641
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9642
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9643
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9644
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
9645
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
9646
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
9648
// Table(s) of coefficients
9649
static const double coefficients0[6][6] = \
9650
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
9651
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
9652
{0, 0, 0.2, 0, 0, 0.163299316},
9653
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
9654
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
9655
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
9657
// Interesting (new) part
9658
// Tables of derivatives of the polynomial base (transpose)
9659
static const double dmats0[6][6] = \
9660
{{0, 0, 0, 0, 0, 0},
9661
{4.89897949, 0, 0, 0, 0, 0},
9663
{0, 9.48683298, 0, 0, 0, 0},
9664
{4, 0, 7.07106781, 0, 0, 0},
9665
{0, 0, 0, 0, 0, 0}};
9667
static const double dmats1[6][6] = \
9668
{{0, 0, 0, 0, 0, 0},
9669
{2.44948974, 0, 0, 0, 0, 0},
9670
{4.24264069, 0, 0, 0, 0, 0},
9671
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
9672
{2, 6.12372436, 3.53553391, 0, 0, 0},
9673
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
9675
// Compute reference derivatives
9676
// Declare pointer to array of derivatives on FIAT element
9677
double *derivatives = new double [num_derivatives];
9679
// Declare coefficients
9680
double coeff0_0 = 0;
9681
double coeff0_1 = 0;
9682
double coeff0_2 = 0;
9683
double coeff0_3 = 0;
9684
double coeff0_4 = 0;
9685
double coeff0_5 = 0;
9687
// Declare new coefficients
9688
double new_coeff0_0 = 0;
9689
double new_coeff0_1 = 0;
9690
double new_coeff0_2 = 0;
9691
double new_coeff0_3 = 0;
9692
double new_coeff0_4 = 0;
9693
double new_coeff0_5 = 0;
9695
// Loop possible derivatives
9696
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9698
// Get values from coefficients array
9699
new_coeff0_0 = coefficients0[dof][0];
9700
new_coeff0_1 = coefficients0[dof][1];
9701
new_coeff0_2 = coefficients0[dof][2];
9702
new_coeff0_3 = coefficients0[dof][3];
9703
new_coeff0_4 = coefficients0[dof][4];
9704
new_coeff0_5 = coefficients0[dof][5];
9706
// Loop derivative order
9707
for (unsigned int j = 0; j < n; j++)
9709
// Update old coefficients
9710
coeff0_0 = new_coeff0_0;
9711
coeff0_1 = new_coeff0_1;
9712
coeff0_2 = new_coeff0_2;
9713
coeff0_3 = new_coeff0_3;
9714
coeff0_4 = new_coeff0_4;
9715
coeff0_5 = new_coeff0_5;
9717
if(combinations[deriv_num][j] == 0)
9719
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
9720
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
9721
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
9722
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
9723
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
9724
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
9726
if(combinations[deriv_num][j] == 1)
9728
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
9729
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
9730
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
9731
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
9732
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
9733
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
9737
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9738
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
9741
// Transform derivatives back to physical element
9742
for (unsigned int row = 0; row < num_derivatives; row++)
9744
for (unsigned int col = 0; col < num_derivatives; col++)
9746
values[num_derivatives + row] += transform[row][col]*derivatives[col];
9749
// Delete pointer to array of derivatives on FIAT element
9750
delete [] derivatives;
9752
// Delete pointer to array of combinations of derivatives and transform
9753
for (unsigned int row = 0; row < num_derivatives; row++)
9755
delete [] combinations[row];
9756
delete [] transform[row];
9759
delete [] combinations;
9760
delete [] transform;
9765
/// Evaluate order n derivatives of all basis functions at given point in cell
9766
virtual void evaluate_basis_derivatives_all(unsigned int n,
9768
const double* coordinates,
9769
const ufc::cell& c) const
9771
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9774
/// Evaluate linear functional for dof i on the function f
9775
virtual double evaluate_dof(unsigned int i,
9776
const ufc::function& f,
9777
const ufc::cell& c) const
9779
// The reference points, direction and weights:
9780
static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
9781
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
9782
static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
9784
const double * const * x = c.coordinates;
9785
double result = 0.0;
9786
// Iterate over the points:
9787
// Evaluate basis functions for affine mapping
9788
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9789
const double w1 = X[i][0][0];
9790
const double w2 = X[i][0][1];
9792
// Compute affine mapping y = F(X)
9794
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9795
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9797
// Evaluate function at physical points
9799
f.evaluate(values, y, c);
9801
// Map function values using appropriate mapping
9802
// Affine map: Do nothing
9804
// Note that we do not map the weights (yet).
9806
// Take directional components
9807
for(int k = 0; k < 2; k++)
9808
result += values[k]*D[i][0][k];
9809
// Multiply by weights
9815
/// Evaluate linear functionals for all dofs on the function f
9816
virtual void evaluate_dofs(double* values,
9817
const ufc::function& f,
9818
const ufc::cell& c) const
9820
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9823
/// Interpolate vertex values from dof values
9824
virtual void interpolate_vertex_values(double* vertex_values,
9825
const double* dof_values,
9826
const ufc::cell& c) const
9828
// Evaluate at vertices and use affine mapping
9829
vertex_values[0] = dof_values[0];
9830
vertex_values[2] = dof_values[1];
9831
vertex_values[4] = dof_values[2];
9832
// Evaluate at vertices and use affine mapping
9833
vertex_values[1] = dof_values[6];
9834
vertex_values[3] = dof_values[7];
9835
vertex_values[5] = dof_values[8];
9838
/// Return the number of sub elements (for a mixed element)
9839
virtual unsigned int num_sub_elements() const
9844
/// Create a new finite element for sub element i (for a mixed element)
9845
virtual ufc::finite_element* create_sub_element(unsigned int i) const
9850
return new stokes_1_finite_element_0_0_0();
9853
return new stokes_1_finite_element_0_0_1();
9861
/// This class defines the interface for a finite element.
9863
class stokes_1_finite_element_0_1: public ufc::finite_element
9868
stokes_1_finite_element_0_1() : ufc::finite_element()
9874
virtual ~stokes_1_finite_element_0_1()
9879
/// Return a string identifying the finite element
9880
virtual const char* signature() const
9882
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
9885
/// Return the cell shape
9886
virtual ufc::shape cell_shape() const
9888
return ufc::triangle;
9891
/// Return the dimension of the finite element function space
9892
virtual unsigned int space_dimension() const
9897
/// Return the rank of the value space
9898
virtual unsigned int value_rank() const
9903
/// Return the dimension of the value space for axis i
9904
virtual unsigned int value_dimension(unsigned int i) const
9909
/// Evaluate basis function i at given point in cell
9910
virtual void evaluate_basis(unsigned int i,
9912
const double* coordinates,
9913
const ufc::cell& c) const
9915
// Extract vertex coordinates
9916
const double * const * element_coordinates = c.coordinates;
9918
// Compute Jacobian of affine map from reference cell
9919
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9920
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9921
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9922
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9924
// Compute determinant of Jacobian
9925
const double detJ = J_00*J_11 - J_01*J_10;
9927
// Compute inverse of Jacobian
9929
// Get coordinates and map to the reference (UFC) element
9930
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9931
element_coordinates[0][0]*element_coordinates[2][1] +\
9932
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9933
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9934
element_coordinates[1][0]*element_coordinates[0][1] -\
9935
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9937
// Map coordinates to the reference square
9938
if (std::abs(y - 1.0) < 1e-08)
9941
x = 2.0 *x/(1.0 - y) - 1.0;
9947
// Map degree of freedom to element degree of freedom
9948
const unsigned int dof = i;
9950
// Generate scalings
9951
const double scalings_y_0 = 1;
9952
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9954
// Compute psitilde_a
9955
const double psitilde_a_0 = 1;
9956
const double psitilde_a_1 = x;
9958
// Compute psitilde_bs
9959
const double psitilde_bs_0_0 = 1;
9960
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9961
const double psitilde_bs_1_0 = 1;
9963
// Compute basisvalues
9964
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9965
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9966
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9968
// Table(s) of coefficients
9969
static const double coefficients0[3][3] = \
9970
{{0.471404521, -0.288675135, -0.166666667},
9971
{0.471404521, 0.288675135, -0.166666667},
9972
{0.471404521, 0, 0.333333333}};
9974
// Extract relevant coefficients
9975
const double coeff0_0 = coefficients0[dof][0];
9976
const double coeff0_1 = coefficients0[dof][1];
9977
const double coeff0_2 = coefficients0[dof][2];
9980
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9983
/// Evaluate all basis functions at given point in cell
9984
virtual void evaluate_basis_all(double* values,
9985
const double* coordinates,
9986
const ufc::cell& c) const
9988
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9991
/// Evaluate order n derivatives of basis function i at given point in cell
9992
virtual void evaluate_basis_derivatives(unsigned int i,
9995
const double* coordinates,
9996
const ufc::cell& c) const
9998
// Extract vertex coordinates
9999
const double * const * element_coordinates = c.coordinates;
10001
// Compute Jacobian of affine map from reference cell
10002
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10003
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10004
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10005
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10007
// Compute determinant of Jacobian
10008
const double detJ = J_00*J_11 - J_01*J_10;
10010
// Compute inverse of Jacobian
10012
// Get coordinates and map to the reference (UFC) element
10013
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10014
element_coordinates[0][0]*element_coordinates[2][1] +\
10015
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10016
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10017
element_coordinates[1][0]*element_coordinates[0][1] -\
10018
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10020
// Map coordinates to the reference square
10021
if (std::abs(y - 1.0) < 1e-08)
10024
x = 2.0 *x/(1.0 - y) - 1.0;
10027
// Compute number of derivatives
10028
unsigned int num_derivatives = 1;
10030
for (unsigned int j = 0; j < n; j++)
10031
num_derivatives *= 2;
10034
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10035
unsigned int **combinations = new unsigned int *[num_derivatives];
10037
for (unsigned int j = 0; j < num_derivatives; j++)
10039
combinations[j] = new unsigned int [n];
10040
for (unsigned int k = 0; k < n; k++)
10041
combinations[j][k] = 0;
10044
// Generate combinations of derivatives
10045
for (unsigned int row = 1; row < num_derivatives; row++)
10047
for (unsigned int num = 0; num < row; num++)
10049
for (unsigned int col = n-1; col+1 > 0; col--)
10051
if (combinations[row][col] + 1 > 1)
10052
combinations[row][col] = 0;
10055
combinations[row][col] += 1;
10062
// Compute inverse of Jacobian
10063
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10065
// Declare transformation matrix
10066
// Declare pointer to two dimensional array and initialise
10067
double **transform = new double *[num_derivatives];
10069
for (unsigned int j = 0; j < num_derivatives; j++)
10071
transform[j] = new double [num_derivatives];
10072
for (unsigned int k = 0; k < num_derivatives; k++)
10073
transform[j][k] = 1;
10076
// Construct transformation matrix
10077
for (unsigned int row = 0; row < num_derivatives; row++)
10079
for (unsigned int col = 0; col < num_derivatives; col++)
10081
for (unsigned int k = 0; k < n; k++)
10082
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10087
for (unsigned int j = 0; j < 1*num_derivatives; j++)
10090
// Map degree of freedom to element degree of freedom
10091
const unsigned int dof = i;
10093
// Generate scalings
10094
const double scalings_y_0 = 1;
10095
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10097
// Compute psitilde_a
10098
const double psitilde_a_0 = 1;
10099
const double psitilde_a_1 = x;
10101
// Compute psitilde_bs
10102
const double psitilde_bs_0_0 = 1;
10103
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10104
const double psitilde_bs_1_0 = 1;
10106
// Compute basisvalues
10107
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10108
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10109
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10111
// Table(s) of coefficients
10112
static const double coefficients0[3][3] = \
10113
{{0.471404521, -0.288675135, -0.166666667},
10114
{0.471404521, 0.288675135, -0.166666667},
10115
{0.471404521, 0, 0.333333333}};
10117
// Interesting (new) part
10118
// Tables of derivatives of the polynomial base (transpose)
10119
static const double dmats0[3][3] = \
10121
{4.89897949, 0, 0},
10124
static const double dmats1[3][3] = \
10126
{2.44948974, 0, 0},
10127
{4.24264069, 0, 0}};
10129
// Compute reference derivatives
10130
// Declare pointer to array of derivatives on FIAT element
10131
double *derivatives = new double [num_derivatives];
10133
// Declare coefficients
10134
double coeff0_0 = 0;
10135
double coeff0_1 = 0;
10136
double coeff0_2 = 0;
10138
// Declare new coefficients
10139
double new_coeff0_0 = 0;
10140
double new_coeff0_1 = 0;
10141
double new_coeff0_2 = 0;
10143
// Loop possible derivatives
10144
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10146
// Get values from coefficients array
10147
new_coeff0_0 = coefficients0[dof][0];
10148
new_coeff0_1 = coefficients0[dof][1];
10149
new_coeff0_2 = coefficients0[dof][2];
10151
// Loop derivative order
10152
for (unsigned int j = 0; j < n; j++)
10154
// Update old coefficients
10155
coeff0_0 = new_coeff0_0;
10156
coeff0_1 = new_coeff0_1;
10157
coeff0_2 = new_coeff0_2;
10159
if(combinations[deriv_num][j] == 0)
10161
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10162
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10163
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10165
if(combinations[deriv_num][j] == 1)
10167
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10168
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10169
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10173
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10174
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10177
// Transform derivatives back to physical element
10178
for (unsigned int row = 0; row < num_derivatives; row++)
10180
for (unsigned int col = 0; col < num_derivatives; col++)
10182
values[row] += transform[row][col]*derivatives[col];
10185
// Delete pointer to array of derivatives on FIAT element
10186
delete [] derivatives;
10188
// Delete pointer to array of combinations of derivatives and transform
10189
for (unsigned int row = 0; row < num_derivatives; row++)
10191
delete [] combinations[row];
10192
delete [] transform[row];
10195
delete [] combinations;
10196
delete [] transform;
10199
/// Evaluate order n derivatives of all basis functions at given point in cell
10200
virtual void evaluate_basis_derivatives_all(unsigned int n,
10202
const double* coordinates,
10203
const ufc::cell& c) const
10205
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
10208
/// Evaluate linear functional for dof i on the function f
10209
virtual double evaluate_dof(unsigned int i,
10210
const ufc::function& f,
10211
const ufc::cell& c) const
10213
// The reference points, direction and weights:
10214
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
10215
static const double W[3][1] = {{1}, {1}, {1}};
10216
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
10218
const double * const * x = c.coordinates;
10219
double result = 0.0;
10220
// Iterate over the points:
10221
// Evaluate basis functions for affine mapping
10222
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
10223
const double w1 = X[i][0][0];
10224
const double w2 = X[i][0][1];
10226
// Compute affine mapping y = F(X)
10228
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
10229
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
10231
// Evaluate function at physical points
10233
f.evaluate(values, y, c);
10235
// Map function values using appropriate mapping
10236
// Affine map: Do nothing
10238
// Note that we do not map the weights (yet).
10240
// Take directional components
10241
for(int k = 0; k < 1; k++)
10242
result += values[k]*D[i][0][k];
10243
// Multiply by weights
10249
/// Evaluate linear functionals for all dofs on the function f
10250
virtual void evaluate_dofs(double* values,
10251
const ufc::function& f,
10252
const ufc::cell& c) const
10254
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10257
/// Interpolate vertex values from dof values
10258
virtual void interpolate_vertex_values(double* vertex_values,
10259
const double* dof_values,
10260
const ufc::cell& c) const
10262
// Evaluate at vertices and use affine mapping
10263
vertex_values[0] = dof_values[0];
10264
vertex_values[1] = dof_values[1];
10265
vertex_values[2] = dof_values[2];
10268
/// Return the number of sub elements (for a mixed element)
10269
virtual unsigned int num_sub_elements() const
10274
/// Create a new finite element for sub element i (for a mixed element)
10275
virtual ufc::finite_element* create_sub_element(unsigned int i) const
10277
return new stokes_1_finite_element_0_1();
10282
/// This class defines the interface for a finite element.
10284
class stokes_1_finite_element_0: public ufc::finite_element
10289
stokes_1_finite_element_0() : ufc::finite_element()
10295
virtual ~stokes_1_finite_element_0()
10300
/// Return a string identifying the finite element
10301
virtual const char* signature() const
10303
return "MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) })";
10306
/// Return the cell shape
10307
virtual ufc::shape cell_shape() const
10309
return ufc::triangle;
10312
/// Return the dimension of the finite element function space
10313
virtual unsigned int space_dimension() const
10318
/// Return the rank of the value space
10319
virtual unsigned int value_rank() const
10324
/// Return the dimension of the value space for axis i
10325
virtual unsigned int value_dimension(unsigned int i) const
10330
/// Evaluate basis function i at given point in cell
10331
virtual void evaluate_basis(unsigned int i,
10333
const double* coordinates,
10334
const ufc::cell& c) const
10336
// Extract vertex coordinates
10337
const double * const * element_coordinates = c.coordinates;
10339
// Compute Jacobian of affine map from reference cell
10340
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10341
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10342
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10343
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10345
// Compute determinant of Jacobian
10346
const double detJ = J_00*J_11 - J_01*J_10;
10348
// Compute inverse of Jacobian
10350
// Get coordinates and map to the reference (UFC) element
10351
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10352
element_coordinates[0][0]*element_coordinates[2][1] +\
10353
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10354
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10355
element_coordinates[1][0]*element_coordinates[0][1] -\
10356
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10358
// Map coordinates to the reference square
10359
if (std::abs(y - 1.0) < 1e-08)
10362
x = 2.0 *x/(1.0 - y) - 1.0;
10370
if (0 <= i && i <= 5)
10372
// Map degree of freedom to element degree of freedom
10373
const unsigned int dof = i;
10375
// Generate scalings
10376
const double scalings_y_0 = 1;
10377
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10378
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
10380
// Compute psitilde_a
10381
const double psitilde_a_0 = 1;
10382
const double psitilde_a_1 = x;
10383
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
10385
// Compute psitilde_bs
10386
const double psitilde_bs_0_0 = 1;
10387
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10388
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
10389
const double psitilde_bs_1_0 = 1;
10390
const double psitilde_bs_1_1 = 2.5*y + 1.5;
10391
const double psitilde_bs_2_0 = 1;
10393
// Compute basisvalues
10394
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10395
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10396
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10397
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
10398
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
10399
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
10401
// Table(s) of coefficients
10402
static const double coefficients0[6][6] = \
10403
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
10404
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
10405
{0, 0, 0.2, 0, 0, 0.163299316},
10406
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
10407
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
10408
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
10410
// Extract relevant coefficients
10411
const double coeff0_0 = coefficients0[dof][0];
10412
const double coeff0_1 = coefficients0[dof][1];
10413
const double coeff0_2 = coefficients0[dof][2];
10414
const double coeff0_3 = coefficients0[dof][3];
10415
const double coeff0_4 = coefficients0[dof][4];
10416
const double coeff0_5 = coefficients0[dof][5];
10418
// Compute value(s)
10419
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
10422
if (6 <= i && i <= 11)
10424
// Map degree of freedom to element degree of freedom
10425
const unsigned int dof = i - 6;
10427
// Generate scalings
10428
const double scalings_y_0 = 1;
10429
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10430
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
10432
// Compute psitilde_a
10433
const double psitilde_a_0 = 1;
10434
const double psitilde_a_1 = x;
10435
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
10437
// Compute psitilde_bs
10438
const double psitilde_bs_0_0 = 1;
10439
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10440
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
10441
const double psitilde_bs_1_0 = 1;
10442
const double psitilde_bs_1_1 = 2.5*y + 1.5;
10443
const double psitilde_bs_2_0 = 1;
10445
// Compute basisvalues
10446
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10447
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10448
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10449
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
10450
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
10451
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
10453
// Table(s) of coefficients
10454
static const double coefficients0[6][6] = \
10455
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
10456
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
10457
{0, 0, 0.2, 0, 0, 0.163299316},
10458
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
10459
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
10460
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
10462
// Extract relevant coefficients
10463
const double coeff0_0 = coefficients0[dof][0];
10464
const double coeff0_1 = coefficients0[dof][1];
10465
const double coeff0_2 = coefficients0[dof][2];
10466
const double coeff0_3 = coefficients0[dof][3];
10467
const double coeff0_4 = coefficients0[dof][4];
10468
const double coeff0_5 = coefficients0[dof][5];
10470
// Compute value(s)
10471
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
10474
if (12 <= i && i <= 14)
10476
// Map degree of freedom to element degree of freedom
10477
const unsigned int dof = i - 12;
10479
// Generate scalings
10480
const double scalings_y_0 = 1;
10481
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10483
// Compute psitilde_a
10484
const double psitilde_a_0 = 1;
10485
const double psitilde_a_1 = x;
10487
// Compute psitilde_bs
10488
const double psitilde_bs_0_0 = 1;
10489
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10490
const double psitilde_bs_1_0 = 1;
10492
// Compute basisvalues
10493
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10494
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10495
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10497
// Table(s) of coefficients
10498
static const double coefficients0[3][3] = \
10499
{{0.471404521, -0.288675135, -0.166666667},
10500
{0.471404521, 0.288675135, -0.166666667},
10501
{0.471404521, 0, 0.333333333}};
10503
// Extract relevant coefficients
10504
const double coeff0_0 = coefficients0[dof][0];
10505
const double coeff0_1 = coefficients0[dof][1];
10506
const double coeff0_2 = coefficients0[dof][2];
10508
// Compute value(s)
10509
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10514
/// Evaluate all basis functions at given point in cell
10515
virtual void evaluate_basis_all(double* values,
10516
const double* coordinates,
10517
const ufc::cell& c) const
10519
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
10522
/// Evaluate order n derivatives of basis function i at given point in cell
10523
virtual void evaluate_basis_derivatives(unsigned int i,
10526
const double* coordinates,
10527
const ufc::cell& c) const
10529
// Extract vertex coordinates
10530
const double * const * element_coordinates = c.coordinates;
10532
// Compute Jacobian of affine map from reference cell
10533
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10534
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10535
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10536
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10538
// Compute determinant of Jacobian
10539
const double detJ = J_00*J_11 - J_01*J_10;
10541
// Compute inverse of Jacobian
10543
// Get coordinates and map to the reference (UFC) element
10544
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10545
element_coordinates[0][0]*element_coordinates[2][1] +\
10546
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10547
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10548
element_coordinates[1][0]*element_coordinates[0][1] -\
10549
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10551
// Map coordinates to the reference square
10552
if (std::abs(y - 1.0) < 1e-08)
10555
x = 2.0 *x/(1.0 - y) - 1.0;
10558
// Compute number of derivatives
10559
unsigned int num_derivatives = 1;
10561
for (unsigned int j = 0; j < n; j++)
10562
num_derivatives *= 2;
10565
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10566
unsigned int **combinations = new unsigned int *[num_derivatives];
10568
for (unsigned int j = 0; j < num_derivatives; j++)
10570
combinations[j] = new unsigned int [n];
10571
for (unsigned int k = 0; k < n; k++)
10572
combinations[j][k] = 0;
10575
// Generate combinations of derivatives
10576
for (unsigned int row = 1; row < num_derivatives; row++)
10578
for (unsigned int num = 0; num < row; num++)
10580
for (unsigned int col = n-1; col+1 > 0; col--)
10582
if (combinations[row][col] + 1 > 1)
10583
combinations[row][col] = 0;
10586
combinations[row][col] += 1;
10593
// Compute inverse of Jacobian
10594
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10596
// Declare transformation matrix
10597
// Declare pointer to two dimensional array and initialise
10598
double **transform = new double *[num_derivatives];
10600
for (unsigned int j = 0; j < num_derivatives; j++)
10602
transform[j] = new double [num_derivatives];
10603
for (unsigned int k = 0; k < num_derivatives; k++)
10604
transform[j][k] = 1;
10607
// Construct transformation matrix
10608
for (unsigned int row = 0; row < num_derivatives; row++)
10610
for (unsigned int col = 0; col < num_derivatives; col++)
10612
for (unsigned int k = 0; k < n; k++)
10613
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10618
for (unsigned int j = 0; j < 3*num_derivatives; j++)
10621
if (0 <= i && i <= 5)
10623
// Map degree of freedom to element degree of freedom
10624
const unsigned int dof = i;
10626
// Generate scalings
10627
const double scalings_y_0 = 1;
10628
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10629
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
10631
// Compute psitilde_a
10632
const double psitilde_a_0 = 1;
10633
const double psitilde_a_1 = x;
10634
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
10636
// Compute psitilde_bs
10637
const double psitilde_bs_0_0 = 1;
10638
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10639
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
10640
const double psitilde_bs_1_0 = 1;
10641
const double psitilde_bs_1_1 = 2.5*y + 1.5;
10642
const double psitilde_bs_2_0 = 1;
10644
// Compute basisvalues
10645
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10646
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10647
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10648
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
10649
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
10650
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
10652
// Table(s) of coefficients
10653
static const double coefficients0[6][6] = \
10654
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
10655
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
10656
{0, 0, 0.2, 0, 0, 0.163299316},
10657
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
10658
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
10659
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
10661
// Interesting (new) part
10662
// Tables of derivatives of the polynomial base (transpose)
10663
static const double dmats0[6][6] = \
10664
{{0, 0, 0, 0, 0, 0},
10665
{4.89897949, 0, 0, 0, 0, 0},
10666
{0, 0, 0, 0, 0, 0},
10667
{0, 9.48683298, 0, 0, 0, 0},
10668
{4, 0, 7.07106781, 0, 0, 0},
10669
{0, 0, 0, 0, 0, 0}};
10671
static const double dmats1[6][6] = \
10672
{{0, 0, 0, 0, 0, 0},
10673
{2.44948974, 0, 0, 0, 0, 0},
10674
{4.24264069, 0, 0, 0, 0, 0},
10675
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
10676
{2, 6.12372436, 3.53553391, 0, 0, 0},
10677
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
10679
// Compute reference derivatives
10680
// Declare pointer to array of derivatives on FIAT element
10681
double *derivatives = new double [num_derivatives];
10683
// Declare coefficients
10684
double coeff0_0 = 0;
10685
double coeff0_1 = 0;
10686
double coeff0_2 = 0;
10687
double coeff0_3 = 0;
10688
double coeff0_4 = 0;
10689
double coeff0_5 = 0;
10691
// Declare new coefficients
10692
double new_coeff0_0 = 0;
10693
double new_coeff0_1 = 0;
10694
double new_coeff0_2 = 0;
10695
double new_coeff0_3 = 0;
10696
double new_coeff0_4 = 0;
10697
double new_coeff0_5 = 0;
10699
// Loop possible derivatives
10700
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10702
// Get values from coefficients array
10703
new_coeff0_0 = coefficients0[dof][0];
10704
new_coeff0_1 = coefficients0[dof][1];
10705
new_coeff0_2 = coefficients0[dof][2];
10706
new_coeff0_3 = coefficients0[dof][3];
10707
new_coeff0_4 = coefficients0[dof][4];
10708
new_coeff0_5 = coefficients0[dof][5];
10710
// Loop derivative order
10711
for (unsigned int j = 0; j < n; j++)
10713
// Update old coefficients
10714
coeff0_0 = new_coeff0_0;
10715
coeff0_1 = new_coeff0_1;
10716
coeff0_2 = new_coeff0_2;
10717
coeff0_3 = new_coeff0_3;
10718
coeff0_4 = new_coeff0_4;
10719
coeff0_5 = new_coeff0_5;
10721
if(combinations[deriv_num][j] == 0)
10723
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
10724
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
10725
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
10726
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
10727
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
10728
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
10730
if(combinations[deriv_num][j] == 1)
10732
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
10733
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
10734
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
10735
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
10736
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
10737
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
10741
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10742
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
10745
// Transform derivatives back to physical element
10746
for (unsigned int row = 0; row < num_derivatives; row++)
10748
for (unsigned int col = 0; col < num_derivatives; col++)
10750
values[row] += transform[row][col]*derivatives[col];
10753
// Delete pointer to array of derivatives on FIAT element
10754
delete [] derivatives;
10756
// Delete pointer to array of combinations of derivatives and transform
10757
for (unsigned int row = 0; row < num_derivatives; row++)
10759
delete [] combinations[row];
10760
delete [] transform[row];
10763
delete [] combinations;
10764
delete [] transform;
10767
if (6 <= i && i <= 11)
10769
// Map degree of freedom to element degree of freedom
10770
const unsigned int dof = i - 6;
10772
// Generate scalings
10773
const double scalings_y_0 = 1;
10774
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10775
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
10777
// Compute psitilde_a
10778
const double psitilde_a_0 = 1;
10779
const double psitilde_a_1 = x;
10780
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
10782
// Compute psitilde_bs
10783
const double psitilde_bs_0_0 = 1;
10784
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10785
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
10786
const double psitilde_bs_1_0 = 1;
10787
const double psitilde_bs_1_1 = 2.5*y + 1.5;
10788
const double psitilde_bs_2_0 = 1;
10790
// Compute basisvalues
10791
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10792
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10793
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10794
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
10795
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
10796
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
10798
// Table(s) of coefficients
10799
static const double coefficients0[6][6] = \
10800
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
10801
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
10802
{0, 0, 0.2, 0, 0, 0.163299316},
10803
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
10804
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
10805
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
10807
// Interesting (new) part
10808
// Tables of derivatives of the polynomial base (transpose)
10809
static const double dmats0[6][6] = \
10810
{{0, 0, 0, 0, 0, 0},
10811
{4.89897949, 0, 0, 0, 0, 0},
10812
{0, 0, 0, 0, 0, 0},
10813
{0, 9.48683298, 0, 0, 0, 0},
10814
{4, 0, 7.07106781, 0, 0, 0},
10815
{0, 0, 0, 0, 0, 0}};
10817
static const double dmats1[6][6] = \
10818
{{0, 0, 0, 0, 0, 0},
10819
{2.44948974, 0, 0, 0, 0, 0},
10820
{4.24264069, 0, 0, 0, 0, 0},
10821
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
10822
{2, 6.12372436, 3.53553391, 0, 0, 0},
10823
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
10825
// Compute reference derivatives
10826
// Declare pointer to array of derivatives on FIAT element
10827
double *derivatives = new double [num_derivatives];
10829
// Declare coefficients
10830
double coeff0_0 = 0;
10831
double coeff0_1 = 0;
10832
double coeff0_2 = 0;
10833
double coeff0_3 = 0;
10834
double coeff0_4 = 0;
10835
double coeff0_5 = 0;
10837
// Declare new coefficients
10838
double new_coeff0_0 = 0;
10839
double new_coeff0_1 = 0;
10840
double new_coeff0_2 = 0;
10841
double new_coeff0_3 = 0;
10842
double new_coeff0_4 = 0;
10843
double new_coeff0_5 = 0;
10845
// Loop possible derivatives
10846
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10848
// Get values from coefficients array
10849
new_coeff0_0 = coefficients0[dof][0];
10850
new_coeff0_1 = coefficients0[dof][1];
10851
new_coeff0_2 = coefficients0[dof][2];
10852
new_coeff0_3 = coefficients0[dof][3];
10853
new_coeff0_4 = coefficients0[dof][4];
10854
new_coeff0_5 = coefficients0[dof][5];
10856
// Loop derivative order
10857
for (unsigned int j = 0; j < n; j++)
10859
// Update old coefficients
10860
coeff0_0 = new_coeff0_0;
10861
coeff0_1 = new_coeff0_1;
10862
coeff0_2 = new_coeff0_2;
10863
coeff0_3 = new_coeff0_3;
10864
coeff0_4 = new_coeff0_4;
10865
coeff0_5 = new_coeff0_5;
10867
if(combinations[deriv_num][j] == 0)
10869
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
10870
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
10871
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
10872
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
10873
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
10874
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
10876
if(combinations[deriv_num][j] == 1)
10878
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
10879
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
10880
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
10881
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
10882
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
10883
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
10887
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10888
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
10891
// Transform derivatives back to physical element
10892
for (unsigned int row = 0; row < num_derivatives; row++)
10894
for (unsigned int col = 0; col < num_derivatives; col++)
10896
values[num_derivatives + row] += transform[row][col]*derivatives[col];
10899
// Delete pointer to array of derivatives on FIAT element
10900
delete [] derivatives;
10902
// Delete pointer to array of combinations of derivatives and transform
10903
for (unsigned int row = 0; row < num_derivatives; row++)
10905
delete [] combinations[row];
10906
delete [] transform[row];
10909
delete [] combinations;
10910
delete [] transform;
10913
if (12 <= i && i <= 14)
10915
// Map degree of freedom to element degree of freedom
10916
const unsigned int dof = i - 12;
10918
// Generate scalings
10919
const double scalings_y_0 = 1;
10920
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10922
// Compute psitilde_a
10923
const double psitilde_a_0 = 1;
10924
const double psitilde_a_1 = x;
10926
// Compute psitilde_bs
10927
const double psitilde_bs_0_0 = 1;
10928
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10929
const double psitilde_bs_1_0 = 1;
10931
// Compute basisvalues
10932
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10933
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10934
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10936
// Table(s) of coefficients
10937
static const double coefficients0[3][3] = \
10938
{{0.471404521, -0.288675135, -0.166666667},
10939
{0.471404521, 0.288675135, -0.166666667},
10940
{0.471404521, 0, 0.333333333}};
10942
// Interesting (new) part
10943
// Tables of derivatives of the polynomial base (transpose)
10944
static const double dmats0[3][3] = \
10946
{4.89897949, 0, 0},
10949
static const double dmats1[3][3] = \
10951
{2.44948974, 0, 0},
10952
{4.24264069, 0, 0}};
10954
// Compute reference derivatives
10955
// Declare pointer to array of derivatives on FIAT element
10956
double *derivatives = new double [num_derivatives];
10958
// Declare coefficients
10959
double coeff0_0 = 0;
10960
double coeff0_1 = 0;
10961
double coeff0_2 = 0;
10963
// Declare new coefficients
10964
double new_coeff0_0 = 0;
10965
double new_coeff0_1 = 0;
10966
double new_coeff0_2 = 0;
10968
// Loop possible derivatives
10969
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10971
// Get values from coefficients array
10972
new_coeff0_0 = coefficients0[dof][0];
10973
new_coeff0_1 = coefficients0[dof][1];
10974
new_coeff0_2 = coefficients0[dof][2];
10976
// Loop derivative order
10977
for (unsigned int j = 0; j < n; j++)
10979
// Update old coefficients
10980
coeff0_0 = new_coeff0_0;
10981
coeff0_1 = new_coeff0_1;
10982
coeff0_2 = new_coeff0_2;
10984
if(combinations[deriv_num][j] == 0)
10986
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10987
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10988
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10990
if(combinations[deriv_num][j] == 1)
10992
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10993
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10994
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10998
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10999
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
11002
// Transform derivatives back to physical element
11003
for (unsigned int row = 0; row < num_derivatives; row++)
11005
for (unsigned int col = 0; col < num_derivatives; col++)
11007
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
11010
// Delete pointer to array of derivatives on FIAT element
11011
delete [] derivatives;
11013
// Delete pointer to array of combinations of derivatives and transform
11014
for (unsigned int row = 0; row < num_derivatives; row++)
11016
delete [] combinations[row];
11017
delete [] transform[row];
11020
delete [] combinations;
11021
delete [] transform;
11026
/// Evaluate order n derivatives of all basis functions at given point in cell
11027
virtual void evaluate_basis_derivatives_all(unsigned int n,
11029
const double* coordinates,
11030
const ufc::cell& c) const
11032
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11035
/// Evaluate linear functional for dof i on the function f
11036
virtual double evaluate_dof(unsigned int i,
11037
const ufc::function& f,
11038
const ufc::cell& c) const
11040
// The reference points, direction and weights:
11041
static const double X[15][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
11042
static const double W[15][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
11043
static const double D[15][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
11045
const double * const * x = c.coordinates;
11046
double result = 0.0;
11047
// Iterate over the points:
11048
// Evaluate basis functions for affine mapping
11049
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11050
const double w1 = X[i][0][0];
11051
const double w2 = X[i][0][1];
11053
// Compute affine mapping y = F(X)
11055
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11056
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11058
// Evaluate function at physical points
11060
f.evaluate(values, y, c);
11062
// Map function values using appropriate mapping
11063
// Affine map: Do nothing
11065
// Note that we do not map the weights (yet).
11067
// Take directional components
11068
for(int k = 0; k < 3; k++)
11069
result += values[k]*D[i][0][k];
11070
// Multiply by weights
11076
/// Evaluate linear functionals for all dofs on the function f
11077
virtual void evaluate_dofs(double* values,
11078
const ufc::function& f,
11079
const ufc::cell& c) const
11081
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11084
/// Interpolate vertex values from dof values
11085
virtual void interpolate_vertex_values(double* vertex_values,
11086
const double* dof_values,
11087
const ufc::cell& c) const
11089
// Evaluate at vertices and use affine mapping
11090
vertex_values[0] = dof_values[0];
11091
vertex_values[3] = dof_values[1];
11092
vertex_values[6] = dof_values[2];
11093
// Evaluate at vertices and use affine mapping
11094
vertex_values[1] = dof_values[6];
11095
vertex_values[4] = dof_values[7];
11096
vertex_values[7] = dof_values[8];
11097
// Evaluate at vertices and use affine mapping
11098
vertex_values[2] = dof_values[12];
11099
vertex_values[5] = dof_values[13];
11100
vertex_values[8] = dof_values[14];
11103
/// Return the number of sub elements (for a mixed element)
11104
virtual unsigned int num_sub_elements() const
11109
/// Create a new finite element for sub element i (for a mixed element)
11110
virtual ufc::finite_element* create_sub_element(unsigned int i) const
11115
return new stokes_1_finite_element_0_0();
11118
return new stokes_1_finite_element_0_1();
11126
/// This class defines the interface for a finite element.
11128
class stokes_1_finite_element_1_0: public ufc::finite_element
11133
stokes_1_finite_element_1_0() : ufc::finite_element()
11139
virtual ~stokes_1_finite_element_1_0()
11144
/// Return a string identifying the finite element
11145
virtual const char* signature() const
11147
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
11150
/// Return the cell shape
11151
virtual ufc::shape cell_shape() const
11153
return ufc::triangle;
11156
/// Return the dimension of the finite element function space
11157
virtual unsigned int space_dimension() const
11162
/// Return the rank of the value space
11163
virtual unsigned int value_rank() const
11168
/// Return the dimension of the value space for axis i
11169
virtual unsigned int value_dimension(unsigned int i) const
11174
/// Evaluate basis function i at given point in cell
11175
virtual void evaluate_basis(unsigned int i,
11177
const double* coordinates,
11178
const ufc::cell& c) const
11180
// Extract vertex coordinates
11181
const double * const * element_coordinates = c.coordinates;
11183
// Compute Jacobian of affine map from reference cell
11184
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11185
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11186
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11187
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11189
// Compute determinant of Jacobian
11190
const double detJ = J_00*J_11 - J_01*J_10;
11192
// Compute inverse of Jacobian
11194
// Get coordinates and map to the reference (UFC) element
11195
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11196
element_coordinates[0][0]*element_coordinates[2][1] +\
11197
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11198
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11199
element_coordinates[1][0]*element_coordinates[0][1] -\
11200
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11202
// Map coordinates to the reference square
11203
if (std::abs(y - 1.0) < 1e-08)
11206
x = 2.0 *x/(1.0 - y) - 1.0;
11212
// Map degree of freedom to element degree of freedom
11213
const unsigned int dof = i;
11215
// Generate scalings
11216
const double scalings_y_0 = 1;
11217
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11218
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
11220
// Compute psitilde_a
11221
const double psitilde_a_0 = 1;
11222
const double psitilde_a_1 = x;
11223
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
11225
// Compute psitilde_bs
11226
const double psitilde_bs_0_0 = 1;
11227
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11228
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
11229
const double psitilde_bs_1_0 = 1;
11230
const double psitilde_bs_1_1 = 2.5*y + 1.5;
11231
const double psitilde_bs_2_0 = 1;
11233
// Compute basisvalues
11234
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11235
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11236
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11237
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
11238
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
11239
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
11241
// Table(s) of coefficients
11242
static const double coefficients0[6][6] = \
11243
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
11244
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
11245
{0, 0, 0.2, 0, 0, 0.163299316},
11246
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
11247
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
11248
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
11250
// Extract relevant coefficients
11251
const double coeff0_0 = coefficients0[dof][0];
11252
const double coeff0_1 = coefficients0[dof][1];
11253
const double coeff0_2 = coefficients0[dof][2];
11254
const double coeff0_3 = coefficients0[dof][3];
11255
const double coeff0_4 = coefficients0[dof][4];
11256
const double coeff0_5 = coefficients0[dof][5];
11258
// Compute value(s)
11259
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
11262
/// Evaluate all basis functions at given point in cell
11263
virtual void evaluate_basis_all(double* values,
11264
const double* coordinates,
11265
const ufc::cell& c) const
11267
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11270
/// Evaluate order n derivatives of basis function i at given point in cell
11271
virtual void evaluate_basis_derivatives(unsigned int i,
11274
const double* coordinates,
11275
const ufc::cell& c) const
11277
// Extract vertex coordinates
11278
const double * const * element_coordinates = c.coordinates;
11280
// Compute Jacobian of affine map from reference cell
11281
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11282
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11283
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11284
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11286
// Compute determinant of Jacobian
11287
const double detJ = J_00*J_11 - J_01*J_10;
11289
// Compute inverse of Jacobian
11291
// Get coordinates and map to the reference (UFC) element
11292
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11293
element_coordinates[0][0]*element_coordinates[2][1] +\
11294
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11295
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11296
element_coordinates[1][0]*element_coordinates[0][1] -\
11297
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11299
// Map coordinates to the reference square
11300
if (std::abs(y - 1.0) < 1e-08)
11303
x = 2.0 *x/(1.0 - y) - 1.0;
11306
// Compute number of derivatives
11307
unsigned int num_derivatives = 1;
11309
for (unsigned int j = 0; j < n; j++)
11310
num_derivatives *= 2;
11313
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11314
unsigned int **combinations = new unsigned int *[num_derivatives];
11316
for (unsigned int j = 0; j < num_derivatives; j++)
11318
combinations[j] = new unsigned int [n];
11319
for (unsigned int k = 0; k < n; k++)
11320
combinations[j][k] = 0;
11323
// Generate combinations of derivatives
11324
for (unsigned int row = 1; row < num_derivatives; row++)
11326
for (unsigned int num = 0; num < row; num++)
11328
for (unsigned int col = n-1; col+1 > 0; col--)
11330
if (combinations[row][col] + 1 > 1)
11331
combinations[row][col] = 0;
11334
combinations[row][col] += 1;
11341
// Compute inverse of Jacobian
11342
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11344
// Declare transformation matrix
11345
// Declare pointer to two dimensional array and initialise
11346
double **transform = new double *[num_derivatives];
11348
for (unsigned int j = 0; j < num_derivatives; j++)
11350
transform[j] = new double [num_derivatives];
11351
for (unsigned int k = 0; k < num_derivatives; k++)
11352
transform[j][k] = 1;
11355
// Construct transformation matrix
11356
for (unsigned int row = 0; row < num_derivatives; row++)
11358
for (unsigned int col = 0; col < num_derivatives; col++)
11360
for (unsigned int k = 0; k < n; k++)
11361
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11366
for (unsigned int j = 0; j < 1*num_derivatives; j++)
11369
// Map degree of freedom to element degree of freedom
11370
const unsigned int dof = i;
11372
// Generate scalings
11373
const double scalings_y_0 = 1;
11374
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11375
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
11377
// Compute psitilde_a
11378
const double psitilde_a_0 = 1;
11379
const double psitilde_a_1 = x;
11380
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
11382
// Compute psitilde_bs
11383
const double psitilde_bs_0_0 = 1;
11384
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11385
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
11386
const double psitilde_bs_1_0 = 1;
11387
const double psitilde_bs_1_1 = 2.5*y + 1.5;
11388
const double psitilde_bs_2_0 = 1;
11390
// Compute basisvalues
11391
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11392
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11393
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11394
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
11395
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
11396
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
11398
// Table(s) of coefficients
11399
static const double coefficients0[6][6] = \
11400
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
11401
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
11402
{0, 0, 0.2, 0, 0, 0.163299316},
11403
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
11404
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
11405
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
11407
// Interesting (new) part
11408
// Tables of derivatives of the polynomial base (transpose)
11409
static const double dmats0[6][6] = \
11410
{{0, 0, 0, 0, 0, 0},
11411
{4.89897949, 0, 0, 0, 0, 0},
11412
{0, 0, 0, 0, 0, 0},
11413
{0, 9.48683298, 0, 0, 0, 0},
11414
{4, 0, 7.07106781, 0, 0, 0},
11415
{0, 0, 0, 0, 0, 0}};
11417
static const double dmats1[6][6] = \
11418
{{0, 0, 0, 0, 0, 0},
11419
{2.44948974, 0, 0, 0, 0, 0},
11420
{4.24264069, 0, 0, 0, 0, 0},
11421
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
11422
{2, 6.12372436, 3.53553391, 0, 0, 0},
11423
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
11425
// Compute reference derivatives
11426
// Declare pointer to array of derivatives on FIAT element
11427
double *derivatives = new double [num_derivatives];
11429
// Declare coefficients
11430
double coeff0_0 = 0;
11431
double coeff0_1 = 0;
11432
double coeff0_2 = 0;
11433
double coeff0_3 = 0;
11434
double coeff0_4 = 0;
11435
double coeff0_5 = 0;
11437
// Declare new coefficients
11438
double new_coeff0_0 = 0;
11439
double new_coeff0_1 = 0;
11440
double new_coeff0_2 = 0;
11441
double new_coeff0_3 = 0;
11442
double new_coeff0_4 = 0;
11443
double new_coeff0_5 = 0;
11445
// Loop possible derivatives
11446
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11448
// Get values from coefficients array
11449
new_coeff0_0 = coefficients0[dof][0];
11450
new_coeff0_1 = coefficients0[dof][1];
11451
new_coeff0_2 = coefficients0[dof][2];
11452
new_coeff0_3 = coefficients0[dof][3];
11453
new_coeff0_4 = coefficients0[dof][4];
11454
new_coeff0_5 = coefficients0[dof][5];
11456
// Loop derivative order
11457
for (unsigned int j = 0; j < n; j++)
11459
// Update old coefficients
11460
coeff0_0 = new_coeff0_0;
11461
coeff0_1 = new_coeff0_1;
11462
coeff0_2 = new_coeff0_2;
11463
coeff0_3 = new_coeff0_3;
11464
coeff0_4 = new_coeff0_4;
11465
coeff0_5 = new_coeff0_5;
11467
if(combinations[deriv_num][j] == 0)
11469
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
11470
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
11471
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
11472
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
11473
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
11474
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
11476
if(combinations[deriv_num][j] == 1)
11478
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
11479
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
11480
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
11481
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
11482
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
11483
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
11487
// Compute derivatives on reference element as dot product of coefficients and basisvalues
11488
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
11491
// Transform derivatives back to physical element
11492
for (unsigned int row = 0; row < num_derivatives; row++)
11494
for (unsigned int col = 0; col < num_derivatives; col++)
11496
values[row] += transform[row][col]*derivatives[col];
11499
// Delete pointer to array of derivatives on FIAT element
11500
delete [] derivatives;
11502
// Delete pointer to array of combinations of derivatives and transform
11503
for (unsigned int row = 0; row < num_derivatives; row++)
11505
delete [] combinations[row];
11506
delete [] transform[row];
11509
delete [] combinations;
11510
delete [] transform;
11513
/// Evaluate order n derivatives of all basis functions at given point in cell
11514
virtual void evaluate_basis_derivatives_all(unsigned int n,
11516
const double* coordinates,
11517
const ufc::cell& c) const
11519
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11522
/// Evaluate linear functional for dof i on the function f
11523
virtual double evaluate_dof(unsigned int i,
11524
const ufc::function& f,
11525
const ufc::cell& c) const
11527
// The reference points, direction and weights:
11528
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
11529
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
11530
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
11532
const double * const * x = c.coordinates;
11533
double result = 0.0;
11534
// Iterate over the points:
11535
// Evaluate basis functions for affine mapping
11536
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11537
const double w1 = X[i][0][0];
11538
const double w2 = X[i][0][1];
11540
// Compute affine mapping y = F(X)
11542
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11543
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11545
// Evaluate function at physical points
11547
f.evaluate(values, y, c);
11549
// Map function values using appropriate mapping
11550
// Affine map: Do nothing
11552
// Note that we do not map the weights (yet).
11554
// Take directional components
11555
for(int k = 0; k < 1; k++)
11556
result += values[k]*D[i][0][k];
11557
// Multiply by weights
11563
/// Evaluate linear functionals for all dofs on the function f
11564
virtual void evaluate_dofs(double* values,
11565
const ufc::function& f,
11566
const ufc::cell& c) const
11568
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11571
/// Interpolate vertex values from dof values
11572
virtual void interpolate_vertex_values(double* vertex_values,
11573
const double* dof_values,
11574
const ufc::cell& c) const
11576
// Evaluate at vertices and use affine mapping
11577
vertex_values[0] = dof_values[0];
11578
vertex_values[1] = dof_values[1];
11579
vertex_values[2] = dof_values[2];
11582
/// Return the number of sub elements (for a mixed element)
11583
virtual unsigned int num_sub_elements() const
11588
/// Create a new finite element for sub element i (for a mixed element)
11589
virtual ufc::finite_element* create_sub_element(unsigned int i) const
11591
return new stokes_1_finite_element_1_0();
11596
/// This class defines the interface for a finite element.
11598
class stokes_1_finite_element_1_1: public ufc::finite_element
11603
stokes_1_finite_element_1_1() : ufc::finite_element()
11609
virtual ~stokes_1_finite_element_1_1()
11614
/// Return a string identifying the finite element
11615
virtual const char* signature() const
11617
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
11620
/// Return the cell shape
11621
virtual ufc::shape cell_shape() const
11623
return ufc::triangle;
11626
/// Return the dimension of the finite element function space
11627
virtual unsigned int space_dimension() const
11632
/// Return the rank of the value space
11633
virtual unsigned int value_rank() const
11638
/// Return the dimension of the value space for axis i
11639
virtual unsigned int value_dimension(unsigned int i) const
11644
/// Evaluate basis function i at given point in cell
11645
virtual void evaluate_basis(unsigned int i,
11647
const double* coordinates,
11648
const ufc::cell& c) const
11650
// Extract vertex coordinates
11651
const double * const * element_coordinates = c.coordinates;
11653
// Compute Jacobian of affine map from reference cell
11654
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11655
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11656
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11657
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11659
// Compute determinant of Jacobian
11660
const double detJ = J_00*J_11 - J_01*J_10;
11662
// Compute inverse of Jacobian
11664
// Get coordinates and map to the reference (UFC) element
11665
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11666
element_coordinates[0][0]*element_coordinates[2][1] +\
11667
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11668
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11669
element_coordinates[1][0]*element_coordinates[0][1] -\
11670
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11672
// Map coordinates to the reference square
11673
if (std::abs(y - 1.0) < 1e-08)
11676
x = 2.0 *x/(1.0 - y) - 1.0;
11682
// Map degree of freedom to element degree of freedom
11683
const unsigned int dof = i;
11685
// Generate scalings
11686
const double scalings_y_0 = 1;
11687
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11688
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
11690
// Compute psitilde_a
11691
const double psitilde_a_0 = 1;
11692
const double psitilde_a_1 = x;
11693
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
11695
// Compute psitilde_bs
11696
const double psitilde_bs_0_0 = 1;
11697
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11698
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
11699
const double psitilde_bs_1_0 = 1;
11700
const double psitilde_bs_1_1 = 2.5*y + 1.5;
11701
const double psitilde_bs_2_0 = 1;
11703
// Compute basisvalues
11704
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11705
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11706
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11707
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
11708
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
11709
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
11711
// Table(s) of coefficients
11712
static const double coefficients0[6][6] = \
11713
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
11714
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
11715
{0, 0, 0.2, 0, 0, 0.163299316},
11716
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
11717
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
11718
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
11720
// Extract relevant coefficients
11721
const double coeff0_0 = coefficients0[dof][0];
11722
const double coeff0_1 = coefficients0[dof][1];
11723
const double coeff0_2 = coefficients0[dof][2];
11724
const double coeff0_3 = coefficients0[dof][3];
11725
const double coeff0_4 = coefficients0[dof][4];
11726
const double coeff0_5 = coefficients0[dof][5];
11728
// Compute value(s)
11729
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
11732
/// Evaluate all basis functions at given point in cell
11733
virtual void evaluate_basis_all(double* values,
11734
const double* coordinates,
11735
const ufc::cell& c) const
11737
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11740
/// Evaluate order n derivatives of basis function i at given point in cell
11741
virtual void evaluate_basis_derivatives(unsigned int i,
11744
const double* coordinates,
11745
const ufc::cell& c) const
11747
// Extract vertex coordinates
11748
const double * const * element_coordinates = c.coordinates;
11750
// Compute Jacobian of affine map from reference cell
11751
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11752
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11753
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11754
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11756
// Compute determinant of Jacobian
11757
const double detJ = J_00*J_11 - J_01*J_10;
11759
// Compute inverse of Jacobian
11761
// Get coordinates and map to the reference (UFC) element
11762
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11763
element_coordinates[0][0]*element_coordinates[2][1] +\
11764
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11765
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11766
element_coordinates[1][0]*element_coordinates[0][1] -\
11767
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11769
// Map coordinates to the reference square
11770
if (std::abs(y - 1.0) < 1e-08)
11773
x = 2.0 *x/(1.0 - y) - 1.0;
11776
// Compute number of derivatives
11777
unsigned int num_derivatives = 1;
11779
for (unsigned int j = 0; j < n; j++)
11780
num_derivatives *= 2;
11783
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11784
unsigned int **combinations = new unsigned int *[num_derivatives];
11786
for (unsigned int j = 0; j < num_derivatives; j++)
11788
combinations[j] = new unsigned int [n];
11789
for (unsigned int k = 0; k < n; k++)
11790
combinations[j][k] = 0;
11793
// Generate combinations of derivatives
11794
for (unsigned int row = 1; row < num_derivatives; row++)
11796
for (unsigned int num = 0; num < row; num++)
11798
for (unsigned int col = n-1; col+1 > 0; col--)
11800
if (combinations[row][col] + 1 > 1)
11801
combinations[row][col] = 0;
11804
combinations[row][col] += 1;
11811
// Compute inverse of Jacobian
11812
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11814
// Declare transformation matrix
11815
// Declare pointer to two dimensional array and initialise
11816
double **transform = new double *[num_derivatives];
11818
for (unsigned int j = 0; j < num_derivatives; j++)
11820
transform[j] = new double [num_derivatives];
11821
for (unsigned int k = 0; k < num_derivatives; k++)
11822
transform[j][k] = 1;
11825
// Construct transformation matrix
11826
for (unsigned int row = 0; row < num_derivatives; row++)
11828
for (unsigned int col = 0; col < num_derivatives; col++)
11830
for (unsigned int k = 0; k < n; k++)
11831
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11836
for (unsigned int j = 0; j < 1*num_derivatives; j++)
11839
// Map degree of freedom to element degree of freedom
11840
const unsigned int dof = i;
11842
// Generate scalings
11843
const double scalings_y_0 = 1;
11844
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11845
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
11847
// Compute psitilde_a
11848
const double psitilde_a_0 = 1;
11849
const double psitilde_a_1 = x;
11850
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
11852
// Compute psitilde_bs
11853
const double psitilde_bs_0_0 = 1;
11854
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11855
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
11856
const double psitilde_bs_1_0 = 1;
11857
const double psitilde_bs_1_1 = 2.5*y + 1.5;
11858
const double psitilde_bs_2_0 = 1;
11860
// Compute basisvalues
11861
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11862
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11863
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11864
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
11865
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
11866
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
11868
// Table(s) of coefficients
11869
static const double coefficients0[6][6] = \
11870
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
11871
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
11872
{0, 0, 0.2, 0, 0, 0.163299316},
11873
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
11874
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
11875
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
11877
// Interesting (new) part
11878
// Tables of derivatives of the polynomial base (transpose)
11879
static const double dmats0[6][6] = \
11880
{{0, 0, 0, 0, 0, 0},
11881
{4.89897949, 0, 0, 0, 0, 0},
11882
{0, 0, 0, 0, 0, 0},
11883
{0, 9.48683298, 0, 0, 0, 0},
11884
{4, 0, 7.07106781, 0, 0, 0},
11885
{0, 0, 0, 0, 0, 0}};
11887
static const double dmats1[6][6] = \
11888
{{0, 0, 0, 0, 0, 0},
11889
{2.44948974, 0, 0, 0, 0, 0},
11890
{4.24264069, 0, 0, 0, 0, 0},
11891
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
11892
{2, 6.12372436, 3.53553391, 0, 0, 0},
11893
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
11895
// Compute reference derivatives
11896
// Declare pointer to array of derivatives on FIAT element
11897
double *derivatives = new double [num_derivatives];
11899
// Declare coefficients
11900
double coeff0_0 = 0;
11901
double coeff0_1 = 0;
11902
double coeff0_2 = 0;
11903
double coeff0_3 = 0;
11904
double coeff0_4 = 0;
11905
double coeff0_5 = 0;
11907
// Declare new coefficients
11908
double new_coeff0_0 = 0;
11909
double new_coeff0_1 = 0;
11910
double new_coeff0_2 = 0;
11911
double new_coeff0_3 = 0;
11912
double new_coeff0_4 = 0;
11913
double new_coeff0_5 = 0;
11915
// Loop possible derivatives
11916
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11918
// Get values from coefficients array
11919
new_coeff0_0 = coefficients0[dof][0];
11920
new_coeff0_1 = coefficients0[dof][1];
11921
new_coeff0_2 = coefficients0[dof][2];
11922
new_coeff0_3 = coefficients0[dof][3];
11923
new_coeff0_4 = coefficients0[dof][4];
11924
new_coeff0_5 = coefficients0[dof][5];
11926
// Loop derivative order
11927
for (unsigned int j = 0; j < n; j++)
11929
// Update old coefficients
11930
coeff0_0 = new_coeff0_0;
11931
coeff0_1 = new_coeff0_1;
11932
coeff0_2 = new_coeff0_2;
11933
coeff0_3 = new_coeff0_3;
11934
coeff0_4 = new_coeff0_4;
11935
coeff0_5 = new_coeff0_5;
11937
if(combinations[deriv_num][j] == 0)
11939
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
11940
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
11941
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
11942
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
11943
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
11944
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
11946
if(combinations[deriv_num][j] == 1)
11948
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
11949
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
11950
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
11951
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
11952
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
11953
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
11957
// Compute derivatives on reference element as dot product of coefficients and basisvalues
11958
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
11961
// Transform derivatives back to physical element
11962
for (unsigned int row = 0; row < num_derivatives; row++)
11964
for (unsigned int col = 0; col < num_derivatives; col++)
11966
values[row] += transform[row][col]*derivatives[col];
11969
// Delete pointer to array of derivatives on FIAT element
11970
delete [] derivatives;
11972
// Delete pointer to array of combinations of derivatives and transform
11973
for (unsigned int row = 0; row < num_derivatives; row++)
11975
delete [] combinations[row];
11976
delete [] transform[row];
11979
delete [] combinations;
11980
delete [] transform;
11983
/// Evaluate order n derivatives of all basis functions at given point in cell
11984
virtual void evaluate_basis_derivatives_all(unsigned int n,
11986
const double* coordinates,
11987
const ufc::cell& c) const
11989
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11992
/// Evaluate linear functional for dof i on the function f
11993
virtual double evaluate_dof(unsigned int i,
11994
const ufc::function& f,
11995
const ufc::cell& c) const
11997
// The reference points, direction and weights:
11998
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
11999
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
12000
static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
12002
const double * const * x = c.coordinates;
12003
double result = 0.0;
12004
// Iterate over the points:
12005
// Evaluate basis functions for affine mapping
12006
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12007
const double w1 = X[i][0][0];
12008
const double w2 = X[i][0][1];
12010
// Compute affine mapping y = F(X)
12012
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12013
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12015
// Evaluate function at physical points
12017
f.evaluate(values, y, c);
12019
// Map function values using appropriate mapping
12020
// Affine map: Do nothing
12022
// Note that we do not map the weights (yet).
12024
// Take directional components
12025
for(int k = 0; k < 1; k++)
12026
result += values[k]*D[i][0][k];
12027
// Multiply by weights
12033
/// Evaluate linear functionals for all dofs on the function f
12034
virtual void evaluate_dofs(double* values,
12035
const ufc::function& f,
12036
const ufc::cell& c) const
12038
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12041
/// Interpolate vertex values from dof values
12042
virtual void interpolate_vertex_values(double* vertex_values,
12043
const double* dof_values,
12044
const ufc::cell& c) const
12046
// Evaluate at vertices and use affine mapping
12047
vertex_values[0] = dof_values[0];
12048
vertex_values[1] = dof_values[1];
12049
vertex_values[2] = dof_values[2];
12052
/// Return the number of sub elements (for a mixed element)
12053
virtual unsigned int num_sub_elements() const
12058
/// Create a new finite element for sub element i (for a mixed element)
12059
virtual ufc::finite_element* create_sub_element(unsigned int i) const
12061
return new stokes_1_finite_element_1_1();
12066
/// This class defines the interface for a finite element.
12068
class stokes_1_finite_element_1: public ufc::finite_element
12073
stokes_1_finite_element_1() : ufc::finite_element()
12079
virtual ~stokes_1_finite_element_1()
12084
/// Return a string identifying the finite element
12085
virtual const char* signature() const
12087
return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
12090
/// Return the cell shape
12091
virtual ufc::shape cell_shape() const
12093
return ufc::triangle;
12096
/// Return the dimension of the finite element function space
12097
virtual unsigned int space_dimension() const
12102
/// Return the rank of the value space
12103
virtual unsigned int value_rank() const
12108
/// Return the dimension of the value space for axis i
12109
virtual unsigned int value_dimension(unsigned int i) const
12114
/// Evaluate basis function i at given point in cell
12115
virtual void evaluate_basis(unsigned int i,
12117
const double* coordinates,
12118
const ufc::cell& c) const
12120
// Extract vertex coordinates
12121
const double * const * element_coordinates = c.coordinates;
12123
// Compute Jacobian of affine map from reference cell
12124
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12125
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12126
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12127
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12129
// Compute determinant of Jacobian
12130
const double detJ = J_00*J_11 - J_01*J_10;
12132
// Compute inverse of Jacobian
12134
// Get coordinates and map to the reference (UFC) element
12135
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12136
element_coordinates[0][0]*element_coordinates[2][1] +\
12137
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12138
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12139
element_coordinates[1][0]*element_coordinates[0][1] -\
12140
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12142
// Map coordinates to the reference square
12143
if (std::abs(y - 1.0) < 1e-08)
12146
x = 2.0 *x/(1.0 - y) - 1.0;
12153
if (0 <= i && i <= 5)
12155
// Map degree of freedom to element degree of freedom
12156
const unsigned int dof = i;
12158
// Generate scalings
12159
const double scalings_y_0 = 1;
12160
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12161
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
12163
// Compute psitilde_a
12164
const double psitilde_a_0 = 1;
12165
const double psitilde_a_1 = x;
12166
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
12168
// Compute psitilde_bs
12169
const double psitilde_bs_0_0 = 1;
12170
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12171
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
12172
const double psitilde_bs_1_0 = 1;
12173
const double psitilde_bs_1_1 = 2.5*y + 1.5;
12174
const double psitilde_bs_2_0 = 1;
12176
// Compute basisvalues
12177
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12178
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12179
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12180
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
12181
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
12182
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
12184
// Table(s) of coefficients
12185
static const double coefficients0[6][6] = \
12186
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
12187
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
12188
{0, 0, 0.2, 0, 0, 0.163299316},
12189
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
12190
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
12191
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
12193
// Extract relevant coefficients
12194
const double coeff0_0 = coefficients0[dof][0];
12195
const double coeff0_1 = coefficients0[dof][1];
12196
const double coeff0_2 = coefficients0[dof][2];
12197
const double coeff0_3 = coefficients0[dof][3];
12198
const double coeff0_4 = coefficients0[dof][4];
12199
const double coeff0_5 = coefficients0[dof][5];
12201
// Compute value(s)
12202
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
12205
if (6 <= i && i <= 11)
12207
// Map degree of freedom to element degree of freedom
12208
const unsigned int dof = i - 6;
12210
// Generate scalings
12211
const double scalings_y_0 = 1;
12212
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12213
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
12215
// Compute psitilde_a
12216
const double psitilde_a_0 = 1;
12217
const double psitilde_a_1 = x;
12218
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
12220
// Compute psitilde_bs
12221
const double psitilde_bs_0_0 = 1;
12222
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12223
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
12224
const double psitilde_bs_1_0 = 1;
12225
const double psitilde_bs_1_1 = 2.5*y + 1.5;
12226
const double psitilde_bs_2_0 = 1;
12228
// Compute basisvalues
12229
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12230
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12231
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12232
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
12233
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
12234
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
12236
// Table(s) of coefficients
12237
static const double coefficients0[6][6] = \
12238
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
12239
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
12240
{0, 0, 0.2, 0, 0, 0.163299316},
12241
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
12242
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
12243
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
12245
// Extract relevant coefficients
12246
const double coeff0_0 = coefficients0[dof][0];
12247
const double coeff0_1 = coefficients0[dof][1];
12248
const double coeff0_2 = coefficients0[dof][2];
12249
const double coeff0_3 = coefficients0[dof][3];
12250
const double coeff0_4 = coefficients0[dof][4];
12251
const double coeff0_5 = coefficients0[dof][5];
12253
// Compute value(s)
12254
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
12259
/// Evaluate all basis functions at given point in cell
12260
virtual void evaluate_basis_all(double* values,
12261
const double* coordinates,
12262
const ufc::cell& c) const
12264
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12267
/// Evaluate order n derivatives of basis function i at given point in cell
12268
virtual void evaluate_basis_derivatives(unsigned int i,
12271
const double* coordinates,
12272
const ufc::cell& c) const
12274
// Extract vertex coordinates
12275
const double * const * element_coordinates = c.coordinates;
12277
// Compute Jacobian of affine map from reference cell
12278
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12279
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12280
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12281
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12283
// Compute determinant of Jacobian
12284
const double detJ = J_00*J_11 - J_01*J_10;
12286
// Compute inverse of Jacobian
12288
// Get coordinates and map to the reference (UFC) element
12289
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12290
element_coordinates[0][0]*element_coordinates[2][1] +\
12291
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12292
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12293
element_coordinates[1][0]*element_coordinates[0][1] -\
12294
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12296
// Map coordinates to the reference square
12297
if (std::abs(y - 1.0) < 1e-08)
12300
x = 2.0 *x/(1.0 - y) - 1.0;
12303
// Compute number of derivatives
12304
unsigned int num_derivatives = 1;
12306
for (unsigned int j = 0; j < n; j++)
12307
num_derivatives *= 2;
12310
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12311
unsigned int **combinations = new unsigned int *[num_derivatives];
12313
for (unsigned int j = 0; j < num_derivatives; j++)
12315
combinations[j] = new unsigned int [n];
12316
for (unsigned int k = 0; k < n; k++)
12317
combinations[j][k] = 0;
12320
// Generate combinations of derivatives
12321
for (unsigned int row = 1; row < num_derivatives; row++)
12323
for (unsigned int num = 0; num < row; num++)
12325
for (unsigned int col = n-1; col+1 > 0; col--)
12327
if (combinations[row][col] + 1 > 1)
12328
combinations[row][col] = 0;
12331
combinations[row][col] += 1;
12338
// Compute inverse of Jacobian
12339
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12341
// Declare transformation matrix
12342
// Declare pointer to two dimensional array and initialise
12343
double **transform = new double *[num_derivatives];
12345
for (unsigned int j = 0; j < num_derivatives; j++)
12347
transform[j] = new double [num_derivatives];
12348
for (unsigned int k = 0; k < num_derivatives; k++)
12349
transform[j][k] = 1;
12352
// Construct transformation matrix
12353
for (unsigned int row = 0; row < num_derivatives; row++)
12355
for (unsigned int col = 0; col < num_derivatives; col++)
12357
for (unsigned int k = 0; k < n; k++)
12358
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12363
for (unsigned int j = 0; j < 2*num_derivatives; j++)
12366
if (0 <= i && i <= 5)
12368
// Map degree of freedom to element degree of freedom
12369
const unsigned int dof = i;
12371
// Generate scalings
12372
const double scalings_y_0 = 1;
12373
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12374
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
12376
// Compute psitilde_a
12377
const double psitilde_a_0 = 1;
12378
const double psitilde_a_1 = x;
12379
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
12381
// Compute psitilde_bs
12382
const double psitilde_bs_0_0 = 1;
12383
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12384
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
12385
const double psitilde_bs_1_0 = 1;
12386
const double psitilde_bs_1_1 = 2.5*y + 1.5;
12387
const double psitilde_bs_2_0 = 1;
12389
// Compute basisvalues
12390
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12391
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12392
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12393
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
12394
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
12395
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
12397
// Table(s) of coefficients
12398
static const double coefficients0[6][6] = \
12399
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
12400
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
12401
{0, 0, 0.2, 0, 0, 0.163299316},
12402
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
12403
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
12404
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
12406
// Interesting (new) part
12407
// Tables of derivatives of the polynomial base (transpose)
12408
static const double dmats0[6][6] = \
12409
{{0, 0, 0, 0, 0, 0},
12410
{4.89897949, 0, 0, 0, 0, 0},
12411
{0, 0, 0, 0, 0, 0},
12412
{0, 9.48683298, 0, 0, 0, 0},
12413
{4, 0, 7.07106781, 0, 0, 0},
12414
{0, 0, 0, 0, 0, 0}};
12416
static const double dmats1[6][6] = \
12417
{{0, 0, 0, 0, 0, 0},
12418
{2.44948974, 0, 0, 0, 0, 0},
12419
{4.24264069, 0, 0, 0, 0, 0},
12420
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
12421
{2, 6.12372436, 3.53553391, 0, 0, 0},
12422
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
12424
// Compute reference derivatives
12425
// Declare pointer to array of derivatives on FIAT element
12426
double *derivatives = new double [num_derivatives];
12428
// Declare coefficients
12429
double coeff0_0 = 0;
12430
double coeff0_1 = 0;
12431
double coeff0_2 = 0;
12432
double coeff0_3 = 0;
12433
double coeff0_4 = 0;
12434
double coeff0_5 = 0;
12436
// Declare new coefficients
12437
double new_coeff0_0 = 0;
12438
double new_coeff0_1 = 0;
12439
double new_coeff0_2 = 0;
12440
double new_coeff0_3 = 0;
12441
double new_coeff0_4 = 0;
12442
double new_coeff0_5 = 0;
12444
// Loop possible derivatives
12445
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12447
// Get values from coefficients array
12448
new_coeff0_0 = coefficients0[dof][0];
12449
new_coeff0_1 = coefficients0[dof][1];
12450
new_coeff0_2 = coefficients0[dof][2];
12451
new_coeff0_3 = coefficients0[dof][3];
12452
new_coeff0_4 = coefficients0[dof][4];
12453
new_coeff0_5 = coefficients0[dof][5];
12455
// Loop derivative order
12456
for (unsigned int j = 0; j < n; j++)
12458
// Update old coefficients
12459
coeff0_0 = new_coeff0_0;
12460
coeff0_1 = new_coeff0_1;
12461
coeff0_2 = new_coeff0_2;
12462
coeff0_3 = new_coeff0_3;
12463
coeff0_4 = new_coeff0_4;
12464
coeff0_5 = new_coeff0_5;
12466
if(combinations[deriv_num][j] == 0)
12468
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
12469
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
12470
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
12471
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
12472
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
12473
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
12475
if(combinations[deriv_num][j] == 1)
12477
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
12478
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
12479
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
12480
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
12481
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
12482
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
12486
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12487
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
12490
// Transform derivatives back to physical element
12491
for (unsigned int row = 0; row < num_derivatives; row++)
12493
for (unsigned int col = 0; col < num_derivatives; col++)
12495
values[row] += transform[row][col]*derivatives[col];
12498
// Delete pointer to array of derivatives on FIAT element
12499
delete [] derivatives;
12501
// Delete pointer to array of combinations of derivatives and transform
12502
for (unsigned int row = 0; row < num_derivatives; row++)
12504
delete [] combinations[row];
12505
delete [] transform[row];
12508
delete [] combinations;
12509
delete [] transform;
12512
if (6 <= i && i <= 11)
12514
// Map degree of freedom to element degree of freedom
12515
const unsigned int dof = i - 6;
12517
// Generate scalings
12518
const double scalings_y_0 = 1;
12519
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12520
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
12522
// Compute psitilde_a
12523
const double psitilde_a_0 = 1;
12524
const double psitilde_a_1 = x;
12525
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
12527
// Compute psitilde_bs
12528
const double psitilde_bs_0_0 = 1;
12529
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12530
const double psitilde_bs_0_2 = 0.111111111*psitilde_bs_0_1 + 1.66666667*y*psitilde_bs_0_1 - 0.555555556*psitilde_bs_0_0;
12531
const double psitilde_bs_1_0 = 1;
12532
const double psitilde_bs_1_1 = 2.5*y + 1.5;
12533
const double psitilde_bs_2_0 = 1;
12535
// Compute basisvalues
12536
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12537
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12538
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12539
const double basisvalue3 = 2.73861279*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
12540
const double basisvalue4 = 2.12132034*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
12541
const double basisvalue5 = 1.22474487*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
12543
// Table(s) of coefficients
12544
static const double coefficients0[6][6] = \
12545
{{0, -0.173205081, -0.1, 0.121716124, 0.0942809042, 0.0544331054},
12546
{0, 0.173205081, -0.1, 0.121716124, -0.0942809042, 0.0544331054},
12547
{0, 0, 0.2, 0, 0, 0.163299316},
12548
{0.471404521, 0.230940108, 0.133333333, 0, 0.188561808, -0.163299316},
12549
{0.471404521, -0.230940108, 0.133333333, 0, -0.188561808, -0.163299316},
12550
{0.471404521, 0, -0.266666667, -0.243432248, 0, 0.0544331054}};
12552
// Interesting (new) part
12553
// Tables of derivatives of the polynomial base (transpose)
12554
static const double dmats0[6][6] = \
12555
{{0, 0, 0, 0, 0, 0},
12556
{4.89897949, 0, 0, 0, 0, 0},
12557
{0, 0, 0, 0, 0, 0},
12558
{0, 9.48683298, 0, 0, 0, 0},
12559
{4, 0, 7.07106781, 0, 0, 0},
12560
{0, 0, 0, 0, 0, 0}};
12562
static const double dmats1[6][6] = \
12563
{{0, 0, 0, 0, 0, 0},
12564
{2.44948974, 0, 0, 0, 0, 0},
12565
{4.24264069, 0, 0, 0, 0, 0},
12566
{2.5819889, 4.74341649, -0.912870929, 0, 0, 0},
12567
{2, 6.12372436, 3.53553391, 0, 0, 0},
12568
{-2.30940108, 0, 8.16496581, 0, 0, 0}};
12570
// Compute reference derivatives
12571
// Declare pointer to array of derivatives on FIAT element
12572
double *derivatives = new double [num_derivatives];
12574
// Declare coefficients
12575
double coeff0_0 = 0;
12576
double coeff0_1 = 0;
12577
double coeff0_2 = 0;
12578
double coeff0_3 = 0;
12579
double coeff0_4 = 0;
12580
double coeff0_5 = 0;
12582
// Declare new coefficients
12583
double new_coeff0_0 = 0;
12584
double new_coeff0_1 = 0;
12585
double new_coeff0_2 = 0;
12586
double new_coeff0_3 = 0;
12587
double new_coeff0_4 = 0;
12588
double new_coeff0_5 = 0;
12590
// Loop possible derivatives
12591
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12593
// Get values from coefficients array
12594
new_coeff0_0 = coefficients0[dof][0];
12595
new_coeff0_1 = coefficients0[dof][1];
12596
new_coeff0_2 = coefficients0[dof][2];
12597
new_coeff0_3 = coefficients0[dof][3];
12598
new_coeff0_4 = coefficients0[dof][4];
12599
new_coeff0_5 = coefficients0[dof][5];
12601
// Loop derivative order
12602
for (unsigned int j = 0; j < n; j++)
12604
// Update old coefficients
12605
coeff0_0 = new_coeff0_0;
12606
coeff0_1 = new_coeff0_1;
12607
coeff0_2 = new_coeff0_2;
12608
coeff0_3 = new_coeff0_3;
12609
coeff0_4 = new_coeff0_4;
12610
coeff0_5 = new_coeff0_5;
12612
if(combinations[deriv_num][j] == 0)
12614
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
12615
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
12616
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
12617
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
12618
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
12619
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
12621
if(combinations[deriv_num][j] == 1)
12623
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
12624
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
12625
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
12626
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
12627
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
12628
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
12632
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12633
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
12636
// Transform derivatives back to physical element
12637
for (unsigned int row = 0; row < num_derivatives; row++)
12639
for (unsigned int col = 0; col < num_derivatives; col++)
12641
values[num_derivatives + row] += transform[row][col]*derivatives[col];
12644
// Delete pointer to array of derivatives on FIAT element
12645
delete [] derivatives;
12647
// Delete pointer to array of combinations of derivatives and transform
12648
for (unsigned int row = 0; row < num_derivatives; row++)
12650
delete [] combinations[row];
12651
delete [] transform[row];
12654
delete [] combinations;
12655
delete [] transform;
12660
/// Evaluate order n derivatives of all basis functions at given point in cell
12661
virtual void evaluate_basis_derivatives_all(unsigned int n,
12663
const double* coordinates,
12664
const ufc::cell& c) const
12666
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12669
/// Evaluate linear functional for dof i on the function f
12670
virtual double evaluate_dof(unsigned int i,
12671
const ufc::function& f,
12672
const ufc::cell& c) const
12674
// The reference points, direction and weights:
12675
static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
12676
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
12677
static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
12679
const double * const * x = c.coordinates;
12680
double result = 0.0;
12681
// Iterate over the points:
12682
// Evaluate basis functions for affine mapping
12683
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12684
const double w1 = X[i][0][0];
12685
const double w2 = X[i][0][1];
12687
// Compute affine mapping y = F(X)
12689
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12690
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12692
// Evaluate function at physical points
12694
f.evaluate(values, y, c);
12696
// Map function values using appropriate mapping
12697
// Affine map: Do nothing
12699
// Note that we do not map the weights (yet).
12701
// Take directional components
12702
for(int k = 0; k < 2; k++)
12703
result += values[k]*D[i][0][k];
12704
// Multiply by weights
12710
/// Evaluate linear functionals for all dofs on the function f
12711
virtual void evaluate_dofs(double* values,
12712
const ufc::function& f,
12713
const ufc::cell& c) const
12715
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12718
/// Interpolate vertex values from dof values
12719
virtual void interpolate_vertex_values(double* vertex_values,
12720
const double* dof_values,
12721
const ufc::cell& c) const
12723
// Evaluate at vertices and use affine mapping
12724
vertex_values[0] = dof_values[0];
12725
vertex_values[2] = dof_values[1];
12726
vertex_values[4] = dof_values[2];
12727
// Evaluate at vertices and use affine mapping
12728
vertex_values[1] = dof_values[6];
12729
vertex_values[3] = dof_values[7];
12730
vertex_values[5] = dof_values[8];
12733
/// Return the number of sub elements (for a mixed element)
12734
virtual unsigned int num_sub_elements() const
12739
/// Create a new finite element for sub element i (for a mixed element)
12740
virtual ufc::finite_element* create_sub_element(unsigned int i) const
12745
return new stokes_1_finite_element_1_0();
12748
return new stokes_1_finite_element_1_1();
12756
/// This class defines the interface for a local-to-global mapping of
12757
/// degrees of freedom (dofs).
12759
class stokes_1_dof_map_0_0_0: public ufc::dof_map
12763
unsigned int __global_dimension;
12768
stokes_1_dof_map_0_0_0() : ufc::dof_map()
12770
__global_dimension = 0;
12774
virtual ~stokes_1_dof_map_0_0_0()
12779
/// Return a string identifying the dof map
12780
virtual const char* signature() const
12782
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
12785
/// Return true iff mesh entities of topological dimension d are needed
12786
virtual bool needs_mesh_entities(unsigned int d) const
12803
/// Initialize dof map for mesh (return true iff init_cell() is needed)
12804
virtual bool init_mesh(const ufc::mesh& m)
12806
__global_dimension = m.num_entities[0] + m.num_entities[1];
12810
/// Initialize dof map for given cell
12811
virtual void init_cell(const ufc::mesh& m,
12812
const ufc::cell& c)
12817
/// Finish initialization of dof map for cells
12818
virtual void init_cell_finalize()
12823
/// Return the dimension of the global finite element function space
12824
virtual unsigned int global_dimension() const
12826
return __global_dimension;
12829
/// Return the dimension of the local finite element function space for a cell
12830
virtual unsigned int local_dimension(const ufc::cell& c) const
12835
/// Return the maximum dimension of the local finite element function space
12836
virtual unsigned int max_local_dimension() const
12841
// Return the geometric dimension of the coordinates this dof map provides
12842
virtual unsigned int geometric_dimension() const
12847
/// Return the number of dofs on each cell facet
12848
virtual unsigned int num_facet_dofs() const
12853
/// Return the number of dofs associated with each cell entity of dimension d
12854
virtual unsigned int num_entity_dofs(unsigned int d) const
12856
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12859
/// Tabulate the local-to-global mapping of dofs on a cell
12860
virtual void tabulate_dofs(unsigned int* dofs,
12861
const ufc::mesh& m,
12862
const ufc::cell& c) const
12864
dofs[0] = c.entity_indices[0][0];
12865
dofs[1] = c.entity_indices[0][1];
12866
dofs[2] = c.entity_indices[0][2];
12867
unsigned int offset = m.num_entities[0];
12868
dofs[3] = offset + c.entity_indices[1][0];
12869
dofs[4] = offset + c.entity_indices[1][1];
12870
dofs[5] = offset + c.entity_indices[1][2];
12873
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
12874
virtual void tabulate_facet_dofs(unsigned int* dofs,
12875
unsigned int facet) const
12897
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
12898
virtual void tabulate_entity_dofs(unsigned int* dofs,
12899
unsigned int d, unsigned int i) const
12901
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12904
/// Tabulate the coordinates of all dofs on a cell
12905
virtual void tabulate_coordinates(double** coordinates,
12906
const ufc::cell& c) const
12908
const double * const * x = c.coordinates;
12909
coordinates[0][0] = x[0][0];
12910
coordinates[0][1] = x[0][1];
12911
coordinates[1][0] = x[1][0];
12912
coordinates[1][1] = x[1][1];
12913
coordinates[2][0] = x[2][0];
12914
coordinates[2][1] = x[2][1];
12915
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
12916
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
12917
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
12918
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
12919
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
12920
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
12923
/// Return the number of sub dof maps (for a mixed element)
12924
virtual unsigned int num_sub_dof_maps() const
12929
/// Create a new dof_map for sub dof map i (for a mixed element)
12930
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
12932
return new stokes_1_dof_map_0_0_0();
12937
/// This class defines the interface for a local-to-global mapping of
12938
/// degrees of freedom (dofs).
12940
class stokes_1_dof_map_0_0_1: public ufc::dof_map
12944
unsigned int __global_dimension;
12949
stokes_1_dof_map_0_0_1() : ufc::dof_map()
12951
__global_dimension = 0;
12955
virtual ~stokes_1_dof_map_0_0_1()
12960
/// Return a string identifying the dof map
12961
virtual const char* signature() const
12963
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
12966
/// Return true iff mesh entities of topological dimension d are needed
12967
virtual bool needs_mesh_entities(unsigned int d) const
12984
/// Initialize dof map for mesh (return true iff init_cell() is needed)
12985
virtual bool init_mesh(const ufc::mesh& m)
12987
__global_dimension = m.num_entities[0] + m.num_entities[1];
12991
/// Initialize dof map for given cell
12992
virtual void init_cell(const ufc::mesh& m,
12993
const ufc::cell& c)
12998
/// Finish initialization of dof map for cells
12999
virtual void init_cell_finalize()
13004
/// Return the dimension of the global finite element function space
13005
virtual unsigned int global_dimension() const
13007
return __global_dimension;
13010
/// Return the dimension of the local finite element function space for a cell
13011
virtual unsigned int local_dimension(const ufc::cell& c) const
13016
/// Return the maximum dimension of the local finite element function space
13017
virtual unsigned int max_local_dimension() const
13022
// Return the geometric dimension of the coordinates this dof map provides
13023
virtual unsigned int geometric_dimension() const
13028
/// Return the number of dofs on each cell facet
13029
virtual unsigned int num_facet_dofs() const
13034
/// Return the number of dofs associated with each cell entity of dimension d
13035
virtual unsigned int num_entity_dofs(unsigned int d) const
13037
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13040
/// Tabulate the local-to-global mapping of dofs on a cell
13041
virtual void tabulate_dofs(unsigned int* dofs,
13042
const ufc::mesh& m,
13043
const ufc::cell& c) const
13045
dofs[0] = c.entity_indices[0][0];
13046
dofs[1] = c.entity_indices[0][1];
13047
dofs[2] = c.entity_indices[0][2];
13048
unsigned int offset = m.num_entities[0];
13049
dofs[3] = offset + c.entity_indices[1][0];
13050
dofs[4] = offset + c.entity_indices[1][1];
13051
dofs[5] = offset + c.entity_indices[1][2];
13054
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
13055
virtual void tabulate_facet_dofs(unsigned int* dofs,
13056
unsigned int facet) const
13078
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
13079
virtual void tabulate_entity_dofs(unsigned int* dofs,
13080
unsigned int d, unsigned int i) const
13082
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13085
/// Tabulate the coordinates of all dofs on a cell
13086
virtual void tabulate_coordinates(double** coordinates,
13087
const ufc::cell& c) const
13089
const double * const * x = c.coordinates;
13090
coordinates[0][0] = x[0][0];
13091
coordinates[0][1] = x[0][1];
13092
coordinates[1][0] = x[1][0];
13093
coordinates[1][1] = x[1][1];
13094
coordinates[2][0] = x[2][0];
13095
coordinates[2][1] = x[2][1];
13096
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
13097
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
13098
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
13099
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
13100
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
13101
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
13104
/// Return the number of sub dof maps (for a mixed element)
13105
virtual unsigned int num_sub_dof_maps() const
13110
/// Create a new dof_map for sub dof map i (for a mixed element)
13111
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
13113
return new stokes_1_dof_map_0_0_1();
13118
/// This class defines the interface for a local-to-global mapping of
13119
/// degrees of freedom (dofs).
13121
class stokes_1_dof_map_0_0: public ufc::dof_map
13125
unsigned int __global_dimension;
13130
stokes_1_dof_map_0_0() : ufc::dof_map()
13132
__global_dimension = 0;
13136
virtual ~stokes_1_dof_map_0_0()
13141
/// Return a string identifying the dof map
13142
virtual const char* signature() const
13144
return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
13147
/// Return true iff mesh entities of topological dimension d are needed
13148
virtual bool needs_mesh_entities(unsigned int d) const
13165
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13166
virtual bool init_mesh(const ufc::mesh& m)
13168
__global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
13172
/// Initialize dof map for given cell
13173
virtual void init_cell(const ufc::mesh& m,
13174
const ufc::cell& c)
13179
/// Finish initialization of dof map for cells
13180
virtual void init_cell_finalize()
13185
/// Return the dimension of the global finite element function space
13186
virtual unsigned int global_dimension() const
13188
return __global_dimension;
13191
/// Return the dimension of the local finite element function space for a cell
13192
virtual unsigned int local_dimension(const ufc::cell& c) const
13197
/// Return the maximum dimension of the local finite element function space
13198
virtual unsigned int max_local_dimension() const
13203
// Return the geometric dimension of the coordinates this dof map provides
13204
virtual unsigned int geometric_dimension() const
13209
/// Return the number of dofs on each cell facet
13210
virtual unsigned int num_facet_dofs() const
13215
/// Return the number of dofs associated with each cell entity of dimension d
13216
virtual unsigned int num_entity_dofs(unsigned int d) const
13218
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13221
/// Tabulate the local-to-global mapping of dofs on a cell
13222
virtual void tabulate_dofs(unsigned int* dofs,
13223
const ufc::mesh& m,
13224
const ufc::cell& c) const
13226
dofs[0] = c.entity_indices[0][0];
13227
dofs[1] = c.entity_indices[0][1];
13228
dofs[2] = c.entity_indices[0][2];
13229
unsigned int offset = m.num_entities[0];
13230
dofs[3] = offset + c.entity_indices[1][0];
13231
dofs[4] = offset + c.entity_indices[1][1];
13232
dofs[5] = offset + c.entity_indices[1][2];
13233
offset = offset + m.num_entities[1];
13234
dofs[6] = offset + c.entity_indices[0][0];
13235
dofs[7] = offset + c.entity_indices[0][1];
13236
dofs[8] = offset + c.entity_indices[0][2];
13237
offset = offset + m.num_entities[0];
13238
dofs[9] = offset + c.entity_indices[1][0];
13239
dofs[10] = offset + c.entity_indices[1][1];
13240
dofs[11] = offset + c.entity_indices[1][2];
13243
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
13244
virtual void tabulate_facet_dofs(unsigned int* dofs,
13245
unsigned int facet) const
13276
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
13277
virtual void tabulate_entity_dofs(unsigned int* dofs,
13278
unsigned int d, unsigned int i) const
13280
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13283
/// Tabulate the coordinates of all dofs on a cell
13284
virtual void tabulate_coordinates(double** coordinates,
13285
const ufc::cell& c) const
13287
const double * const * x = c.coordinates;
13288
coordinates[0][0] = x[0][0];
13289
coordinates[0][1] = x[0][1];
13290
coordinates[1][0] = x[1][0];
13291
coordinates[1][1] = x[1][1];
13292
coordinates[2][0] = x[2][0];
13293
coordinates[2][1] = x[2][1];
13294
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
13295
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
13296
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
13297
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
13298
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
13299
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
13300
coordinates[6][0] = x[0][0];
13301
coordinates[6][1] = x[0][1];
13302
coordinates[7][0] = x[1][0];
13303
coordinates[7][1] = x[1][1];
13304
coordinates[8][0] = x[2][0];
13305
coordinates[8][1] = x[2][1];
13306
coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
13307
coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
13308
coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
13309
coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
13310
coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
13311
coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
13314
/// Return the number of sub dof maps (for a mixed element)
13315
virtual unsigned int num_sub_dof_maps() const
13320
/// Create a new dof_map for sub dof map i (for a mixed element)
13321
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
13326
return new stokes_1_dof_map_0_0_0();
13329
return new stokes_1_dof_map_0_0_1();
13337
/// This class defines the interface for a local-to-global mapping of
13338
/// degrees of freedom (dofs).
13340
class stokes_1_dof_map_0_1: public ufc::dof_map
13344
unsigned int __global_dimension;
13349
stokes_1_dof_map_0_1() : ufc::dof_map()
13351
__global_dimension = 0;
13355
virtual ~stokes_1_dof_map_0_1()
13360
/// Return a string identifying the dof map
13361
virtual const char* signature() const
13363
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
13366
/// Return true iff mesh entities of topological dimension d are needed
13367
virtual bool needs_mesh_entities(unsigned int d) const
13384
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13385
virtual bool init_mesh(const ufc::mesh& m)
13387
__global_dimension = m.num_entities[0];
13391
/// Initialize dof map for given cell
13392
virtual void init_cell(const ufc::mesh& m,
13393
const ufc::cell& c)
13398
/// Finish initialization of dof map for cells
13399
virtual void init_cell_finalize()
13404
/// Return the dimension of the global finite element function space
13405
virtual unsigned int global_dimension() const
13407
return __global_dimension;
13410
/// Return the dimension of the local finite element function space for a cell
13411
virtual unsigned int local_dimension(const ufc::cell& c) const
13416
/// Return the maximum dimension of the local finite element function space
13417
virtual unsigned int max_local_dimension() const
13422
// Return the geometric dimension of the coordinates this dof map provides
13423
virtual unsigned int geometric_dimension() const
13428
/// Return the number of dofs on each cell facet
13429
virtual unsigned int num_facet_dofs() const
13434
/// Return the number of dofs associated with each cell entity of dimension d
13435
virtual unsigned int num_entity_dofs(unsigned int d) const
13437
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13440
/// Tabulate the local-to-global mapping of dofs on a cell
13441
virtual void tabulate_dofs(unsigned int* dofs,
13442
const ufc::mesh& m,
13443
const ufc::cell& c) const
13445
dofs[0] = c.entity_indices[0][0];
13446
dofs[1] = c.entity_indices[0][1];
13447
dofs[2] = c.entity_indices[0][2];
13450
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
13451
virtual void tabulate_facet_dofs(unsigned int* dofs,
13452
unsigned int facet) const
13471
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
13472
virtual void tabulate_entity_dofs(unsigned int* dofs,
13473
unsigned int d, unsigned int i) const
13475
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13478
/// Tabulate the coordinates of all dofs on a cell
13479
virtual void tabulate_coordinates(double** coordinates,
13480
const ufc::cell& c) const
13482
const double * const * x = c.coordinates;
13483
coordinates[0][0] = x[0][0];
13484
coordinates[0][1] = x[0][1];
13485
coordinates[1][0] = x[1][0];
13486
coordinates[1][1] = x[1][1];
13487
coordinates[2][0] = x[2][0];
13488
coordinates[2][1] = x[2][1];
13491
/// Return the number of sub dof maps (for a mixed element)
13492
virtual unsigned int num_sub_dof_maps() const
13497
/// Create a new dof_map for sub dof map i (for a mixed element)
13498
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
13500
return new stokes_1_dof_map_0_1();
13505
/// This class defines the interface for a local-to-global mapping of
13506
/// degrees of freedom (dofs).
13508
class stokes_1_dof_map_0: public ufc::dof_map
13512
unsigned int __global_dimension;
13517
stokes_1_dof_map_0() : ufc::dof_map()
13519
__global_dimension = 0;
13523
virtual ~stokes_1_dof_map_0()
13528
/// Return a string identifying the dof map
13529
virtual const char* signature() const
13531
return "FFC dof map for MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) })";
13534
/// Return true iff mesh entities of topological dimension d are needed
13535
virtual bool needs_mesh_entities(unsigned int d) const
13552
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13553
virtual bool init_mesh(const ufc::mesh& m)
13555
__global_dimension = 3*m.num_entities[0] + 2*m.num_entities[1];
13559
/// Initialize dof map for given cell
13560
virtual void init_cell(const ufc::mesh& m,
13561
const ufc::cell& c)
13566
/// Finish initialization of dof map for cells
13567
virtual void init_cell_finalize()
13572
/// Return the dimension of the global finite element function space
13573
virtual unsigned int global_dimension() const
13575
return __global_dimension;
13578
/// Return the dimension of the local finite element function space for a cell
13579
virtual unsigned int local_dimension(const ufc::cell& c) const
13584
/// Return the maximum dimension of the local finite element function space
13585
virtual unsigned int max_local_dimension() const
13590
// Return the geometric dimension of the coordinates this dof map provides
13591
virtual unsigned int geometric_dimension() const
13596
/// Return the number of dofs on each cell facet
13597
virtual unsigned int num_facet_dofs() const
13602
/// Return the number of dofs associated with each cell entity of dimension d
13603
virtual unsigned int num_entity_dofs(unsigned int d) const
13605
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13608
/// Tabulate the local-to-global mapping of dofs on a cell
13609
virtual void tabulate_dofs(unsigned int* dofs,
13610
const ufc::mesh& m,
13611
const ufc::cell& c) const
13613
dofs[0] = c.entity_indices[0][0];
13614
dofs[1] = c.entity_indices[0][1];
13615
dofs[2] = c.entity_indices[0][2];
13616
unsigned int offset = m.num_entities[0];
13617
dofs[3] = offset + c.entity_indices[1][0];
13618
dofs[4] = offset + c.entity_indices[1][1];
13619
dofs[5] = offset + c.entity_indices[1][2];
13620
offset = offset + m.num_entities[1];
13621
dofs[6] = offset + c.entity_indices[0][0];
13622
dofs[7] = offset + c.entity_indices[0][1];
13623
dofs[8] = offset + c.entity_indices[0][2];
13624
offset = offset + m.num_entities[0];
13625
dofs[9] = offset + c.entity_indices[1][0];
13626
dofs[10] = offset + c.entity_indices[1][1];
13627
dofs[11] = offset + c.entity_indices[1][2];
13628
offset = offset + m.num_entities[1];
13629
dofs[12] = offset + c.entity_indices[0][0];
13630
dofs[13] = offset + c.entity_indices[0][1];
13631
dofs[14] = offset + c.entity_indices[0][2];
13634
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
13635
virtual void tabulate_facet_dofs(unsigned int* dofs,
13636
unsigned int facet) const
13673
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
13674
virtual void tabulate_entity_dofs(unsigned int* dofs,
13675
unsigned int d, unsigned int i) const
13677
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13680
/// Tabulate the coordinates of all dofs on a cell
13681
virtual void tabulate_coordinates(double** coordinates,
13682
const ufc::cell& c) const
13684
const double * const * x = c.coordinates;
13685
coordinates[0][0] = x[0][0];
13686
coordinates[0][1] = x[0][1];
13687
coordinates[1][0] = x[1][0];
13688
coordinates[1][1] = x[1][1];
13689
coordinates[2][0] = x[2][0];
13690
coordinates[2][1] = x[2][1];
13691
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
13692
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
13693
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
13694
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
13695
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
13696
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
13697
coordinates[6][0] = x[0][0];
13698
coordinates[6][1] = x[0][1];
13699
coordinates[7][0] = x[1][0];
13700
coordinates[7][1] = x[1][1];
13701
coordinates[8][0] = x[2][0];
13702
coordinates[8][1] = x[2][1];
13703
coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
13704
coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
13705
coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
13706
coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
13707
coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
13708
coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
13709
coordinates[12][0] = x[0][0];
13710
coordinates[12][1] = x[0][1];
13711
coordinates[13][0] = x[1][0];
13712
coordinates[13][1] = x[1][1];
13713
coordinates[14][0] = x[2][0];
13714
coordinates[14][1] = x[2][1];
13717
/// Return the number of sub dof maps (for a mixed element)
13718
virtual unsigned int num_sub_dof_maps() const
13723
/// Create a new dof_map for sub dof map i (for a mixed element)
13724
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
13729
return new stokes_1_dof_map_0_0();
13732
return new stokes_1_dof_map_0_1();
13740
/// This class defines the interface for a local-to-global mapping of
13741
/// degrees of freedom (dofs).
13743
class stokes_1_dof_map_1_0: public ufc::dof_map
13747
unsigned int __global_dimension;
13752
stokes_1_dof_map_1_0() : ufc::dof_map()
13754
__global_dimension = 0;
13758
virtual ~stokes_1_dof_map_1_0()
13763
/// Return a string identifying the dof map
13764
virtual const char* signature() const
13766
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
13769
/// Return true iff mesh entities of topological dimension d are needed
13770
virtual bool needs_mesh_entities(unsigned int d) const
13787
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13788
virtual bool init_mesh(const ufc::mesh& m)
13790
__global_dimension = m.num_entities[0] + m.num_entities[1];
13794
/// Initialize dof map for given cell
13795
virtual void init_cell(const ufc::mesh& m,
13796
const ufc::cell& c)
13801
/// Finish initialization of dof map for cells
13802
virtual void init_cell_finalize()
13807
/// Return the dimension of the global finite element function space
13808
virtual unsigned int global_dimension() const
13810
return __global_dimension;
13813
/// Return the dimension of the local finite element function space for a cell
13814
virtual unsigned int local_dimension(const ufc::cell& c) const
13819
/// Return the maximum dimension of the local finite element function space
13820
virtual unsigned int max_local_dimension() const
13825
// Return the geometric dimension of the coordinates this dof map provides
13826
virtual unsigned int geometric_dimension() const
13831
/// Return the number of dofs on each cell facet
13832
virtual unsigned int num_facet_dofs() const
13837
/// Return the number of dofs associated with each cell entity of dimension d
13838
virtual unsigned int num_entity_dofs(unsigned int d) const
13840
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13843
/// Tabulate the local-to-global mapping of dofs on a cell
13844
virtual void tabulate_dofs(unsigned int* dofs,
13845
const ufc::mesh& m,
13846
const ufc::cell& c) const
13848
dofs[0] = c.entity_indices[0][0];
13849
dofs[1] = c.entity_indices[0][1];
13850
dofs[2] = c.entity_indices[0][2];
13851
unsigned int offset = m.num_entities[0];
13852
dofs[3] = offset + c.entity_indices[1][0];
13853
dofs[4] = offset + c.entity_indices[1][1];
13854
dofs[5] = offset + c.entity_indices[1][2];
13857
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
13858
virtual void tabulate_facet_dofs(unsigned int* dofs,
13859
unsigned int facet) const
13881
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
13882
virtual void tabulate_entity_dofs(unsigned int* dofs,
13883
unsigned int d, unsigned int i) const
13885
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13888
/// Tabulate the coordinates of all dofs on a cell
13889
virtual void tabulate_coordinates(double** coordinates,
13890
const ufc::cell& c) const
13892
const double * const * x = c.coordinates;
13893
coordinates[0][0] = x[0][0];
13894
coordinates[0][1] = x[0][1];
13895
coordinates[1][0] = x[1][0];
13896
coordinates[1][1] = x[1][1];
13897
coordinates[2][0] = x[2][0];
13898
coordinates[2][1] = x[2][1];
13899
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
13900
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
13901
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
13902
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
13903
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
13904
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
13907
/// Return the number of sub dof maps (for a mixed element)
13908
virtual unsigned int num_sub_dof_maps() const
13913
/// Create a new dof_map for sub dof map i (for a mixed element)
13914
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
13916
return new stokes_1_dof_map_1_0();
13921
/// This class defines the interface for a local-to-global mapping of
13922
/// degrees of freedom (dofs).
13924
class stokes_1_dof_map_1_1: public ufc::dof_map
13928
unsigned int __global_dimension;
13933
stokes_1_dof_map_1_1() : ufc::dof_map()
13935
__global_dimension = 0;
13939
virtual ~stokes_1_dof_map_1_1()
13944
/// Return a string identifying the dof map
13945
virtual const char* signature() const
13947
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
13950
/// Return true iff mesh entities of topological dimension d are needed
13951
virtual bool needs_mesh_entities(unsigned int d) const
13968
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13969
virtual bool init_mesh(const ufc::mesh& m)
13971
__global_dimension = m.num_entities[0] + m.num_entities[1];
13975
/// Initialize dof map for given cell
13976
virtual void init_cell(const ufc::mesh& m,
13977
const ufc::cell& c)
13982
/// Finish initialization of dof map for cells
13983
virtual void init_cell_finalize()
13988
/// Return the dimension of the global finite element function space
13989
virtual unsigned int global_dimension() const
13991
return __global_dimension;
13994
/// Return the dimension of the local finite element function space for a cell
13995
virtual unsigned int local_dimension(const ufc::cell& c) const
14000
/// Return the maximum dimension of the local finite element function space
14001
virtual unsigned int max_local_dimension() const
14006
// Return the geometric dimension of the coordinates this dof map provides
14007
virtual unsigned int geometric_dimension() const
14012
/// Return the number of dofs on each cell facet
14013
virtual unsigned int num_facet_dofs() const
14018
/// Return the number of dofs associated with each cell entity of dimension d
14019
virtual unsigned int num_entity_dofs(unsigned int d) const
14021
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14024
/// Tabulate the local-to-global mapping of dofs on a cell
14025
virtual void tabulate_dofs(unsigned int* dofs,
14026
const ufc::mesh& m,
14027
const ufc::cell& c) const
14029
dofs[0] = c.entity_indices[0][0];
14030
dofs[1] = c.entity_indices[0][1];
14031
dofs[2] = c.entity_indices[0][2];
14032
unsigned int offset = m.num_entities[0];
14033
dofs[3] = offset + c.entity_indices[1][0];
14034
dofs[4] = offset + c.entity_indices[1][1];
14035
dofs[5] = offset + c.entity_indices[1][2];
14038
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14039
virtual void tabulate_facet_dofs(unsigned int* dofs,
14040
unsigned int facet) const
14062
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14063
virtual void tabulate_entity_dofs(unsigned int* dofs,
14064
unsigned int d, unsigned int i) const
14066
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14069
/// Tabulate the coordinates of all dofs on a cell
14070
virtual void tabulate_coordinates(double** coordinates,
14071
const ufc::cell& c) const
14073
const double * const * x = c.coordinates;
14074
coordinates[0][0] = x[0][0];
14075
coordinates[0][1] = x[0][1];
14076
coordinates[1][0] = x[1][0];
14077
coordinates[1][1] = x[1][1];
14078
coordinates[2][0] = x[2][0];
14079
coordinates[2][1] = x[2][1];
14080
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
14081
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
14082
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
14083
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
14084
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
14085
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
14088
/// Return the number of sub dof maps (for a mixed element)
14089
virtual unsigned int num_sub_dof_maps() const
14094
/// Create a new dof_map for sub dof map i (for a mixed element)
14095
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
14097
return new stokes_1_dof_map_1_1();
14102
/// This class defines the interface for a local-to-global mapping of
14103
/// degrees of freedom (dofs).
14105
class stokes_1_dof_map_1: public ufc::dof_map
14109
unsigned int __global_dimension;
14114
stokes_1_dof_map_1() : ufc::dof_map()
14116
__global_dimension = 0;
14120
virtual ~stokes_1_dof_map_1()
14125
/// Return a string identifying the dof map
14126
virtual const char* signature() const
14128
return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
14131
/// Return true iff mesh entities of topological dimension d are needed
14132
virtual bool needs_mesh_entities(unsigned int d) const
14149
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14150
virtual bool init_mesh(const ufc::mesh& m)
14152
__global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
14156
/// Initialize dof map for given cell
14157
virtual void init_cell(const ufc::mesh& m,
14158
const ufc::cell& c)
14163
/// Finish initialization of dof map for cells
14164
virtual void init_cell_finalize()
14169
/// Return the dimension of the global finite element function space
14170
virtual unsigned int global_dimension() const
14172
return __global_dimension;
14175
/// Return the dimension of the local finite element function space for a cell
14176
virtual unsigned int local_dimension(const ufc::cell& c) const
14181
/// Return the maximum dimension of the local finite element function space
14182
virtual unsigned int max_local_dimension() const
14187
// Return the geometric dimension of the coordinates this dof map provides
14188
virtual unsigned int geometric_dimension() const
14193
/// Return the number of dofs on each cell facet
14194
virtual unsigned int num_facet_dofs() const
14199
/// Return the number of dofs associated with each cell entity of dimension d
14200
virtual unsigned int num_entity_dofs(unsigned int d) const
14202
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14205
/// Tabulate the local-to-global mapping of dofs on a cell
14206
virtual void tabulate_dofs(unsigned int* dofs,
14207
const ufc::mesh& m,
14208
const ufc::cell& c) const
14210
dofs[0] = c.entity_indices[0][0];
14211
dofs[1] = c.entity_indices[0][1];
14212
dofs[2] = c.entity_indices[0][2];
14213
unsigned int offset = m.num_entities[0];
14214
dofs[3] = offset + c.entity_indices[1][0];
14215
dofs[4] = offset + c.entity_indices[1][1];
14216
dofs[5] = offset + c.entity_indices[1][2];
14217
offset = offset + m.num_entities[1];
14218
dofs[6] = offset + c.entity_indices[0][0];
14219
dofs[7] = offset + c.entity_indices[0][1];
14220
dofs[8] = offset + c.entity_indices[0][2];
14221
offset = offset + m.num_entities[0];
14222
dofs[9] = offset + c.entity_indices[1][0];
14223
dofs[10] = offset + c.entity_indices[1][1];
14224
dofs[11] = offset + c.entity_indices[1][2];
14227
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14228
virtual void tabulate_facet_dofs(unsigned int* dofs,
14229
unsigned int facet) const
14260
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14261
virtual void tabulate_entity_dofs(unsigned int* dofs,
14262
unsigned int d, unsigned int i) const
14264
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14267
/// Tabulate the coordinates of all dofs on a cell
14268
virtual void tabulate_coordinates(double** coordinates,
14269
const ufc::cell& c) const
14271
const double * const * x = c.coordinates;
14272
coordinates[0][0] = x[0][0];
14273
coordinates[0][1] = x[0][1];
14274
coordinates[1][0] = x[1][0];
14275
coordinates[1][1] = x[1][1];
14276
coordinates[2][0] = x[2][0];
14277
coordinates[2][1] = x[2][1];
14278
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
14279
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
14280
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
14281
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
14282
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
14283
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
14284
coordinates[6][0] = x[0][0];
14285
coordinates[6][1] = x[0][1];
14286
coordinates[7][0] = x[1][0];
14287
coordinates[7][1] = x[1][1];
14288
coordinates[8][0] = x[2][0];
14289
coordinates[8][1] = x[2][1];
14290
coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
14291
coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
14292
coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
14293
coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
14294
coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
14295
coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
14298
/// Return the number of sub dof maps (for a mixed element)
14299
virtual unsigned int num_sub_dof_maps() const
14304
/// Create a new dof_map for sub dof map i (for a mixed element)
14305
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
14310
return new stokes_1_dof_map_1_0();
14313
return new stokes_1_dof_map_1_1();
14321
/// This class defines the interface for the tabulation of the cell
14322
/// tensor corresponding to the local contribution to a form from
14323
/// the integral over a cell.
14325
class stokes_1_cell_integral_0_tensor: public ufc::cell_integral
14330
stokes_1_cell_integral_0_tensor() : ufc::cell_integral()
14336
virtual ~stokes_1_cell_integral_0_tensor()
14341
/// Tabulate the tensor for the contribution from a local cell
14342
virtual void tabulate_tensor(double* A,
14343
const double * const * w,
14344
const ufc::cell& c) const
14346
// Number of operations to compute geometry tensor: 12
14347
// Number of operations to compute tensor contraction: 84
14348
// Total number of operations to compute cell tensor: 96
14350
// Extract vertex coordinates
14351
const double * const * x = c.coordinates;
14353
// Compute Jacobian of affine map from reference cell
14354
const double J_00 = x[1][0] - x[0][0];
14355
const double J_01 = x[2][0] - x[0][0];
14356
const double J_10 = x[1][1] - x[0][1];
14357
const double J_11 = x[2][1] - x[0][1];
14359
// Compute determinant of Jacobian
14360
double detJ = J_00*J_11 - J_01*J_10;
14362
// Compute inverse of Jacobian
14364
// Set scale factor
14365
const double det = std::abs(detJ);
14367
// Compute geometry tensor
14368
const double G0_0 = det*w[0][0];
14369
const double G0_1 = det*w[0][1];
14370
const double G0_2 = det*w[0][2];
14371
const double G0_3 = det*w[0][3];
14372
const double G0_4 = det*w[0][4];
14373
const double G0_5 = det*w[0][5];
14374
const double G1_6 = det*w[0][6];
14375
const double G1_7 = det*w[0][7];
14376
const double G1_8 = det*w[0][8];
14377
const double G1_9 = det*w[0][9];
14378
const double G1_10 = det*w[0][10];
14379
const double G1_11 = det*w[0][11];
14381
// Compute element tensor
14382
A[0] += 0.0166666667*G0_0 - 0.00277777778*G0_1 - 0.00277777778*G0_2 - 0.0111111111*G0_3;
14383
A[1] += -0.00277777778*G0_0 + 0.0166666667*G0_1 - 0.00277777778*G0_2 - 0.0111111111*G0_4;
14384
A[2] += -0.00277777778*G0_0 - 0.00277777778*G0_1 + 0.0166666667*G0_2 - 0.0111111111*G0_5;
14385
A[3] += -0.0111111111*G0_0 + 0.0888888889*G0_3 + 0.0444444444*G0_4 + 0.0444444444*G0_5;
14386
A[4] += -0.0111111111*G0_1 + 0.0444444444*G0_3 + 0.0888888889*G0_4 + 0.0444444444*G0_5;
14387
A[5] += -0.0111111111*G0_2 + 0.0444444444*G0_3 + 0.0444444444*G0_4 + 0.0888888889*G0_5;
14388
A[6] += 0.0166666667*G1_6 - 0.00277777778*G1_7 - 0.00277777778*G1_8 - 0.0111111111*G1_9;
14389
A[7] += -0.00277777778*G1_6 + 0.0166666667*G1_7 - 0.00277777778*G1_8 - 0.0111111111*G1_10;
14390
A[8] += -0.00277777778*G1_6 - 0.00277777778*G1_7 + 0.0166666667*G1_8 - 0.0111111111*G1_11;
14391
A[9] += -0.0111111111*G1_6 + 0.0888888889*G1_9 + 0.0444444444*G1_10 + 0.0444444444*G1_11;
14392
A[10] += -0.0111111111*G1_7 + 0.0444444444*G1_9 + 0.0888888889*G1_10 + 0.0444444444*G1_11;
14393
A[11] += -0.0111111111*G1_8 + 0.0444444444*G1_9 + 0.0444444444*G1_10 + 0.0888888889*G1_11;
14401
/// This class defines the interface for the tabulation of the cell
14402
/// tensor corresponding to the local contribution to a form from
14403
/// the integral over a cell.
14405
class stokes_1_cell_integral_0: public ufc::cell_integral
14409
stokes_1_cell_integral_0_tensor integral_0_tensor;
14414
stokes_1_cell_integral_0() : ufc::cell_integral()
14420
virtual ~stokes_1_cell_integral_0()
14425
/// Tabulate the tensor for the contribution from a local cell
14426
virtual void tabulate_tensor(double* A,
14427
const double * const * w,
14428
const ufc::cell& c) const
14430
// Reset values of the element tensor block
14431
for (unsigned int j = 0; j < 15; j++)
14434
// Add all contributions to element tensor
14435
integral_0_tensor.tabulate_tensor(A, w, c);
14440
/// This class defines the interface for the assembly of the global
14441
/// tensor corresponding to a form with r + n arguments, that is, a
14444
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
14446
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
14447
/// global tensor A is defined by
14449
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
14451
/// where each argument Vj represents the application to the
14452
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
14453
/// fixed functions (coefficients).
14455
class stokes_form_1: public ufc::form
14460
stokes_form_1() : ufc::form()
14466
virtual ~stokes_form_1()
14471
/// Return a string identifying the form
14472
virtual const char* signature() const
14474
return "Form([Integral(IndexSum(Product(Indexed(Function(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), 0), MultiIndex((Index(0),), {Index(0): 2})), Indexed(ListTensor(Indexed(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 3})), Indexed(BasisFunction(MixedElement(*[VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (3,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 3}))), MultiIndex((Index(0),), {Index(0): 2}))), MultiIndex((Index(0),), {Index(0): 2})), Measure('cell', 0, None))])";
14477
/// Return the rank of the global tensor (r)
14478
virtual unsigned int rank() const
14483
/// Return the number of coefficients (n)
14484
virtual unsigned int num_coefficients() const
14489
/// Return the number of cell integrals
14490
virtual unsigned int num_cell_integrals() const
14495
/// Return the number of exterior facet integrals
14496
virtual unsigned int num_exterior_facet_integrals() const
14501
/// Return the number of interior facet integrals
14502
virtual unsigned int num_interior_facet_integrals() const
14507
/// Create a new finite element for argument function i
14508
virtual ufc::finite_element* create_finite_element(unsigned int i) const
14513
return new stokes_1_finite_element_0();
14516
return new stokes_1_finite_element_1();
14522
/// Create a new dof map for argument function i
14523
virtual ufc::dof_map* create_dof_map(unsigned int i) const
14528
return new stokes_1_dof_map_0();
14531
return new stokes_1_dof_map_1();
14537
/// Create a new cell integral on sub domain i
14538
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
14540
return new stokes_1_cell_integral_0();
14543
/// Create a new exterior facet integral on sub domain i
14544
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
14549
/// Create a new interior facet integral on sub domain i
14550
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const