1
1
#include "CahnHilliard2D.h"
3
UFC_CahnHilliard2DBilinearForm_finite_element_0_0::UFC_CahnHilliard2DBilinearForm_finite_element_0_0() : ufc::finite_element()
9
UFC_CahnHilliard2DBilinearForm_finite_element_0_0::~UFC_CahnHilliard2DBilinearForm_finite_element_0_0()
14
/// Return a string identifying the finite element
15
const char* UFC_CahnHilliard2DBilinearForm_finite_element_0_0::signature() const
17
return "FiniteElement('Lagrange', 'triangle', 1)";
20
/// Return the cell shape
21
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_0_0::cell_shape() const
26
/// Return the dimension of the finite element function space
27
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::space_dimension() const
32
/// Return the rank of the value space
33
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::value_rank() const
38
/// Return the dimension of the value space for axis i
39
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::value_dimension(unsigned int i) const
44
/// Evaluate basis function i at given point in cell
45
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis(unsigned int i,
47
const double* coordinates,
48
const ufc::cell& c) const
50
// Extract vertex coordinates
51
const double * const * element_coordinates = c.coordinates;
53
// Compute Jacobian of affine map from reference cell
54
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
55
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
56
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
57
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
59
// Compute determinant of Jacobian
60
const double detJ = J_00*J_11 - J_01*J_10;
62
// Compute inverse of Jacobian
64
// Get coordinates and map to the reference (UFC) element
65
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
66
element_coordinates[0][0]*element_coordinates[2][1] +\
67
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
68
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
69
element_coordinates[1][0]*element_coordinates[0][1] -\
70
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
72
// Map coordinates to the reference square
73
if (std::abs(y - 1.0) < 1e-14)
76
x = 2.0 *x/(1.0 - y) - 1.0;
82
// Map degree of freedom to element degree of freedom
83
const unsigned int dof = i;
86
const double scalings_y_0 = 1;
87
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
90
const double psitilde_a_0 = 1;
91
const double psitilde_a_1 = x;
93
// Compute psitilde_bs
94
const double psitilde_bs_0_0 = 1;
95
const double psitilde_bs_0_1 = 1.5*y + 0.5;
96
const double psitilde_bs_1_0 = 1;
98
// Compute basisvalues
99
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
100
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
101
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
103
// Table(s) of coefficients
104
const static double coefficients0[3][3] = \
105
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
106
{0.471404520791032, 0.288675134594813, -0.166666666666667},
107
{0.471404520791032, 0, 0.333333333333333}};
109
// Extract relevant coefficients
110
const double coeff0_0 = coefficients0[dof][0];
111
const double coeff0_1 = coefficients0[dof][1];
112
const double coeff0_2 = coefficients0[dof][2];
115
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
118
/// Evaluate all basis functions at given point in cell
119
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis_all(double* values,
120
const double* coordinates,
121
const ufc::cell& c) const
123
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
126
/// Evaluate order n derivatives of basis function i at given point in cell
127
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis_derivatives(unsigned int i,
130
const double* coordinates,
131
const ufc::cell& c) const
133
// Extract vertex coordinates
134
const double * const * element_coordinates = c.coordinates;
136
// Compute Jacobian of affine map from reference cell
137
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
138
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
139
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
140
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
142
// Compute determinant of Jacobian
143
const double detJ = J_00*J_11 - J_01*J_10;
145
// Compute inverse of Jacobian
147
// Get coordinates and map to the reference (UFC) element
148
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
149
element_coordinates[0][0]*element_coordinates[2][1] +\
150
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
151
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
152
element_coordinates[1][0]*element_coordinates[0][1] -\
153
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
155
// Map coordinates to the reference square
156
if (std::abs(y - 1.0) < 1e-14)
159
x = 2.0 *x/(1.0 - y) - 1.0;
162
// Compute number of derivatives
163
unsigned int num_derivatives = 1;
165
for (unsigned int j = 0; j < n; j++)
166
num_derivatives *= 2;
169
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
170
unsigned int **combinations = new unsigned int *[num_derivatives];
172
for (unsigned int j = 0; j < num_derivatives; j++)
174
combinations[j] = new unsigned int [n];
175
for (unsigned int k = 0; k < n; k++)
176
combinations[j][k] = 0;
179
// Generate combinations of derivatives
180
for (unsigned int row = 1; row < num_derivatives; row++)
182
for (unsigned int num = 0; num < row; num++)
184
for (unsigned int col = n-1; col+1 > 0; col--)
186
if (combinations[row][col] + 1 > 1)
187
combinations[row][col] = 0;
190
combinations[row][col] += 1;
197
// Compute inverse of Jacobian
198
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
200
// Declare transformation matrix
201
// Declare pointer to two dimensional array and initialise
202
double **transform = new double *[num_derivatives];
204
for (unsigned int j = 0; j < num_derivatives; j++)
206
transform[j] = new double [num_derivatives];
207
for (unsigned int k = 0; k < num_derivatives; k++)
211
// Construct transformation matrix
212
for (unsigned int row = 0; row < num_derivatives; row++)
214
for (unsigned int col = 0; col < num_derivatives; col++)
216
for (unsigned int k = 0; k < n; k++)
217
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
222
for (unsigned int j = 0; j < 1*num_derivatives; j++)
225
// Map degree of freedom to element degree of freedom
226
const unsigned int dof = i;
229
const double scalings_y_0 = 1;
230
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
232
// Compute psitilde_a
233
const double psitilde_a_0 = 1;
234
const double psitilde_a_1 = x;
236
// Compute psitilde_bs
237
const double psitilde_bs_0_0 = 1;
238
const double psitilde_bs_0_1 = 1.5*y + 0.5;
239
const double psitilde_bs_1_0 = 1;
241
// Compute basisvalues
242
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
243
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
244
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
246
// Table(s) of coefficients
247
const static double coefficients0[3][3] = \
248
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
249
{0.471404520791032, 0.288675134594813, -0.166666666666667},
250
{0.471404520791032, 0, 0.333333333333333}};
252
// Interesting (new) part
253
// Tables of derivatives of the polynomial base (transpose)
254
const static double dmats0[3][3] = \
256
{4.89897948556636, 0, 0},
259
const static double dmats1[3][3] = \
261
{2.44948974278318, 0, 0},
262
{4.24264068711928, 0, 0}};
264
// Compute reference derivatives
265
// Declare pointer to array of derivatives on FIAT element
266
double *derivatives = new double [num_derivatives];
268
// Declare coefficients
273
// Declare new coefficients
274
double new_coeff0_0 = 0;
275
double new_coeff0_1 = 0;
276
double new_coeff0_2 = 0;
278
// Loop possible derivatives
279
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
281
// Get values from coefficients array
282
new_coeff0_0 = coefficients0[dof][0];
283
new_coeff0_1 = coefficients0[dof][1];
284
new_coeff0_2 = coefficients0[dof][2];
286
// Loop derivative order
287
for (unsigned int j = 0; j < n; j++)
289
// Update old coefficients
290
coeff0_0 = new_coeff0_0;
291
coeff0_1 = new_coeff0_1;
292
coeff0_2 = new_coeff0_2;
294
if(combinations[deriv_num][j] == 0)
296
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
297
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
298
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
300
if(combinations[deriv_num][j] == 1)
302
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
303
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
304
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
308
// Compute derivatives on reference element as dot product of coefficients and basisvalues
309
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
312
// Transform derivatives back to physical element
313
for (unsigned int row = 0; row < num_derivatives; row++)
315
for (unsigned int col = 0; col < num_derivatives; col++)
317
values[row] += transform[row][col]*derivatives[col];
320
// Delete pointer to array of derivatives on FIAT element
321
delete [] derivatives;
323
// Delete pointer to array of combinations of derivatives and transform
324
for (unsigned int row = 0; row < num_derivatives; row++)
326
delete [] combinations[row];
327
delete [] transform[row];
330
delete [] combinations;
334
/// Evaluate order n derivatives of all basis functions at given point in cell
335
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
337
const double* coordinates,
338
const ufc::cell& c) const
340
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
343
/// Evaluate linear functional for dof i on the function f
344
double UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_dof(unsigned int i,
345
const ufc::function& f,
346
const ufc::cell& c) const
348
// The reference points, direction and weights:
349
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
350
const static double W[3][1] = {{1}, {1}, {1}};
351
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
353
const double * const * x = c.coordinates;
355
// Iterate over the points:
356
// Evaluate basis functions for affine mapping
357
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
358
const double w1 = X[i][0][0];
359
const double w2 = X[i][0][1];
361
// Compute affine mapping y = F(X)
363
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
364
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
366
// Evaluate function at physical points
368
f.evaluate(values, y, c);
370
// Map function values using appropriate mapping
371
// Affine map: Do nothing
373
// Note that we do not map the weights (yet).
375
// Take directional components
376
for(int k = 0; k < 1; k++)
377
result += values[k]*D[i][0][k];
378
// Multiply by weights
384
/// Evaluate linear functionals for all dofs on the function f
385
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_dofs(double* values,
386
const ufc::function& f,
387
const ufc::cell& c) const
389
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
392
/// Interpolate vertex values from dof values
393
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
394
const double* dof_values,
395
const ufc::cell& c) const
397
// Evaluate at vertices and use affine mapping
398
vertex_values[0] = dof_values[0];
399
vertex_values[1] = dof_values[1];
400
vertex_values[2] = dof_values[2];
403
/// Return the number of sub elements (for a mixed element)
404
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::num_sub_elements() const
409
/// Create a new finite element for sub element i (for a mixed element)
410
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_0_0::create_sub_element(unsigned int i) const
412
return new UFC_CahnHilliard2DBilinearForm_finite_element_0_0();
417
UFC_CahnHilliard2DBilinearForm_finite_element_0_1::UFC_CahnHilliard2DBilinearForm_finite_element_0_1() : ufc::finite_element()
423
UFC_CahnHilliard2DBilinearForm_finite_element_0_1::~UFC_CahnHilliard2DBilinearForm_finite_element_0_1()
428
/// Return a string identifying the finite element
429
const char* UFC_CahnHilliard2DBilinearForm_finite_element_0_1::signature() const
431
return "FiniteElement('Lagrange', 'triangle', 1)";
434
/// Return the cell shape
435
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_0_1::cell_shape() const
437
return ufc::triangle;
440
/// Return the dimension of the finite element function space
441
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::space_dimension() const
446
/// Return the rank of the value space
447
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::value_rank() const
452
/// Return the dimension of the value space for axis i
453
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::value_dimension(unsigned int i) const
458
/// Evaluate basis function i at given point in cell
459
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis(unsigned int i,
461
const double* coordinates,
462
const ufc::cell& c) const
464
// Extract vertex coordinates
465
const double * const * element_coordinates = c.coordinates;
467
// Compute Jacobian of affine map from reference cell
468
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
469
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
470
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
471
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
473
// Compute determinant of Jacobian
474
const double detJ = J_00*J_11 - J_01*J_10;
476
// Compute inverse of Jacobian
478
// Get coordinates and map to the reference (UFC) element
479
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
480
element_coordinates[0][0]*element_coordinates[2][1] +\
481
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
482
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
483
element_coordinates[1][0]*element_coordinates[0][1] -\
484
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
486
// Map coordinates to the reference square
487
if (std::abs(y - 1.0) < 1e-14)
490
x = 2.0 *x/(1.0 - y) - 1.0;
496
// Map degree of freedom to element degree of freedom
497
const unsigned int dof = i;
500
const double scalings_y_0 = 1;
501
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
503
// Compute psitilde_a
504
const double psitilde_a_0 = 1;
505
const double psitilde_a_1 = x;
507
// Compute psitilde_bs
508
const double psitilde_bs_0_0 = 1;
509
const double psitilde_bs_0_1 = 1.5*y + 0.5;
510
const double psitilde_bs_1_0 = 1;
512
// Compute basisvalues
513
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
514
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
515
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
517
// Table(s) of coefficients
518
const static double coefficients0[3][3] = \
519
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
520
{0.471404520791032, 0.288675134594813, -0.166666666666667},
521
{0.471404520791032, 0, 0.333333333333333}};
523
// Extract relevant coefficients
524
const double coeff0_0 = coefficients0[dof][0];
525
const double coeff0_1 = coefficients0[dof][1];
526
const double coeff0_2 = coefficients0[dof][2];
529
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
532
/// Evaluate all basis functions at given point in cell
533
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis_all(double* values,
534
const double* coordinates,
535
const ufc::cell& c) const
537
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
540
/// Evaluate order n derivatives of basis function i at given point in cell
541
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
544
const double* coordinates,
545
const ufc::cell& c) const
547
// Extract vertex coordinates
548
const double * const * element_coordinates = c.coordinates;
550
// Compute Jacobian of affine map from reference cell
551
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
552
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
553
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
554
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
556
// Compute determinant of Jacobian
557
const double detJ = J_00*J_11 - J_01*J_10;
559
// Compute inverse of Jacobian
561
// Get coordinates and map to the reference (UFC) element
562
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
563
element_coordinates[0][0]*element_coordinates[2][1] +\
564
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
565
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
566
element_coordinates[1][0]*element_coordinates[0][1] -\
567
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
569
// Map coordinates to the reference square
570
if (std::abs(y - 1.0) < 1e-14)
573
x = 2.0 *x/(1.0 - y) - 1.0;
576
// Compute number of derivatives
577
unsigned int num_derivatives = 1;
579
for (unsigned int j = 0; j < n; j++)
580
num_derivatives *= 2;
583
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
584
unsigned int **combinations = new unsigned int *[num_derivatives];
586
for (unsigned int j = 0; j < num_derivatives; j++)
588
combinations[j] = new unsigned int [n];
589
for (unsigned int k = 0; k < n; k++)
590
combinations[j][k] = 0;
593
// Generate combinations of derivatives
594
for (unsigned int row = 1; row < num_derivatives; row++)
596
for (unsigned int num = 0; num < row; num++)
598
for (unsigned int col = n-1; col+1 > 0; col--)
600
if (combinations[row][col] + 1 > 1)
601
combinations[row][col] = 0;
604
combinations[row][col] += 1;
611
// Compute inverse of Jacobian
612
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
614
// Declare transformation matrix
615
// Declare pointer to two dimensional array and initialise
616
double **transform = new double *[num_derivatives];
618
for (unsigned int j = 0; j < num_derivatives; j++)
620
transform[j] = new double [num_derivatives];
621
for (unsigned int k = 0; k < num_derivatives; k++)
625
// Construct transformation matrix
626
for (unsigned int row = 0; row < num_derivatives; row++)
628
for (unsigned int col = 0; col < num_derivatives; col++)
630
for (unsigned int k = 0; k < n; k++)
631
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
636
for (unsigned int j = 0; j < 1*num_derivatives; j++)
639
// Map degree of freedom to element degree of freedom
640
const unsigned int dof = i;
643
const double scalings_y_0 = 1;
644
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
646
// Compute psitilde_a
647
const double psitilde_a_0 = 1;
648
const double psitilde_a_1 = x;
650
// Compute psitilde_bs
651
const double psitilde_bs_0_0 = 1;
652
const double psitilde_bs_0_1 = 1.5*y + 0.5;
653
const double psitilde_bs_1_0 = 1;
655
// Compute basisvalues
656
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
657
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
658
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
660
// Table(s) of coefficients
661
const static double coefficients0[3][3] = \
662
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
663
{0.471404520791032, 0.288675134594813, -0.166666666666667},
664
{0.471404520791032, 0, 0.333333333333333}};
666
// Interesting (new) part
667
// Tables of derivatives of the polynomial base (transpose)
668
const static double dmats0[3][3] = \
670
{4.89897948556636, 0, 0},
673
const static double dmats1[3][3] = \
675
{2.44948974278318, 0, 0},
676
{4.24264068711928, 0, 0}};
678
// Compute reference derivatives
679
// Declare pointer to array of derivatives on FIAT element
680
double *derivatives = new double [num_derivatives];
682
// Declare coefficients
687
// Declare new coefficients
688
double new_coeff0_0 = 0;
689
double new_coeff0_1 = 0;
690
double new_coeff0_2 = 0;
692
// Loop possible derivatives
693
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
695
// Get values from coefficients array
696
new_coeff0_0 = coefficients0[dof][0];
697
new_coeff0_1 = coefficients0[dof][1];
698
new_coeff0_2 = coefficients0[dof][2];
700
// Loop derivative order
701
for (unsigned int j = 0; j < n; j++)
703
// Update old coefficients
704
coeff0_0 = new_coeff0_0;
705
coeff0_1 = new_coeff0_1;
706
coeff0_2 = new_coeff0_2;
708
if(combinations[deriv_num][j] == 0)
710
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
711
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
712
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
714
if(combinations[deriv_num][j] == 1)
716
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
717
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
718
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
722
// Compute derivatives on reference element as dot product of coefficients and basisvalues
723
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
726
// Transform derivatives back to physical element
727
for (unsigned int row = 0; row < num_derivatives; row++)
729
for (unsigned int col = 0; col < num_derivatives; col++)
731
values[row] += transform[row][col]*derivatives[col];
734
// Delete pointer to array of derivatives on FIAT element
735
delete [] derivatives;
737
// Delete pointer to array of combinations of derivatives and transform
738
for (unsigned int row = 0; row < num_derivatives; row++)
740
delete [] combinations[row];
741
delete [] transform[row];
744
delete [] combinations;
748
/// Evaluate order n derivatives of all basis functions at given point in cell
749
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
751
const double* coordinates,
752
const ufc::cell& c) const
754
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
757
/// Evaluate linear functional for dof i on the function f
758
double UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_dof(unsigned int i,
759
const ufc::function& f,
760
const ufc::cell& c) const
762
// The reference points, direction and weights:
763
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
764
const static double W[3][1] = {{1}, {1}, {1}};
765
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
767
const double * const * x = c.coordinates;
769
// Iterate over the points:
770
// Evaluate basis functions for affine mapping
771
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
772
const double w1 = X[i][0][0];
773
const double w2 = X[i][0][1];
775
// Compute affine mapping y = F(X)
777
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
778
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
780
// Evaluate function at physical points
782
f.evaluate(values, y, c);
784
// Map function values using appropriate mapping
785
// Affine map: Do nothing
787
// Note that we do not map the weights (yet).
789
// Take directional components
790
for(int k = 0; k < 1; k++)
791
result += values[k]*D[i][0][k];
792
// Multiply by weights
798
/// Evaluate linear functionals for all dofs on the function f
799
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_dofs(double* values,
800
const ufc::function& f,
801
const ufc::cell& c) const
803
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
806
/// Interpolate vertex values from dof values
807
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
808
const double* dof_values,
809
const ufc::cell& c) const
811
// Evaluate at vertices and use affine mapping
812
vertex_values[0] = dof_values[0];
813
vertex_values[1] = dof_values[1];
814
vertex_values[2] = dof_values[2];
817
/// Return the number of sub elements (for a mixed element)
818
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::num_sub_elements() const
823
/// Create a new finite element for sub element i (for a mixed element)
824
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_0_1::create_sub_element(unsigned int i) const
826
return new UFC_CahnHilliard2DBilinearForm_finite_element_0_1();
831
UFC_CahnHilliard2DBilinearForm_finite_element_0::UFC_CahnHilliard2DBilinearForm_finite_element_0() : ufc::finite_element()
837
UFC_CahnHilliard2DBilinearForm_finite_element_0::~UFC_CahnHilliard2DBilinearForm_finite_element_0()
842
/// Return a string identifying the finite element
843
const char* UFC_CahnHilliard2DBilinearForm_finite_element_0::signature() const
845
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
848
/// Return the cell shape
849
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_0::cell_shape() const
851
return ufc::triangle;
854
/// Return the dimension of the finite element function space
855
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::space_dimension() const
860
/// Return the rank of the value space
861
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::value_rank() const
866
/// Return the dimension of the value space for axis i
867
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::value_dimension(unsigned int i) const
872
/// Evaluate basis function i at given point in cell
873
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis(unsigned int i,
875
const double* coordinates,
876
const ufc::cell& c) const
878
// Extract vertex coordinates
879
const double * const * element_coordinates = c.coordinates;
881
// Compute Jacobian of affine map from reference cell
882
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
883
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
884
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
885
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
887
// Compute determinant of Jacobian
888
const double detJ = J_00*J_11 - J_01*J_10;
890
// Compute inverse of Jacobian
892
// Get coordinates and map to the reference (UFC) element
893
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
894
element_coordinates[0][0]*element_coordinates[2][1] +\
895
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
896
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
897
element_coordinates[1][0]*element_coordinates[0][1] -\
898
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
900
// Map coordinates to the reference square
901
if (std::abs(y - 1.0) < 1e-14)
904
x = 2.0 *x/(1.0 - y) - 1.0;
911
if (0 <= i && i <= 2)
913
// Map degree of freedom to element degree of freedom
914
const unsigned int dof = i;
917
const double scalings_y_0 = 1;
918
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
920
// Compute psitilde_a
921
const double psitilde_a_0 = 1;
922
const double psitilde_a_1 = x;
924
// Compute psitilde_bs
925
const double psitilde_bs_0_0 = 1;
926
const double psitilde_bs_0_1 = 1.5*y + 0.5;
927
const double psitilde_bs_1_0 = 1;
929
// Compute basisvalues
930
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
931
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
932
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
934
// Table(s) of coefficients
935
const static double coefficients0[3][3] = \
936
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
937
{0.471404520791032, 0.288675134594813, -0.166666666666667},
938
{0.471404520791032, 0, 0.333333333333333}};
940
// Extract relevant coefficients
941
const double coeff0_0 = coefficients0[dof][0];
942
const double coeff0_1 = coefficients0[dof][1];
943
const double coeff0_2 = coefficients0[dof][2];
946
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
949
if (3 <= i && i <= 5)
951
// Map degree of freedom to element degree of freedom
952
const unsigned int dof = i - 3;
955
const double scalings_y_0 = 1;
956
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
958
// Compute psitilde_a
959
const double psitilde_a_0 = 1;
960
const double psitilde_a_1 = x;
962
// Compute psitilde_bs
963
const double psitilde_bs_0_0 = 1;
964
const double psitilde_bs_0_1 = 1.5*y + 0.5;
965
const double psitilde_bs_1_0 = 1;
967
// Compute basisvalues
968
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
969
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
970
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
972
// Table(s) of coefficients
973
const static double coefficients0[3][3] = \
974
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
975
{0.471404520791032, 0.288675134594813, -0.166666666666667},
976
{0.471404520791032, 0, 0.333333333333333}};
978
// Extract relevant coefficients
979
const double coeff0_0 = coefficients0[dof][0];
980
const double coeff0_1 = coefficients0[dof][1];
981
const double coeff0_2 = coefficients0[dof][2];
984
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
989
/// Evaluate all basis functions at given point in cell
990
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis_all(double* values,
991
const double* coordinates,
992
const ufc::cell& c) const
994
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
997
/// Evaluate order n derivatives of basis function i at given point in cell
998
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis_derivatives(unsigned int i,
1001
const double* coordinates,
1002
const ufc::cell& c) const
1004
// Extract vertex coordinates
1005
const double * const * element_coordinates = c.coordinates;
1007
// Compute Jacobian of affine map from reference cell
1008
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1009
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1010
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1011
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1013
// Compute determinant of Jacobian
1014
const double detJ = J_00*J_11 - J_01*J_10;
1016
// Compute inverse of Jacobian
1018
// Get coordinates and map to the reference (UFC) element
1019
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1020
element_coordinates[0][0]*element_coordinates[2][1] +\
1021
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1022
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1023
element_coordinates[1][0]*element_coordinates[0][1] -\
1024
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1026
// Map coordinates to the reference square
1027
if (std::abs(y - 1.0) < 1e-14)
1030
x = 2.0 *x/(1.0 - y) - 1.0;
1033
// Compute number of derivatives
1034
unsigned int num_derivatives = 1;
1036
for (unsigned int j = 0; j < n; j++)
1037
num_derivatives *= 2;
1040
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1041
unsigned int **combinations = new unsigned int *[num_derivatives];
1043
for (unsigned int j = 0; j < num_derivatives; j++)
1045
combinations[j] = new unsigned int [n];
1046
for (unsigned int k = 0; k < n; k++)
1047
combinations[j][k] = 0;
1050
// Generate combinations of derivatives
1051
for (unsigned int row = 1; row < num_derivatives; row++)
1053
for (unsigned int num = 0; num < row; num++)
1055
for (unsigned int col = n-1; col+1 > 0; col--)
1057
if (combinations[row][col] + 1 > 1)
1058
combinations[row][col] = 0;
1061
combinations[row][col] += 1;
1068
// Compute inverse of Jacobian
1069
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1071
// Declare transformation matrix
1072
// Declare pointer to two dimensional array and initialise
1073
double **transform = new double *[num_derivatives];
1075
for (unsigned int j = 0; j < num_derivatives; j++)
1077
transform[j] = new double [num_derivatives];
1078
for (unsigned int k = 0; k < num_derivatives; k++)
1079
transform[j][k] = 1;
1082
// Construct transformation matrix
1083
for (unsigned int row = 0; row < num_derivatives; row++)
1085
for (unsigned int col = 0; col < num_derivatives; col++)
1087
for (unsigned int k = 0; k < n; k++)
1088
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1093
for (unsigned int j = 0; j < 2*num_derivatives; j++)
1096
if (0 <= i && i <= 2)
1098
// Map degree of freedom to element degree of freedom
1099
const unsigned int dof = i;
1101
// Generate scalings
1102
const double scalings_y_0 = 1;
1103
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1105
// Compute psitilde_a
1106
const double psitilde_a_0 = 1;
1107
const double psitilde_a_1 = x;
1109
// Compute psitilde_bs
1110
const double psitilde_bs_0_0 = 1;
1111
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1112
const double psitilde_bs_1_0 = 1;
1114
// Compute basisvalues
1115
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1116
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1117
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1119
// Table(s) of coefficients
1120
const static double coefficients0[3][3] = \
1121
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1122
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1123
{0.471404520791032, 0, 0.333333333333333}};
1125
// Interesting (new) part
1126
// Tables of derivatives of the polynomial base (transpose)
1127
const static double dmats0[3][3] = \
1129
{4.89897948556636, 0, 0},
1132
const static double dmats1[3][3] = \
1134
{2.44948974278318, 0, 0},
1135
{4.24264068711928, 0, 0}};
1137
// Compute reference derivatives
1138
// Declare pointer to array of derivatives on FIAT element
1139
double *derivatives = new double [num_derivatives];
1141
// Declare coefficients
1142
double coeff0_0 = 0;
1143
double coeff0_1 = 0;
1144
double coeff0_2 = 0;
1146
// Declare new coefficients
1147
double new_coeff0_0 = 0;
1148
double new_coeff0_1 = 0;
1149
double new_coeff0_2 = 0;
1151
// Loop possible derivatives
1152
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1154
// Get values from coefficients array
1155
new_coeff0_0 = coefficients0[dof][0];
1156
new_coeff0_1 = coefficients0[dof][1];
1157
new_coeff0_2 = coefficients0[dof][2];
1159
// Loop derivative order
1160
for (unsigned int j = 0; j < n; j++)
1162
// Update old coefficients
1163
coeff0_0 = new_coeff0_0;
1164
coeff0_1 = new_coeff0_1;
1165
coeff0_2 = new_coeff0_2;
1167
if(combinations[deriv_num][j] == 0)
1169
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1170
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1171
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1173
if(combinations[deriv_num][j] == 1)
1175
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1176
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1177
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1181
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1182
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1185
// Transform derivatives back to physical element
1186
for (unsigned int row = 0; row < num_derivatives; row++)
1188
for (unsigned int col = 0; col < num_derivatives; col++)
1190
values[row] += transform[row][col]*derivatives[col];
1193
// Delete pointer to array of derivatives on FIAT element
1194
delete [] derivatives;
1196
// Delete pointer to array of combinations of derivatives and transform
1197
for (unsigned int row = 0; row < num_derivatives; row++)
1199
delete [] combinations[row];
1200
delete [] transform[row];
1203
delete [] combinations;
1204
delete [] transform;
1207
if (3 <= i && i <= 5)
1209
// Map degree of freedom to element degree of freedom
1210
const unsigned int dof = i - 3;
1212
// Generate scalings
1213
const double scalings_y_0 = 1;
1214
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1216
// Compute psitilde_a
1217
const double psitilde_a_0 = 1;
1218
const double psitilde_a_1 = x;
1220
// Compute psitilde_bs
1221
const double psitilde_bs_0_0 = 1;
1222
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1223
const double psitilde_bs_1_0 = 1;
1225
// Compute basisvalues
1226
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1227
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1228
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1230
// Table(s) of coefficients
1231
const static double coefficients0[3][3] = \
1232
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1233
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1234
{0.471404520791032, 0, 0.333333333333333}};
1236
// Interesting (new) part
1237
// Tables of derivatives of the polynomial base (transpose)
1238
const static double dmats0[3][3] = \
1240
{4.89897948556636, 0, 0},
1243
const static double dmats1[3][3] = \
1245
{2.44948974278318, 0, 0},
1246
{4.24264068711928, 0, 0}};
1248
// Compute reference derivatives
1249
// Declare pointer to array of derivatives on FIAT element
1250
double *derivatives = new double [num_derivatives];
1252
// Declare coefficients
1253
double coeff0_0 = 0;
1254
double coeff0_1 = 0;
1255
double coeff0_2 = 0;
1257
// Declare new coefficients
1258
double new_coeff0_0 = 0;
1259
double new_coeff0_1 = 0;
1260
double new_coeff0_2 = 0;
1262
// Loop possible derivatives
1263
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1265
// Get values from coefficients array
1266
new_coeff0_0 = coefficients0[dof][0];
1267
new_coeff0_1 = coefficients0[dof][1];
1268
new_coeff0_2 = coefficients0[dof][2];
1270
// Loop derivative order
1271
for (unsigned int j = 0; j < n; j++)
1273
// Update old coefficients
1274
coeff0_0 = new_coeff0_0;
1275
coeff0_1 = new_coeff0_1;
1276
coeff0_2 = new_coeff0_2;
1278
if(combinations[deriv_num][j] == 0)
1280
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1281
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1282
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1284
if(combinations[deriv_num][j] == 1)
1286
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1287
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1288
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1292
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1293
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1296
// Transform derivatives back to physical element
1297
for (unsigned int row = 0; row < num_derivatives; row++)
1299
for (unsigned int col = 0; col < num_derivatives; col++)
1301
values[num_derivatives + row] += transform[row][col]*derivatives[col];
1304
// Delete pointer to array of derivatives on FIAT element
1305
delete [] derivatives;
1307
// Delete pointer to array of combinations of derivatives and transform
1308
for (unsigned int row = 0; row < num_derivatives; row++)
1310
delete [] combinations[row];
1311
delete [] transform[row];
1314
delete [] combinations;
1315
delete [] transform;
1320
/// Evaluate order n derivatives of all basis functions at given point in cell
1321
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
1323
const double* coordinates,
1324
const ufc::cell& c) const
1326
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1329
/// Evaluate linear functional for dof i on the function f
1330
double UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_dof(unsigned int i,
1331
const ufc::function& f,
1332
const ufc::cell& c) const
1334
// The reference points, direction and weights:
1335
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
1336
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
1337
const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
1339
const double * const * x = c.coordinates;
1340
double result = 0.0;
1341
// Iterate over the points:
1342
// Evaluate basis functions for affine mapping
1343
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1344
const double w1 = X[i][0][0];
1345
const double w2 = X[i][0][1];
1347
// Compute affine mapping y = F(X)
1349
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1350
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1352
// Evaluate function at physical points
1354
f.evaluate(values, y, c);
1356
// Map function values using appropriate mapping
1357
// Affine map: Do nothing
1359
// Note that we do not map the weights (yet).
1361
// Take directional components
1362
for(int k = 0; k < 2; k++)
1363
result += values[k]*D[i][0][k];
1364
// Multiply by weights
1370
/// Evaluate linear functionals for all dofs on the function f
1371
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_dofs(double* values,
1372
const ufc::function& f,
1373
const ufc::cell& c) const
1375
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1378
/// Interpolate vertex values from dof values
1379
void UFC_CahnHilliard2DBilinearForm_finite_element_0::interpolate_vertex_values(double* vertex_values,
1380
const double* dof_values,
1381
const ufc::cell& c) const
1383
// Evaluate at vertices and use affine mapping
1384
vertex_values[0] = dof_values[0];
1385
vertex_values[2] = dof_values[1];
1386
vertex_values[4] = dof_values[2];
1387
// Evaluate at vertices and use affine mapping
1388
vertex_values[1] = dof_values[3];
1389
vertex_values[3] = dof_values[4];
1390
vertex_values[5] = dof_values[5];
1393
/// Return the number of sub elements (for a mixed element)
1394
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::num_sub_elements() const
1399
/// Create a new finite element for sub element i (for a mixed element)
1400
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_0::create_sub_element(unsigned int i) const
1405
return new UFC_CahnHilliard2DBilinearForm_finite_element_0_0();
1408
return new UFC_CahnHilliard2DBilinearForm_finite_element_0_1();
1416
UFC_CahnHilliard2DBilinearForm_finite_element_1_0::UFC_CahnHilliard2DBilinearForm_finite_element_1_0() : ufc::finite_element()
1422
UFC_CahnHilliard2DBilinearForm_finite_element_1_0::~UFC_CahnHilliard2DBilinearForm_finite_element_1_0()
1427
/// Return a string identifying the finite element
1428
const char* UFC_CahnHilliard2DBilinearForm_finite_element_1_0::signature() const
1430
return "FiniteElement('Lagrange', 'triangle', 1)";
1433
/// Return the cell shape
1434
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_1_0::cell_shape() const
1436
return ufc::triangle;
1439
/// Return the dimension of the finite element function space
1440
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::space_dimension() const
1445
/// Return the rank of the value space
1446
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::value_rank() const
1451
/// Return the dimension of the value space for axis i
1452
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::value_dimension(unsigned int i) const
1457
/// Evaluate basis function i at given point in cell
1458
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis(unsigned int i,
1460
const double* coordinates,
1461
const ufc::cell& c) const
1463
// Extract vertex coordinates
1464
const double * const * element_coordinates = c.coordinates;
1466
// Compute Jacobian of affine map from reference cell
1467
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1468
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1469
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1470
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1472
// Compute determinant of Jacobian
1473
const double detJ = J_00*J_11 - J_01*J_10;
1475
// Compute inverse of Jacobian
1477
// Get coordinates and map to the reference (UFC) element
1478
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1479
element_coordinates[0][0]*element_coordinates[2][1] +\
1480
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1481
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1482
element_coordinates[1][0]*element_coordinates[0][1] -\
1483
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1485
// Map coordinates to the reference square
1486
if (std::abs(y - 1.0) < 1e-14)
1489
x = 2.0 *x/(1.0 - y) - 1.0;
1495
// Map degree of freedom to element degree of freedom
1496
const unsigned int dof = i;
1498
// Generate scalings
1499
const double scalings_y_0 = 1;
1500
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1502
// Compute psitilde_a
1503
const double psitilde_a_0 = 1;
1504
const double psitilde_a_1 = x;
1506
// Compute psitilde_bs
1507
const double psitilde_bs_0_0 = 1;
1508
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1509
const double psitilde_bs_1_0 = 1;
1511
// Compute basisvalues
1512
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1513
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1514
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1516
// Table(s) of coefficients
1517
const static double coefficients0[3][3] = \
1518
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1519
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1520
{0.471404520791032, 0, 0.333333333333333}};
1522
// Extract relevant coefficients
1523
const double coeff0_0 = coefficients0[dof][0];
1524
const double coeff0_1 = coefficients0[dof][1];
1525
const double coeff0_2 = coefficients0[dof][2];
1528
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1531
/// Evaluate all basis functions at given point in cell
1532
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis_all(double* values,
1533
const double* coordinates,
1534
const ufc::cell& c) const
1536
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1539
/// Evaluate order n derivatives of basis function i at given point in cell
1540
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
1543
const double* coordinates,
1544
const ufc::cell& c) const
1546
// Extract vertex coordinates
1547
const double * const * element_coordinates = c.coordinates;
1549
// Compute Jacobian of affine map from reference cell
1550
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1551
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1552
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1553
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1555
// Compute determinant of Jacobian
1556
const double detJ = J_00*J_11 - J_01*J_10;
1558
// Compute inverse of Jacobian
1560
// Get coordinates and map to the reference (UFC) element
1561
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1562
element_coordinates[0][0]*element_coordinates[2][1] +\
1563
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1564
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1565
element_coordinates[1][0]*element_coordinates[0][1] -\
1566
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1568
// Map coordinates to the reference square
1569
if (std::abs(y - 1.0) < 1e-14)
1572
x = 2.0 *x/(1.0 - y) - 1.0;
1575
// Compute number of derivatives
1576
unsigned int num_derivatives = 1;
1578
for (unsigned int j = 0; j < n; j++)
1579
num_derivatives *= 2;
1582
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1583
unsigned int **combinations = new unsigned int *[num_derivatives];
1585
for (unsigned int j = 0; j < num_derivatives; j++)
1587
combinations[j] = new unsigned int [n];
1588
for (unsigned int k = 0; k < n; k++)
1589
combinations[j][k] = 0;
1592
// Generate combinations of derivatives
1593
for (unsigned int row = 1; row < num_derivatives; row++)
1595
for (unsigned int num = 0; num < row; num++)
1597
for (unsigned int col = n-1; col+1 > 0; col--)
1599
if (combinations[row][col] + 1 > 1)
1600
combinations[row][col] = 0;
1603
combinations[row][col] += 1;
1610
// Compute inverse of Jacobian
1611
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1613
// Declare transformation matrix
1614
// Declare pointer to two dimensional array and initialise
1615
double **transform = new double *[num_derivatives];
1617
for (unsigned int j = 0; j < num_derivatives; j++)
1619
transform[j] = new double [num_derivatives];
1620
for (unsigned int k = 0; k < num_derivatives; k++)
1621
transform[j][k] = 1;
1624
// Construct transformation matrix
1625
for (unsigned int row = 0; row < num_derivatives; row++)
1627
for (unsigned int col = 0; col < num_derivatives; col++)
1629
for (unsigned int k = 0; k < n; k++)
1630
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1635
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1638
// Map degree of freedom to element degree of freedom
1639
const unsigned int dof = i;
1641
// Generate scalings
1642
const double scalings_y_0 = 1;
1643
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1645
// Compute psitilde_a
1646
const double psitilde_a_0 = 1;
1647
const double psitilde_a_1 = x;
1649
// Compute psitilde_bs
1650
const double psitilde_bs_0_0 = 1;
1651
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1652
const double psitilde_bs_1_0 = 1;
1654
// Compute basisvalues
1655
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1656
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1657
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1659
// Table(s) of coefficients
1660
const static double coefficients0[3][3] = \
1661
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1662
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1663
{0.471404520791032, 0, 0.333333333333333}};
1665
// Interesting (new) part
1666
// Tables of derivatives of the polynomial base (transpose)
1667
const static double dmats0[3][3] = \
1669
{4.89897948556636, 0, 0},
1672
const static double dmats1[3][3] = \
1674
{2.44948974278318, 0, 0},
1675
{4.24264068711928, 0, 0}};
1677
// Compute reference derivatives
1678
// Declare pointer to array of derivatives on FIAT element
1679
double *derivatives = new double [num_derivatives];
1681
// Declare coefficients
1682
double coeff0_0 = 0;
1683
double coeff0_1 = 0;
1684
double coeff0_2 = 0;
1686
// Declare new coefficients
1687
double new_coeff0_0 = 0;
1688
double new_coeff0_1 = 0;
1689
double new_coeff0_2 = 0;
1691
// Loop possible derivatives
1692
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1694
// Get values from coefficients array
1695
new_coeff0_0 = coefficients0[dof][0];
1696
new_coeff0_1 = coefficients0[dof][1];
1697
new_coeff0_2 = coefficients0[dof][2];
1699
// Loop derivative order
1700
for (unsigned int j = 0; j < n; j++)
1702
// Update old coefficients
1703
coeff0_0 = new_coeff0_0;
1704
coeff0_1 = new_coeff0_1;
1705
coeff0_2 = new_coeff0_2;
1707
if(combinations[deriv_num][j] == 0)
1709
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1710
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1711
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1713
if(combinations[deriv_num][j] == 1)
1715
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1716
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1717
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1721
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1722
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1725
// Transform derivatives back to physical element
1726
for (unsigned int row = 0; row < num_derivatives; row++)
1728
for (unsigned int col = 0; col < num_derivatives; col++)
1730
values[row] += transform[row][col]*derivatives[col];
1733
// Delete pointer to array of derivatives on FIAT element
1734
delete [] derivatives;
1736
// Delete pointer to array of combinations of derivatives and transform
1737
for (unsigned int row = 0; row < num_derivatives; row++)
1739
delete [] combinations[row];
1740
delete [] transform[row];
1743
delete [] combinations;
1744
delete [] transform;
1747
/// Evaluate order n derivatives of all basis functions at given point in cell
1748
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
1750
const double* coordinates,
1751
const ufc::cell& c) const
1753
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1756
/// Evaluate linear functional for dof i on the function f
1757
double UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_dof(unsigned int i,
1758
const ufc::function& f,
1759
const ufc::cell& c) const
1761
// The reference points, direction and weights:
1762
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
1763
const static double W[3][1] = {{1}, {1}, {1}};
1764
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
1766
const double * const * x = c.coordinates;
1767
double result = 0.0;
1768
// Iterate over the points:
1769
// Evaluate basis functions for affine mapping
1770
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1771
const double w1 = X[i][0][0];
1772
const double w2 = X[i][0][1];
1774
// Compute affine mapping y = F(X)
1776
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1777
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1779
// Evaluate function at physical points
1781
f.evaluate(values, y, c);
1783
// Map function values using appropriate mapping
1784
// Affine map: Do nothing
1786
// Note that we do not map the weights (yet).
1788
// Take directional components
1789
for(int k = 0; k < 1; k++)
1790
result += values[k]*D[i][0][k];
1791
// Multiply by weights
1797
/// Evaluate linear functionals for all dofs on the function f
1798
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_dofs(double* values,
1799
const ufc::function& f,
1800
const ufc::cell& c) const
1802
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1805
/// Interpolate vertex values from dof values
1806
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
1807
const double* dof_values,
1808
const ufc::cell& c) const
1810
// Evaluate at vertices and use affine mapping
1811
vertex_values[0] = dof_values[0];
1812
vertex_values[1] = dof_values[1];
1813
vertex_values[2] = dof_values[2];
1816
/// Return the number of sub elements (for a mixed element)
1817
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::num_sub_elements() const
1822
/// Create a new finite element for sub element i (for a mixed element)
1823
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_1_0::create_sub_element(unsigned int i) const
1825
return new UFC_CahnHilliard2DBilinearForm_finite_element_1_0();
1830
UFC_CahnHilliard2DBilinearForm_finite_element_1_1::UFC_CahnHilliard2DBilinearForm_finite_element_1_1() : ufc::finite_element()
1836
UFC_CahnHilliard2DBilinearForm_finite_element_1_1::~UFC_CahnHilliard2DBilinearForm_finite_element_1_1()
1841
/// Return a string identifying the finite element
1842
const char* UFC_CahnHilliard2DBilinearForm_finite_element_1_1::signature() const
1844
return "FiniteElement('Lagrange', 'triangle', 1)";
1847
/// Return the cell shape
1848
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_1_1::cell_shape() const
1850
return ufc::triangle;
1853
/// Return the dimension of the finite element function space
1854
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::space_dimension() const
1859
/// Return the rank of the value space
1860
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::value_rank() const
1865
/// Return the dimension of the value space for axis i
1866
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::value_dimension(unsigned int i) const
1871
/// Evaluate basis function i at given point in cell
1872
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis(unsigned int i,
1874
const double* coordinates,
1875
const ufc::cell& c) const
1877
// Extract vertex coordinates
1878
const double * const * element_coordinates = c.coordinates;
1880
// Compute Jacobian of affine map from reference cell
1881
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1882
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1883
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1884
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1886
// Compute determinant of Jacobian
1887
const double detJ = J_00*J_11 - J_01*J_10;
1889
// Compute inverse of Jacobian
1891
// Get coordinates and map to the reference (UFC) element
1892
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1893
element_coordinates[0][0]*element_coordinates[2][1] +\
1894
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1895
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1896
element_coordinates[1][0]*element_coordinates[0][1] -\
1897
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1899
// Map coordinates to the reference square
1900
if (std::abs(y - 1.0) < 1e-14)
1903
x = 2.0 *x/(1.0 - y) - 1.0;
1909
// Map degree of freedom to element degree of freedom
1910
const unsigned int dof = i;
1912
// Generate scalings
1913
const double scalings_y_0 = 1;
1914
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1916
// Compute psitilde_a
1917
const double psitilde_a_0 = 1;
1918
const double psitilde_a_1 = x;
1920
// Compute psitilde_bs
1921
const double psitilde_bs_0_0 = 1;
1922
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1923
const double psitilde_bs_1_0 = 1;
1925
// Compute basisvalues
1926
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1927
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1928
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1930
// Table(s) of coefficients
1931
const static double coefficients0[3][3] = \
1932
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1933
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1934
{0.471404520791032, 0, 0.333333333333333}};
1936
// Extract relevant coefficients
1937
const double coeff0_0 = coefficients0[dof][0];
1938
const double coeff0_1 = coefficients0[dof][1];
1939
const double coeff0_2 = coefficients0[dof][2];
1942
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1945
/// Evaluate all basis functions at given point in cell
1946
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis_all(double* values,
1947
const double* coordinates,
1948
const ufc::cell& c) const
1950
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1953
/// Evaluate order n derivatives of basis function i at given point in cell
1954
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
1957
const double* coordinates,
1958
const ufc::cell& c) const
1960
// Extract vertex coordinates
1961
const double * const * element_coordinates = c.coordinates;
1963
// Compute Jacobian of affine map from reference cell
1964
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1965
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1966
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1967
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1969
// Compute determinant of Jacobian
1970
const double detJ = J_00*J_11 - J_01*J_10;
1972
// Compute inverse of Jacobian
1974
// Get coordinates and map to the reference (UFC) element
1975
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1976
element_coordinates[0][0]*element_coordinates[2][1] +\
1977
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1978
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1979
element_coordinates[1][0]*element_coordinates[0][1] -\
1980
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1982
// Map coordinates to the reference square
1983
if (std::abs(y - 1.0) < 1e-14)
1986
x = 2.0 *x/(1.0 - y) - 1.0;
1989
// Compute number of derivatives
1990
unsigned int num_derivatives = 1;
1992
for (unsigned int j = 0; j < n; j++)
1993
num_derivatives *= 2;
1996
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1997
unsigned int **combinations = new unsigned int *[num_derivatives];
1999
for (unsigned int j = 0; j < num_derivatives; j++)
2001
combinations[j] = new unsigned int [n];
2002
for (unsigned int k = 0; k < n; k++)
2003
combinations[j][k] = 0;
2006
// Generate combinations of derivatives
2007
for (unsigned int row = 1; row < num_derivatives; row++)
2009
for (unsigned int num = 0; num < row; num++)
2011
for (unsigned int col = n-1; col+1 > 0; col--)
2013
if (combinations[row][col] + 1 > 1)
2014
combinations[row][col] = 0;
2017
combinations[row][col] += 1;
2024
// Compute inverse of Jacobian
2025
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2027
// Declare transformation matrix
2028
// Declare pointer to two dimensional array and initialise
2029
double **transform = new double *[num_derivatives];
2031
for (unsigned int j = 0; j < num_derivatives; j++)
2033
transform[j] = new double [num_derivatives];
2034
for (unsigned int k = 0; k < num_derivatives; k++)
2035
transform[j][k] = 1;
2038
// Construct transformation matrix
2039
for (unsigned int row = 0; row < num_derivatives; row++)
2041
for (unsigned int col = 0; col < num_derivatives; col++)
2043
for (unsigned int k = 0; k < n; k++)
2044
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2049
for (unsigned int j = 0; j < 1*num_derivatives; j++)
2052
// Map degree of freedom to element degree of freedom
2053
const unsigned int dof = i;
2055
// Generate scalings
2056
const double scalings_y_0 = 1;
2057
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2059
// Compute psitilde_a
2060
const double psitilde_a_0 = 1;
2061
const double psitilde_a_1 = x;
2063
// Compute psitilde_bs
2064
const double psitilde_bs_0_0 = 1;
2065
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2066
const double psitilde_bs_1_0 = 1;
2068
// Compute basisvalues
2069
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2070
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2071
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2073
// Table(s) of coefficients
2074
const static double coefficients0[3][3] = \
2075
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2076
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2077
{0.471404520791032, 0, 0.333333333333333}};
2079
// Interesting (new) part
2080
// Tables of derivatives of the polynomial base (transpose)
2081
const static double dmats0[3][3] = \
2083
{4.89897948556636, 0, 0},
2086
const static double dmats1[3][3] = \
2088
{2.44948974278318, 0, 0},
2089
{4.24264068711928, 0, 0}};
2091
// Compute reference derivatives
2092
// Declare pointer to array of derivatives on FIAT element
2093
double *derivatives = new double [num_derivatives];
2095
// Declare coefficients
2096
double coeff0_0 = 0;
2097
double coeff0_1 = 0;
2098
double coeff0_2 = 0;
2100
// Declare new coefficients
2101
double new_coeff0_0 = 0;
2102
double new_coeff0_1 = 0;
2103
double new_coeff0_2 = 0;
2105
// Loop possible derivatives
2106
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2108
// Get values from coefficients array
2109
new_coeff0_0 = coefficients0[dof][0];
2110
new_coeff0_1 = coefficients0[dof][1];
2111
new_coeff0_2 = coefficients0[dof][2];
2113
// Loop derivative order
2114
for (unsigned int j = 0; j < n; j++)
2116
// Update old coefficients
2117
coeff0_0 = new_coeff0_0;
2118
coeff0_1 = new_coeff0_1;
2119
coeff0_2 = new_coeff0_2;
2121
if(combinations[deriv_num][j] == 0)
2123
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2124
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2125
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2127
if(combinations[deriv_num][j] == 1)
2129
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2130
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2131
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2135
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2136
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2139
// Transform derivatives back to physical element
2140
for (unsigned int row = 0; row < num_derivatives; row++)
2142
for (unsigned int col = 0; col < num_derivatives; col++)
2144
values[row] += transform[row][col]*derivatives[col];
2147
// Delete pointer to array of derivatives on FIAT element
2148
delete [] derivatives;
2150
// Delete pointer to array of combinations of derivatives and transform
2151
for (unsigned int row = 0; row < num_derivatives; row++)
2153
delete [] combinations[row];
2154
delete [] transform[row];
2157
delete [] combinations;
2158
delete [] transform;
2161
/// Evaluate order n derivatives of all basis functions at given point in cell
2162
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
2164
const double* coordinates,
2165
const ufc::cell& c) const
2167
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2170
/// Evaluate linear functional for dof i on the function f
2171
double UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_dof(unsigned int i,
2172
const ufc::function& f,
2173
const ufc::cell& c) const
2175
// The reference points, direction and weights:
2176
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
2177
const static double W[3][1] = {{1}, {1}, {1}};
2178
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
2180
const double * const * x = c.coordinates;
2181
double result = 0.0;
2182
// Iterate over the points:
2183
// Evaluate basis functions for affine mapping
2184
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2185
const double w1 = X[i][0][0];
2186
const double w2 = X[i][0][1];
2188
// Compute affine mapping y = F(X)
2190
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2191
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2193
// Evaluate function at physical points
2195
f.evaluate(values, y, c);
2197
// Map function values using appropriate mapping
2198
// Affine map: Do nothing
2200
// Note that we do not map the weights (yet).
2202
// Take directional components
2203
for(int k = 0; k < 1; k++)
2204
result += values[k]*D[i][0][k];
2205
// Multiply by weights
2211
/// Evaluate linear functionals for all dofs on the function f
2212
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_dofs(double* values,
2213
const ufc::function& f,
2214
const ufc::cell& c) const
2216
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2219
/// Interpolate vertex values from dof values
2220
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
2221
const double* dof_values,
2222
const ufc::cell& c) const
2224
// Evaluate at vertices and use affine mapping
2225
vertex_values[0] = dof_values[0];
2226
vertex_values[1] = dof_values[1];
2227
vertex_values[2] = dof_values[2];
2230
/// Return the number of sub elements (for a mixed element)
2231
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::num_sub_elements() const
2236
/// Create a new finite element for sub element i (for a mixed element)
2237
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_1_1::create_sub_element(unsigned int i) const
2239
return new UFC_CahnHilliard2DBilinearForm_finite_element_1_1();
2244
UFC_CahnHilliard2DBilinearForm_finite_element_1::UFC_CahnHilliard2DBilinearForm_finite_element_1() : ufc::finite_element()
2250
UFC_CahnHilliard2DBilinearForm_finite_element_1::~UFC_CahnHilliard2DBilinearForm_finite_element_1()
2255
/// Return a string identifying the finite element
2256
const char* UFC_CahnHilliard2DBilinearForm_finite_element_1::signature() const
2258
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
2261
/// Return the cell shape
2262
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_1::cell_shape() const
2264
return ufc::triangle;
2267
/// Return the dimension of the finite element function space
2268
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::space_dimension() const
2273
/// Return the rank of the value space
2274
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::value_rank() const
2279
/// Return the dimension of the value space for axis i
2280
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::value_dimension(unsigned int i) const
2285
/// Evaluate basis function i at given point in cell
2286
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis(unsigned int i,
2288
const double* coordinates,
2289
const ufc::cell& c) const
2291
// Extract vertex coordinates
2292
const double * const * element_coordinates = c.coordinates;
2294
// Compute Jacobian of affine map from reference cell
2295
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2296
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2297
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2298
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2300
// Compute determinant of Jacobian
2301
const double detJ = J_00*J_11 - J_01*J_10;
2303
// Compute inverse of Jacobian
2305
// Get coordinates and map to the reference (UFC) element
2306
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2307
element_coordinates[0][0]*element_coordinates[2][1] +\
2308
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2309
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2310
element_coordinates[1][0]*element_coordinates[0][1] -\
2311
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2313
// Map coordinates to the reference square
2314
if (std::abs(y - 1.0) < 1e-14)
2317
x = 2.0 *x/(1.0 - y) - 1.0;
2324
if (0 <= i && i <= 2)
2326
// Map degree of freedom to element degree of freedom
2327
const unsigned int dof = i;
2329
// Generate scalings
2330
const double scalings_y_0 = 1;
2331
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2333
// Compute psitilde_a
2334
const double psitilde_a_0 = 1;
2335
const double psitilde_a_1 = x;
2337
// Compute psitilde_bs
2338
const double psitilde_bs_0_0 = 1;
2339
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2340
const double psitilde_bs_1_0 = 1;
2342
// Compute basisvalues
2343
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2344
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2345
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2347
// Table(s) of coefficients
2348
const static double coefficients0[3][3] = \
2349
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2350
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2351
{0.471404520791032, 0, 0.333333333333333}};
2353
// Extract relevant coefficients
2354
const double coeff0_0 = coefficients0[dof][0];
2355
const double coeff0_1 = coefficients0[dof][1];
2356
const double coeff0_2 = coefficients0[dof][2];
2359
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2362
if (3 <= i && i <= 5)
2364
// Map degree of freedom to element degree of freedom
2365
const unsigned int dof = i - 3;
2367
// Generate scalings
2368
const double scalings_y_0 = 1;
2369
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2371
// Compute psitilde_a
2372
const double psitilde_a_0 = 1;
2373
const double psitilde_a_1 = x;
2375
// Compute psitilde_bs
2376
const double psitilde_bs_0_0 = 1;
2377
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2378
const double psitilde_bs_1_0 = 1;
2380
// Compute basisvalues
2381
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2382
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2383
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2385
// Table(s) of coefficients
2386
const static double coefficients0[3][3] = \
2387
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2388
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2389
{0.471404520791032, 0, 0.333333333333333}};
2391
// Extract relevant coefficients
2392
const double coeff0_0 = coefficients0[dof][0];
2393
const double coeff0_1 = coefficients0[dof][1];
2394
const double coeff0_2 = coefficients0[dof][2];
2397
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2402
/// Evaluate all basis functions at given point in cell
2403
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis_all(double* values,
2404
const double* coordinates,
2405
const ufc::cell& c) const
2407
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2410
/// Evaluate order n derivatives of basis function i at given point in cell
2411
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis_derivatives(unsigned int i,
2414
const double* coordinates,
2415
const ufc::cell& c) const
2417
// Extract vertex coordinates
2418
const double * const * element_coordinates = c.coordinates;
2420
// Compute Jacobian of affine map from reference cell
2421
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2422
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2423
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2424
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2426
// Compute determinant of Jacobian
2427
const double detJ = J_00*J_11 - J_01*J_10;
2429
// Compute inverse of Jacobian
2431
// Get coordinates and map to the reference (UFC) element
2432
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2433
element_coordinates[0][0]*element_coordinates[2][1] +\
2434
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2435
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2436
element_coordinates[1][0]*element_coordinates[0][1] -\
2437
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2439
// Map coordinates to the reference square
2440
if (std::abs(y - 1.0) < 1e-14)
2443
x = 2.0 *x/(1.0 - y) - 1.0;
2446
// Compute number of derivatives
2447
unsigned int num_derivatives = 1;
2449
for (unsigned int j = 0; j < n; j++)
2450
num_derivatives *= 2;
2453
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2454
unsigned int **combinations = new unsigned int *[num_derivatives];
2456
for (unsigned int j = 0; j < num_derivatives; j++)
2458
combinations[j] = new unsigned int [n];
2459
for (unsigned int k = 0; k < n; k++)
2460
combinations[j][k] = 0;
2463
// Generate combinations of derivatives
2464
for (unsigned int row = 1; row < num_derivatives; row++)
2466
for (unsigned int num = 0; num < row; num++)
2468
for (unsigned int col = n-1; col+1 > 0; col--)
2470
if (combinations[row][col] + 1 > 1)
2471
combinations[row][col] = 0;
2474
combinations[row][col] += 1;
2481
// Compute inverse of Jacobian
2482
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2484
// Declare transformation matrix
2485
// Declare pointer to two dimensional array and initialise
2486
double **transform = new double *[num_derivatives];
2488
for (unsigned int j = 0; j < num_derivatives; j++)
2490
transform[j] = new double [num_derivatives];
2491
for (unsigned int k = 0; k < num_derivatives; k++)
2492
transform[j][k] = 1;
2495
// Construct transformation matrix
2496
for (unsigned int row = 0; row < num_derivatives; row++)
2498
for (unsigned int col = 0; col < num_derivatives; col++)
2500
for (unsigned int k = 0; k < n; k++)
2501
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2506
for (unsigned int j = 0; j < 2*num_derivatives; j++)
2509
if (0 <= i && i <= 2)
2511
// Map degree of freedom to element degree of freedom
2512
const unsigned int dof = i;
2514
// Generate scalings
2515
const double scalings_y_0 = 1;
2516
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2518
// Compute psitilde_a
2519
const double psitilde_a_0 = 1;
2520
const double psitilde_a_1 = x;
2522
// Compute psitilde_bs
2523
const double psitilde_bs_0_0 = 1;
2524
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2525
const double psitilde_bs_1_0 = 1;
2527
// Compute basisvalues
2528
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2529
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2530
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2532
// Table(s) of coefficients
2533
const static double coefficients0[3][3] = \
2534
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2535
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2536
{0.471404520791032, 0, 0.333333333333333}};
2538
// Interesting (new) part
2539
// Tables of derivatives of the polynomial base (transpose)
2540
const static double dmats0[3][3] = \
2542
{4.89897948556636, 0, 0},
2545
const static double dmats1[3][3] = \
2547
{2.44948974278318, 0, 0},
2548
{4.24264068711928, 0, 0}};
2550
// Compute reference derivatives
2551
// Declare pointer to array of derivatives on FIAT element
2552
double *derivatives = new double [num_derivatives];
2554
// Declare coefficients
2555
double coeff0_0 = 0;
2556
double coeff0_1 = 0;
2557
double coeff0_2 = 0;
2559
// Declare new coefficients
2560
double new_coeff0_0 = 0;
2561
double new_coeff0_1 = 0;
2562
double new_coeff0_2 = 0;
2564
// Loop possible derivatives
2565
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2567
// Get values from coefficients array
2568
new_coeff0_0 = coefficients0[dof][0];
2569
new_coeff0_1 = coefficients0[dof][1];
2570
new_coeff0_2 = coefficients0[dof][2];
2572
// Loop derivative order
2573
for (unsigned int j = 0; j < n; j++)
2575
// Update old coefficients
2576
coeff0_0 = new_coeff0_0;
2577
coeff0_1 = new_coeff0_1;
2578
coeff0_2 = new_coeff0_2;
2580
if(combinations[deriv_num][j] == 0)
2582
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2583
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2584
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2586
if(combinations[deriv_num][j] == 1)
2588
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2589
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2590
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2594
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2595
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2598
// Transform derivatives back to physical element
2599
for (unsigned int row = 0; row < num_derivatives; row++)
2601
for (unsigned int col = 0; col < num_derivatives; col++)
2603
values[row] += transform[row][col]*derivatives[col];
2606
// Delete pointer to array of derivatives on FIAT element
2607
delete [] derivatives;
2609
// Delete pointer to array of combinations of derivatives and transform
2610
for (unsigned int row = 0; row < num_derivatives; row++)
2612
delete [] combinations[row];
2613
delete [] transform[row];
2616
delete [] combinations;
2617
delete [] transform;
2620
if (3 <= i && i <= 5)
2622
// Map degree of freedom to element degree of freedom
2623
const unsigned int dof = i - 3;
2625
// Generate scalings
2626
const double scalings_y_0 = 1;
2627
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2629
// Compute psitilde_a
2630
const double psitilde_a_0 = 1;
2631
const double psitilde_a_1 = x;
2633
// Compute psitilde_bs
2634
const double psitilde_bs_0_0 = 1;
2635
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2636
const double psitilde_bs_1_0 = 1;
2638
// Compute basisvalues
2639
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2640
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2641
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2643
// Table(s) of coefficients
2644
const static double coefficients0[3][3] = \
2645
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2646
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2647
{0.471404520791032, 0, 0.333333333333333}};
2649
// Interesting (new) part
2650
// Tables of derivatives of the polynomial base (transpose)
2651
const static double dmats0[3][3] = \
2653
{4.89897948556636, 0, 0},
2656
const static double dmats1[3][3] = \
2658
{2.44948974278318, 0, 0},
2659
{4.24264068711928, 0, 0}};
2661
// Compute reference derivatives
2662
// Declare pointer to array of derivatives on FIAT element
2663
double *derivatives = new double [num_derivatives];
2665
// Declare coefficients
2666
double coeff0_0 = 0;
2667
double coeff0_1 = 0;
2668
double coeff0_2 = 0;
2670
// Declare new coefficients
2671
double new_coeff0_0 = 0;
2672
double new_coeff0_1 = 0;
2673
double new_coeff0_2 = 0;
2675
// Loop possible derivatives
2676
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2678
// Get values from coefficients array
2679
new_coeff0_0 = coefficients0[dof][0];
2680
new_coeff0_1 = coefficients0[dof][1];
2681
new_coeff0_2 = coefficients0[dof][2];
2683
// Loop derivative order
2684
for (unsigned int j = 0; j < n; j++)
2686
// Update old coefficients
2687
coeff0_0 = new_coeff0_0;
2688
coeff0_1 = new_coeff0_1;
2689
coeff0_2 = new_coeff0_2;
2691
if(combinations[deriv_num][j] == 0)
2693
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2694
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2695
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2697
if(combinations[deriv_num][j] == 1)
2699
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2700
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2701
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2705
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2706
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2709
// Transform derivatives back to physical element
2710
for (unsigned int row = 0; row < num_derivatives; row++)
2712
for (unsigned int col = 0; col < num_derivatives; col++)
2714
values[num_derivatives + row] += transform[row][col]*derivatives[col];
2717
// Delete pointer to array of derivatives on FIAT element
2718
delete [] derivatives;
2720
// Delete pointer to array of combinations of derivatives and transform
2721
for (unsigned int row = 0; row < num_derivatives; row++)
2723
delete [] combinations[row];
2724
delete [] transform[row];
2727
delete [] combinations;
2728
delete [] transform;
2733
/// Evaluate order n derivatives of all basis functions at given point in cell
2734
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
2736
const double* coordinates,
2737
const ufc::cell& c) const
2739
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2742
/// Evaluate linear functional for dof i on the function f
2743
double UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_dof(unsigned int i,
2744
const ufc::function& f,
2745
const ufc::cell& c) const
2747
// The reference points, direction and weights:
2748
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
2749
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
2750
const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
2752
const double * const * x = c.coordinates;
2753
double result = 0.0;
2754
// Iterate over the points:
2755
// Evaluate basis functions for affine mapping
2756
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2757
const double w1 = X[i][0][0];
2758
const double w2 = X[i][0][1];
2760
// Compute affine mapping y = F(X)
2762
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2763
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2765
// Evaluate function at physical points
2767
f.evaluate(values, y, c);
2769
// Map function values using appropriate mapping
2770
// Affine map: Do nothing
2772
// Note that we do not map the weights (yet).
2774
// Take directional components
2775
for(int k = 0; k < 2; k++)
2776
result += values[k]*D[i][0][k];
2777
// Multiply by weights
2783
/// Evaluate linear functionals for all dofs on the function f
2784
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_dofs(double* values,
2785
const ufc::function& f,
2786
const ufc::cell& c) const
2788
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2791
/// Interpolate vertex values from dof values
2792
void UFC_CahnHilliard2DBilinearForm_finite_element_1::interpolate_vertex_values(double* vertex_values,
2793
const double* dof_values,
2794
const ufc::cell& c) const
2796
// Evaluate at vertices and use affine mapping
2797
vertex_values[0] = dof_values[0];
2798
vertex_values[2] = dof_values[1];
2799
vertex_values[4] = dof_values[2];
2800
// Evaluate at vertices and use affine mapping
2801
vertex_values[1] = dof_values[3];
2802
vertex_values[3] = dof_values[4];
2803
vertex_values[5] = dof_values[5];
2806
/// Return the number of sub elements (for a mixed element)
2807
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::num_sub_elements() const
2812
/// Create a new finite element for sub element i (for a mixed element)
2813
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_1::create_sub_element(unsigned int i) const
2818
return new UFC_CahnHilliard2DBilinearForm_finite_element_1_0();
2821
return new UFC_CahnHilliard2DBilinearForm_finite_element_1_1();
2829
UFC_CahnHilliard2DBilinearForm_finite_element_2_0::UFC_CahnHilliard2DBilinearForm_finite_element_2_0() : ufc::finite_element()
2835
UFC_CahnHilliard2DBilinearForm_finite_element_2_0::~UFC_CahnHilliard2DBilinearForm_finite_element_2_0()
2840
/// Return a string identifying the finite element
2841
const char* UFC_CahnHilliard2DBilinearForm_finite_element_2_0::signature() const
2843
return "FiniteElement('Lagrange', 'triangle', 1)";
2846
/// Return the cell shape
2847
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_2_0::cell_shape() const
2849
return ufc::triangle;
2852
/// Return the dimension of the finite element function space
2853
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::space_dimension() const
2858
/// Return the rank of the value space
2859
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::value_rank() const
2864
/// Return the dimension of the value space for axis i
2865
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::value_dimension(unsigned int i) const
2870
/// Evaluate basis function i at given point in cell
2871
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis(unsigned int i,
2873
const double* coordinates,
2874
const ufc::cell& c) const
2876
// Extract vertex coordinates
2877
const double * const * element_coordinates = c.coordinates;
2879
// Compute Jacobian of affine map from reference cell
2880
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2881
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2882
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2883
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2885
// Compute determinant of Jacobian
2886
const double detJ = J_00*J_11 - J_01*J_10;
2888
// Compute inverse of Jacobian
2890
// Get coordinates and map to the reference (UFC) element
2891
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2892
element_coordinates[0][0]*element_coordinates[2][1] +\
2893
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2894
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2895
element_coordinates[1][0]*element_coordinates[0][1] -\
2896
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2898
// Map coordinates to the reference square
2899
if (std::abs(y - 1.0) < 1e-14)
2902
x = 2.0 *x/(1.0 - y) - 1.0;
2908
// Map degree of freedom to element degree of freedom
2909
const unsigned int dof = i;
2911
// Generate scalings
2912
const double scalings_y_0 = 1;
2913
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2915
// Compute psitilde_a
2916
const double psitilde_a_0 = 1;
2917
const double psitilde_a_1 = x;
2919
// Compute psitilde_bs
2920
const double psitilde_bs_0_0 = 1;
2921
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2922
const double psitilde_bs_1_0 = 1;
2924
// Compute basisvalues
2925
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2926
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2927
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2929
// Table(s) of coefficients
2930
const static double coefficients0[3][3] = \
2931
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2932
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2933
{0.471404520791032, 0, 0.333333333333333}};
2935
// Extract relevant coefficients
2936
const double coeff0_0 = coefficients0[dof][0];
2937
const double coeff0_1 = coefficients0[dof][1];
2938
const double coeff0_2 = coefficients0[dof][2];
2941
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2944
/// Evaluate all basis functions at given point in cell
2945
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis_all(double* values,
2946
const double* coordinates,
2947
const ufc::cell& c) const
2949
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2952
/// Evaluate order n derivatives of basis function i at given point in cell
2953
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis_derivatives(unsigned int i,
2956
const double* coordinates,
2957
const ufc::cell& c) const
2959
// Extract vertex coordinates
2960
const double * const * element_coordinates = c.coordinates;
2962
// Compute Jacobian of affine map from reference cell
2963
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2964
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2965
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2966
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2968
// Compute determinant of Jacobian
2969
const double detJ = J_00*J_11 - J_01*J_10;
2971
// Compute inverse of Jacobian
2973
// Get coordinates and map to the reference (UFC) element
2974
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2975
element_coordinates[0][0]*element_coordinates[2][1] +\
2976
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2977
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2978
element_coordinates[1][0]*element_coordinates[0][1] -\
2979
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2981
// Map coordinates to the reference square
2982
if (std::abs(y - 1.0) < 1e-14)
2985
x = 2.0 *x/(1.0 - y) - 1.0;
2988
// Compute number of derivatives
2989
unsigned int num_derivatives = 1;
2991
for (unsigned int j = 0; j < n; j++)
2992
num_derivatives *= 2;
2995
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2996
unsigned int **combinations = new unsigned int *[num_derivatives];
2998
for (unsigned int j = 0; j < num_derivatives; j++)
3000
combinations[j] = new unsigned int [n];
3001
for (unsigned int k = 0; k < n; k++)
3002
combinations[j][k] = 0;
3005
// Generate combinations of derivatives
3006
for (unsigned int row = 1; row < num_derivatives; row++)
3008
for (unsigned int num = 0; num < row; num++)
3010
for (unsigned int col = n-1; col+1 > 0; col--)
3012
if (combinations[row][col] + 1 > 1)
3013
combinations[row][col] = 0;
3016
combinations[row][col] += 1;
3023
// Compute inverse of Jacobian
3024
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3026
// Declare transformation matrix
3027
// Declare pointer to two dimensional array and initialise
3028
double **transform = new double *[num_derivatives];
3030
for (unsigned int j = 0; j < num_derivatives; j++)
3032
transform[j] = new double [num_derivatives];
3033
for (unsigned int k = 0; k < num_derivatives; k++)
3034
transform[j][k] = 1;
3037
// Construct transformation matrix
3038
for (unsigned int row = 0; row < num_derivatives; row++)
3040
for (unsigned int col = 0; col < num_derivatives; col++)
3042
for (unsigned int k = 0; k < n; k++)
3043
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3048
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3051
// Map degree of freedom to element degree of freedom
3052
const unsigned int dof = i;
3054
// Generate scalings
3055
const double scalings_y_0 = 1;
3056
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3058
// Compute psitilde_a
3059
const double psitilde_a_0 = 1;
3060
const double psitilde_a_1 = x;
3062
// Compute psitilde_bs
3063
const double psitilde_bs_0_0 = 1;
3064
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3065
const double psitilde_bs_1_0 = 1;
3067
// Compute basisvalues
3068
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3069
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3070
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3072
// Table(s) of coefficients
3073
const static double coefficients0[3][3] = \
3074
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3075
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3076
{0.471404520791032, 0, 0.333333333333333}};
3078
// Interesting (new) part
3079
// Tables of derivatives of the polynomial base (transpose)
3080
const static double dmats0[3][3] = \
3082
{4.89897948556636, 0, 0},
3085
const static double dmats1[3][3] = \
3087
{2.44948974278318, 0, 0},
3088
{4.24264068711928, 0, 0}};
3090
// Compute reference derivatives
3091
// Declare pointer to array of derivatives on FIAT element
3092
double *derivatives = new double [num_derivatives];
3094
// Declare coefficients
3095
double coeff0_0 = 0;
3096
double coeff0_1 = 0;
3097
double coeff0_2 = 0;
3099
// Declare new coefficients
3100
double new_coeff0_0 = 0;
3101
double new_coeff0_1 = 0;
3102
double new_coeff0_2 = 0;
3104
// Loop possible derivatives
3105
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3107
// Get values from coefficients array
3108
new_coeff0_0 = coefficients0[dof][0];
3109
new_coeff0_1 = coefficients0[dof][1];
3110
new_coeff0_2 = coefficients0[dof][2];
3112
// Loop derivative order
3113
for (unsigned int j = 0; j < n; j++)
3115
// Update old coefficients
3116
coeff0_0 = new_coeff0_0;
3117
coeff0_1 = new_coeff0_1;
3118
coeff0_2 = new_coeff0_2;
3120
if(combinations[deriv_num][j] == 0)
3122
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3123
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3124
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3126
if(combinations[deriv_num][j] == 1)
3128
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3129
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3130
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3134
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3135
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3138
// Transform derivatives back to physical element
3139
for (unsigned int row = 0; row < num_derivatives; row++)
3141
for (unsigned int col = 0; col < num_derivatives; col++)
3143
values[row] += transform[row][col]*derivatives[col];
3146
// Delete pointer to array of derivatives on FIAT element
3147
delete [] derivatives;
3149
// Delete pointer to array of combinations of derivatives and transform
3150
for (unsigned int row = 0; row < num_derivatives; row++)
3152
delete [] combinations[row];
3153
delete [] transform[row];
3156
delete [] combinations;
3157
delete [] transform;
3160
/// Evaluate order n derivatives of all basis functions at given point in cell
3161
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
3163
const double* coordinates,
3164
const ufc::cell& c) const
3166
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3169
/// Evaluate linear functional for dof i on the function f
3170
double UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_dof(unsigned int i,
3171
const ufc::function& f,
3172
const ufc::cell& c) const
3174
// The reference points, direction and weights:
3175
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3176
const static double W[3][1] = {{1}, {1}, {1}};
3177
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3179
const double * const * x = c.coordinates;
3180
double result = 0.0;
3181
// Iterate over the points:
3182
// Evaluate basis functions for affine mapping
3183
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3184
const double w1 = X[i][0][0];
3185
const double w2 = X[i][0][1];
3187
// Compute affine mapping y = F(X)
3189
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3190
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3192
// Evaluate function at physical points
3194
f.evaluate(values, y, c);
3196
// Map function values using appropriate mapping
3197
// Affine map: Do nothing
3199
// Note that we do not map the weights (yet).
3201
// Take directional components
3202
for(int k = 0; k < 1; k++)
3203
result += values[k]*D[i][0][k];
3204
// Multiply by weights
3210
/// Evaluate linear functionals for all dofs on the function f
3211
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_dofs(double* values,
3212
const ufc::function& f,
3213
const ufc::cell& c) const
3215
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3218
/// Interpolate vertex values from dof values
3219
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
3220
const double* dof_values,
3221
const ufc::cell& c) const
3223
// Evaluate at vertices and use affine mapping
3224
vertex_values[0] = dof_values[0];
3225
vertex_values[1] = dof_values[1];
3226
vertex_values[2] = dof_values[2];
3229
/// Return the number of sub elements (for a mixed element)
3230
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::num_sub_elements() const
3235
/// Create a new finite element for sub element i (for a mixed element)
3236
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_2_0::create_sub_element(unsigned int i) const
3238
return new UFC_CahnHilliard2DBilinearForm_finite_element_2_0();
3243
UFC_CahnHilliard2DBilinearForm_finite_element_2_1::UFC_CahnHilliard2DBilinearForm_finite_element_2_1() : ufc::finite_element()
3249
UFC_CahnHilliard2DBilinearForm_finite_element_2_1::~UFC_CahnHilliard2DBilinearForm_finite_element_2_1()
3254
/// Return a string identifying the finite element
3255
const char* UFC_CahnHilliard2DBilinearForm_finite_element_2_1::signature() const
3257
return "FiniteElement('Lagrange', 'triangle', 1)";
3260
/// Return the cell shape
3261
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_2_1::cell_shape() const
3263
return ufc::triangle;
3266
/// Return the dimension of the finite element function space
3267
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::space_dimension() const
3272
/// Return the rank of the value space
3273
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::value_rank() const
3278
/// Return the dimension of the value space for axis i
3279
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::value_dimension(unsigned int i) const
3284
/// Evaluate basis function i at given point in cell
3285
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis(unsigned int i,
3287
const double* coordinates,
3288
const ufc::cell& c) const
3290
// Extract vertex coordinates
3291
const double * const * element_coordinates = c.coordinates;
3293
// Compute Jacobian of affine map from reference cell
3294
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3295
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3296
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3297
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3299
// Compute determinant of Jacobian
3300
const double detJ = J_00*J_11 - J_01*J_10;
3302
// Compute inverse of Jacobian
3304
// Get coordinates and map to the reference (UFC) element
3305
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3306
element_coordinates[0][0]*element_coordinates[2][1] +\
3307
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3308
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3309
element_coordinates[1][0]*element_coordinates[0][1] -\
3310
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3312
// Map coordinates to the reference square
3313
if (std::abs(y - 1.0) < 1e-14)
3316
x = 2.0 *x/(1.0 - y) - 1.0;
3322
// Map degree of freedom to element degree of freedom
3323
const unsigned int dof = i;
3325
// Generate scalings
3326
const double scalings_y_0 = 1;
3327
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3329
// Compute psitilde_a
3330
const double psitilde_a_0 = 1;
3331
const double psitilde_a_1 = x;
3333
// Compute psitilde_bs
3334
const double psitilde_bs_0_0 = 1;
3335
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3336
const double psitilde_bs_1_0 = 1;
3338
// Compute basisvalues
3339
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3340
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3341
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3343
// Table(s) of coefficients
3344
const static double coefficients0[3][3] = \
3345
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3346
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3347
{0.471404520791032, 0, 0.333333333333333}};
3349
// Extract relevant coefficients
3350
const double coeff0_0 = coefficients0[dof][0];
3351
const double coeff0_1 = coefficients0[dof][1];
3352
const double coeff0_2 = coefficients0[dof][2];
3355
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3358
/// Evaluate all basis functions at given point in cell
3359
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis_all(double* values,
3360
const double* coordinates,
3361
const ufc::cell& c) const
3363
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3366
/// Evaluate order n derivatives of basis function i at given point in cell
3367
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
3370
const double* coordinates,
3371
const ufc::cell& c) const
3373
// Extract vertex coordinates
3374
const double * const * element_coordinates = c.coordinates;
3376
// Compute Jacobian of affine map from reference cell
3377
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3378
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3379
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3380
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3382
// Compute determinant of Jacobian
3383
const double detJ = J_00*J_11 - J_01*J_10;
3385
// Compute inverse of Jacobian
3387
// Get coordinates and map to the reference (UFC) element
3388
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3389
element_coordinates[0][0]*element_coordinates[2][1] +\
3390
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3391
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3392
element_coordinates[1][0]*element_coordinates[0][1] -\
3393
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3395
// Map coordinates to the reference square
3396
if (std::abs(y - 1.0) < 1e-14)
3399
x = 2.0 *x/(1.0 - y) - 1.0;
3402
// Compute number of derivatives
3403
unsigned int num_derivatives = 1;
3405
for (unsigned int j = 0; j < n; j++)
3406
num_derivatives *= 2;
3409
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3410
unsigned int **combinations = new unsigned int *[num_derivatives];
3412
for (unsigned int j = 0; j < num_derivatives; j++)
3414
combinations[j] = new unsigned int [n];
3415
for (unsigned int k = 0; k < n; k++)
3416
combinations[j][k] = 0;
3419
// Generate combinations of derivatives
3420
for (unsigned int row = 1; row < num_derivatives; row++)
3422
for (unsigned int num = 0; num < row; num++)
3424
for (unsigned int col = n-1; col+1 > 0; col--)
3426
if (combinations[row][col] + 1 > 1)
3427
combinations[row][col] = 0;
3430
combinations[row][col] += 1;
3437
// Compute inverse of Jacobian
3438
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3440
// Declare transformation matrix
3441
// Declare pointer to two dimensional array and initialise
3442
double **transform = new double *[num_derivatives];
3444
for (unsigned int j = 0; j < num_derivatives; j++)
3446
transform[j] = new double [num_derivatives];
3447
for (unsigned int k = 0; k < num_derivatives; k++)
3448
transform[j][k] = 1;
3451
// Construct transformation matrix
3452
for (unsigned int row = 0; row < num_derivatives; row++)
3454
for (unsigned int col = 0; col < num_derivatives; col++)
3456
for (unsigned int k = 0; k < n; k++)
3457
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3462
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3465
// Map degree of freedom to element degree of freedom
3466
const unsigned int dof = i;
3468
// Generate scalings
3469
const double scalings_y_0 = 1;
3470
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3472
// Compute psitilde_a
3473
const double psitilde_a_0 = 1;
3474
const double psitilde_a_1 = x;
3476
// Compute psitilde_bs
3477
const double psitilde_bs_0_0 = 1;
3478
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3479
const double psitilde_bs_1_0 = 1;
3481
// Compute basisvalues
3482
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3483
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3484
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3486
// Table(s) of coefficients
3487
const static double coefficients0[3][3] = \
3488
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3489
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3490
{0.471404520791032, 0, 0.333333333333333}};
3492
// Interesting (new) part
3493
// Tables of derivatives of the polynomial base (transpose)
3494
const static double dmats0[3][3] = \
3496
{4.89897948556636, 0, 0},
3499
const static double dmats1[3][3] = \
3501
{2.44948974278318, 0, 0},
3502
{4.24264068711928, 0, 0}};
3504
// Compute reference derivatives
3505
// Declare pointer to array of derivatives on FIAT element
3506
double *derivatives = new double [num_derivatives];
3508
// Declare coefficients
3509
double coeff0_0 = 0;
3510
double coeff0_1 = 0;
3511
double coeff0_2 = 0;
3513
// Declare new coefficients
3514
double new_coeff0_0 = 0;
3515
double new_coeff0_1 = 0;
3516
double new_coeff0_2 = 0;
3518
// Loop possible derivatives
3519
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3521
// Get values from coefficients array
3522
new_coeff0_0 = coefficients0[dof][0];
3523
new_coeff0_1 = coefficients0[dof][1];
3524
new_coeff0_2 = coefficients0[dof][2];
3526
// Loop derivative order
3527
for (unsigned int j = 0; j < n; j++)
3529
// Update old coefficients
3530
coeff0_0 = new_coeff0_0;
3531
coeff0_1 = new_coeff0_1;
3532
coeff0_2 = new_coeff0_2;
3534
if(combinations[deriv_num][j] == 0)
3536
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3537
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3538
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3540
if(combinations[deriv_num][j] == 1)
3542
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3543
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3544
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3548
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3549
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3552
// Transform derivatives back to physical element
3553
for (unsigned int row = 0; row < num_derivatives; row++)
3555
for (unsigned int col = 0; col < num_derivatives; col++)
3557
values[row] += transform[row][col]*derivatives[col];
3560
// Delete pointer to array of derivatives on FIAT element
3561
delete [] derivatives;
3563
// Delete pointer to array of combinations of derivatives and transform
3564
for (unsigned int row = 0; row < num_derivatives; row++)
3566
delete [] combinations[row];
3567
delete [] transform[row];
3570
delete [] combinations;
3571
delete [] transform;
3574
/// Evaluate order n derivatives of all basis functions at given point in cell
3575
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
3577
const double* coordinates,
3578
const ufc::cell& c) const
3580
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3583
/// Evaluate linear functional for dof i on the function f
3584
double UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_dof(unsigned int i,
3585
const ufc::function& f,
3586
const ufc::cell& c) const
3588
// The reference points, direction and weights:
3589
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3590
const static double W[3][1] = {{1}, {1}, {1}};
3591
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3593
const double * const * x = c.coordinates;
3594
double result = 0.0;
3595
// Iterate over the points:
3596
// Evaluate basis functions for affine mapping
3597
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3598
const double w1 = X[i][0][0];
3599
const double w2 = X[i][0][1];
3601
// Compute affine mapping y = F(X)
3603
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3604
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3606
// Evaluate function at physical points
3608
f.evaluate(values, y, c);
3610
// Map function values using appropriate mapping
3611
// Affine map: Do nothing
3613
// Note that we do not map the weights (yet).
3615
// Take directional components
3616
for(int k = 0; k < 1; k++)
3617
result += values[k]*D[i][0][k];
3618
// Multiply by weights
3624
/// Evaluate linear functionals for all dofs on the function f
3625
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_dofs(double* values,
3626
const ufc::function& f,
3627
const ufc::cell& c) const
3629
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3632
/// Interpolate vertex values from dof values
3633
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
3634
const double* dof_values,
3635
const ufc::cell& c) const
3637
// Evaluate at vertices and use affine mapping
3638
vertex_values[0] = dof_values[0];
3639
vertex_values[1] = dof_values[1];
3640
vertex_values[2] = dof_values[2];
3643
/// Return the number of sub elements (for a mixed element)
3644
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::num_sub_elements() const
3649
/// Create a new finite element for sub element i (for a mixed element)
3650
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_2_1::create_sub_element(unsigned int i) const
3652
return new UFC_CahnHilliard2DBilinearForm_finite_element_2_1();
3657
UFC_CahnHilliard2DBilinearForm_finite_element_2::UFC_CahnHilliard2DBilinearForm_finite_element_2() : ufc::finite_element()
3663
UFC_CahnHilliard2DBilinearForm_finite_element_2::~UFC_CahnHilliard2DBilinearForm_finite_element_2()
3668
/// Return a string identifying the finite element
3669
const char* UFC_CahnHilliard2DBilinearForm_finite_element_2::signature() const
3671
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
3674
/// Return the cell shape
3675
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_2::cell_shape() const
3677
return ufc::triangle;
3680
/// Return the dimension of the finite element function space
3681
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::space_dimension() const
3686
/// Return the rank of the value space
3687
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::value_rank() const
3692
/// Return the dimension of the value space for axis i
3693
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::value_dimension(unsigned int i) const
3698
/// Evaluate basis function i at given point in cell
3699
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis(unsigned int i,
3701
const double* coordinates,
3702
const ufc::cell& c) const
3704
// Extract vertex coordinates
3705
const double * const * element_coordinates = c.coordinates;
3707
// Compute Jacobian of affine map from reference cell
3708
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3709
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3710
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3711
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3713
// Compute determinant of Jacobian
3714
const double detJ = J_00*J_11 - J_01*J_10;
3716
// Compute inverse of Jacobian
3718
// Get coordinates and map to the reference (UFC) element
3719
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3720
element_coordinates[0][0]*element_coordinates[2][1] +\
3721
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3722
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3723
element_coordinates[1][0]*element_coordinates[0][1] -\
3724
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3726
// Map coordinates to the reference square
3727
if (std::abs(y - 1.0) < 1e-14)
3730
x = 2.0 *x/(1.0 - y) - 1.0;
3737
if (0 <= i && i <= 2)
3739
// Map degree of freedom to element degree of freedom
3740
const unsigned int dof = i;
3742
// Generate scalings
3743
const double scalings_y_0 = 1;
3744
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3746
// Compute psitilde_a
3747
const double psitilde_a_0 = 1;
3748
const double psitilde_a_1 = x;
3750
// Compute psitilde_bs
3751
const double psitilde_bs_0_0 = 1;
3752
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3753
const double psitilde_bs_1_0 = 1;
3755
// Compute basisvalues
3756
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3757
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3758
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3760
// Table(s) of coefficients
3761
const static double coefficients0[3][3] = \
3762
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3763
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3764
{0.471404520791032, 0, 0.333333333333333}};
3766
// Extract relevant coefficients
3767
const double coeff0_0 = coefficients0[dof][0];
3768
const double coeff0_1 = coefficients0[dof][1];
3769
const double coeff0_2 = coefficients0[dof][2];
3772
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3775
if (3 <= i && i <= 5)
3777
// Map degree of freedom to element degree of freedom
3778
const unsigned int dof = i - 3;
3780
// Generate scalings
3781
const double scalings_y_0 = 1;
3782
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3784
// Compute psitilde_a
3785
const double psitilde_a_0 = 1;
3786
const double psitilde_a_1 = x;
3788
// Compute psitilde_bs
3789
const double psitilde_bs_0_0 = 1;
3790
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3791
const double psitilde_bs_1_0 = 1;
3793
// Compute basisvalues
3794
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3795
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3796
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3798
// Table(s) of coefficients
3799
const static double coefficients0[3][3] = \
3800
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3801
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3802
{0.471404520791032, 0, 0.333333333333333}};
3804
// Extract relevant coefficients
3805
const double coeff0_0 = coefficients0[dof][0];
3806
const double coeff0_1 = coefficients0[dof][1];
3807
const double coeff0_2 = coefficients0[dof][2];
3810
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3815
/// Evaluate all basis functions at given point in cell
3816
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis_all(double* values,
3817
const double* coordinates,
3818
const ufc::cell& c) const
3820
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3823
/// Evaluate order n derivatives of basis function i at given point in cell
3824
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis_derivatives(unsigned int i,
3827
const double* coordinates,
3828
const ufc::cell& c) const
3830
// Extract vertex coordinates
3831
const double * const * element_coordinates = c.coordinates;
3833
// Compute Jacobian of affine map from reference cell
3834
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3835
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3836
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3837
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3839
// Compute determinant of Jacobian
3840
const double detJ = J_00*J_11 - J_01*J_10;
3842
// Compute inverse of Jacobian
3844
// Get coordinates and map to the reference (UFC) element
3845
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3846
element_coordinates[0][0]*element_coordinates[2][1] +\
3847
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3848
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3849
element_coordinates[1][0]*element_coordinates[0][1] -\
3850
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3852
// Map coordinates to the reference square
3853
if (std::abs(y - 1.0) < 1e-14)
3856
x = 2.0 *x/(1.0 - y) - 1.0;
3859
// Compute number of derivatives
3860
unsigned int num_derivatives = 1;
3862
for (unsigned int j = 0; j < n; j++)
3863
num_derivatives *= 2;
3866
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3867
unsigned int **combinations = new unsigned int *[num_derivatives];
3869
for (unsigned int j = 0; j < num_derivatives; j++)
3871
combinations[j] = new unsigned int [n];
3872
for (unsigned int k = 0; k < n; k++)
3873
combinations[j][k] = 0;
3876
// Generate combinations of derivatives
3877
for (unsigned int row = 1; row < num_derivatives; row++)
3879
for (unsigned int num = 0; num < row; num++)
3881
for (unsigned int col = n-1; col+1 > 0; col--)
3883
if (combinations[row][col] + 1 > 1)
3884
combinations[row][col] = 0;
3887
combinations[row][col] += 1;
3894
// Compute inverse of Jacobian
3895
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3897
// Declare transformation matrix
3898
// Declare pointer to two dimensional array and initialise
3899
double **transform = new double *[num_derivatives];
3901
for (unsigned int j = 0; j < num_derivatives; j++)
3903
transform[j] = new double [num_derivatives];
3904
for (unsigned int k = 0; k < num_derivatives; k++)
3905
transform[j][k] = 1;
3908
// Construct transformation matrix
3909
for (unsigned int row = 0; row < num_derivatives; row++)
3911
for (unsigned int col = 0; col < num_derivatives; col++)
3913
for (unsigned int k = 0; k < n; k++)
3914
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3919
for (unsigned int j = 0; j < 2*num_derivatives; j++)
3922
if (0 <= i && i <= 2)
3924
// Map degree of freedom to element degree of freedom
3925
const unsigned int dof = i;
3927
// Generate scalings
3928
const double scalings_y_0 = 1;
3929
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3931
// Compute psitilde_a
3932
const double psitilde_a_0 = 1;
3933
const double psitilde_a_1 = x;
3935
// Compute psitilde_bs
3936
const double psitilde_bs_0_0 = 1;
3937
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3938
const double psitilde_bs_1_0 = 1;
3940
// Compute basisvalues
3941
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3942
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3943
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3945
// Table(s) of coefficients
3946
const static double coefficients0[3][3] = \
3947
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3948
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3949
{0.471404520791032, 0, 0.333333333333333}};
3951
// Interesting (new) part
3952
// Tables of derivatives of the polynomial base (transpose)
3953
const static double dmats0[3][3] = \
3955
{4.89897948556636, 0, 0},
3958
const static double dmats1[3][3] = \
3960
{2.44948974278318, 0, 0},
3961
{4.24264068711928, 0, 0}};
3963
// Compute reference derivatives
3964
// Declare pointer to array of derivatives on FIAT element
3965
double *derivatives = new double [num_derivatives];
3967
// Declare coefficients
3968
double coeff0_0 = 0;
3969
double coeff0_1 = 0;
3970
double coeff0_2 = 0;
3972
// Declare new coefficients
3973
double new_coeff0_0 = 0;
3974
double new_coeff0_1 = 0;
3975
double new_coeff0_2 = 0;
3977
// Loop possible derivatives
3978
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3980
// Get values from coefficients array
3981
new_coeff0_0 = coefficients0[dof][0];
3982
new_coeff0_1 = coefficients0[dof][1];
3983
new_coeff0_2 = coefficients0[dof][2];
3985
// Loop derivative order
3986
for (unsigned int j = 0; j < n; j++)
3988
// Update old coefficients
3989
coeff0_0 = new_coeff0_0;
3990
coeff0_1 = new_coeff0_1;
3991
coeff0_2 = new_coeff0_2;
3993
if(combinations[deriv_num][j] == 0)
3995
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3996
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3997
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3999
if(combinations[deriv_num][j] == 1)
4001
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
4002
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
4003
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
4007
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4008
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
4011
// Transform derivatives back to physical element
4012
for (unsigned int row = 0; row < num_derivatives; row++)
4014
for (unsigned int col = 0; col < num_derivatives; col++)
4016
values[row] += transform[row][col]*derivatives[col];
4019
// Delete pointer to array of derivatives on FIAT element
4020
delete [] derivatives;
4022
// Delete pointer to array of combinations of derivatives and transform
4023
for (unsigned int row = 0; row < num_derivatives; row++)
4025
delete [] combinations[row];
4026
delete [] transform[row];
4029
delete [] combinations;
4030
delete [] transform;
4033
if (3 <= i && i <= 5)
4035
// Map degree of freedom to element degree of freedom
4036
const unsigned int dof = i - 3;
4038
// Generate scalings
4039
const double scalings_y_0 = 1;
4040
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4042
// Compute psitilde_a
4043
const double psitilde_a_0 = 1;
4044
const double psitilde_a_1 = x;
4046
// Compute psitilde_bs
4047
const double psitilde_bs_0_0 = 1;
4048
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4049
const double psitilde_bs_1_0 = 1;
4051
// Compute basisvalues
4052
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4053
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4054
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4056
// Table(s) of coefficients
4057
const static double coefficients0[3][3] = \
4058
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
4059
{0.471404520791032, 0.288675134594813, -0.166666666666667},
4060
{0.471404520791032, 0, 0.333333333333333}};
4062
// Interesting (new) part
4063
// Tables of derivatives of the polynomial base (transpose)
4064
const static double dmats0[3][3] = \
4066
{4.89897948556636, 0, 0},
4069
const static double dmats1[3][3] = \
4071
{2.44948974278318, 0, 0},
4072
{4.24264068711928, 0, 0}};
4074
// Compute reference derivatives
4075
// Declare pointer to array of derivatives on FIAT element
4076
double *derivatives = new double [num_derivatives];
4078
// Declare coefficients
4079
double coeff0_0 = 0;
4080
double coeff0_1 = 0;
4081
double coeff0_2 = 0;
4083
// Declare new coefficients
4084
double new_coeff0_0 = 0;
4085
double new_coeff0_1 = 0;
4086
double new_coeff0_2 = 0;
4088
// Loop possible derivatives
4089
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4091
// Get values from coefficients array
4092
new_coeff0_0 = coefficients0[dof][0];
4093
new_coeff0_1 = coefficients0[dof][1];
4094
new_coeff0_2 = coefficients0[dof][2];
4096
// Loop derivative order
4097
for (unsigned int j = 0; j < n; j++)
4099
// Update old coefficients
4100
coeff0_0 = new_coeff0_0;
4101
coeff0_1 = new_coeff0_1;
4102
coeff0_2 = new_coeff0_2;
4104
if(combinations[deriv_num][j] == 0)
4106
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
4107
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
4108
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
4110
if(combinations[deriv_num][j] == 1)
4112
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
4113
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
4114
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
4118
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4119
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
4122
// Transform derivatives back to physical element
4123
for (unsigned int row = 0; row < num_derivatives; row++)
4125
for (unsigned int col = 0; col < num_derivatives; col++)
4127
values[num_derivatives + row] += transform[row][col]*derivatives[col];
4130
// Delete pointer to array of derivatives on FIAT element
4131
delete [] derivatives;
4133
// Delete pointer to array of combinations of derivatives and transform
4134
for (unsigned int row = 0; row < num_derivatives; row++)
4136
delete [] combinations[row];
4137
delete [] transform[row];
4140
delete [] combinations;
4141
delete [] transform;
4146
/// Evaluate order n derivatives of all basis functions at given point in cell
4147
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
4149
const double* coordinates,
4150
const ufc::cell& c) const
4152
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4155
/// Evaluate linear functional for dof i on the function f
4156
double UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_dof(unsigned int i,
4157
const ufc::function& f,
4158
const ufc::cell& c) const
4160
// The reference points, direction and weights:
4161
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
4162
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
4163
const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
4165
const double * const * x = c.coordinates;
4166
double result = 0.0;
4167
// Iterate over the points:
4168
// Evaluate basis functions for affine mapping
4169
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4170
const double w1 = X[i][0][0];
4171
const double w2 = X[i][0][1];
4173
// Compute affine mapping y = F(X)
4175
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4176
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4178
// Evaluate function at physical points
4180
f.evaluate(values, y, c);
4182
// Map function values using appropriate mapping
4183
// Affine map: Do nothing
4185
// Note that we do not map the weights (yet).
4187
// Take directional components
4188
for(int k = 0; k < 2; k++)
4189
result += values[k]*D[i][0][k];
4190
// Multiply by weights
4196
/// Evaluate linear functionals for all dofs on the function f
4197
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_dofs(double* values,
4198
const ufc::function& f,
4199
const ufc::cell& c) const
4201
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4204
/// Interpolate vertex values from dof values
4205
void UFC_CahnHilliard2DBilinearForm_finite_element_2::interpolate_vertex_values(double* vertex_values,
4206
const double* dof_values,
4207
const ufc::cell& c) const
4209
// Evaluate at vertices and use affine mapping
4210
vertex_values[0] = dof_values[0];
4211
vertex_values[2] = dof_values[1];
4212
vertex_values[4] = dof_values[2];
4213
// Evaluate at vertices and use affine mapping
4214
vertex_values[1] = dof_values[3];
4215
vertex_values[3] = dof_values[4];
4216
vertex_values[5] = dof_values[5];
4219
/// Return the number of sub elements (for a mixed element)
4220
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::num_sub_elements() const
4225
/// Create a new finite element for sub element i (for a mixed element)
4226
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_2::create_sub_element(unsigned int i) const
4231
return new UFC_CahnHilliard2DBilinearForm_finite_element_2_0();
4234
return new UFC_CahnHilliard2DBilinearForm_finite_element_2_1();
4242
UFC_CahnHilliard2DBilinearForm_finite_element_3::UFC_CahnHilliard2DBilinearForm_finite_element_3() : ufc::finite_element()
4248
UFC_CahnHilliard2DBilinearForm_finite_element_3::~UFC_CahnHilliard2DBilinearForm_finite_element_3()
4253
/// Return a string identifying the finite element
4254
const char* UFC_CahnHilliard2DBilinearForm_finite_element_3::signature() const
4256
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
4259
/// Return the cell shape
4260
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_3::cell_shape() const
4262
return ufc::triangle;
4265
/// Return the dimension of the finite element function space
4266
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::space_dimension() const
4271
/// Return the rank of the value space
4272
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::value_rank() const
4277
/// Return the dimension of the value space for axis i
4278
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::value_dimension(unsigned int i) const
4283
/// Evaluate basis function i at given point in cell
4284
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis(unsigned int i,
4286
const double* coordinates,
4287
const ufc::cell& c) const
4289
// Extract vertex coordinates
4290
const double * const * element_coordinates = c.coordinates;
4292
// Compute Jacobian of affine map from reference cell
4293
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4294
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4295
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4296
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4298
// Compute determinant of Jacobian
4299
const double detJ = J_00*J_11 - J_01*J_10;
4301
// Compute inverse of Jacobian
4303
// Get coordinates and map to the reference (UFC) element
4304
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4305
element_coordinates[0][0]*element_coordinates[2][1] +\
4306
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4307
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4308
element_coordinates[1][0]*element_coordinates[0][1] -\
4309
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4311
// Map coordinates to the reference square
4312
if (std::abs(y - 1.0) < 1e-14)
4315
x = 2.0 *x/(1.0 - y) - 1.0;
4321
// Map degree of freedom to element degree of freedom
4322
const unsigned int dof = i;
4324
// Generate scalings
4325
const double scalings_y_0 = 1;
4327
// Compute psitilde_a
4328
const double psitilde_a_0 = 1;
4330
// Compute psitilde_bs
4331
const double psitilde_bs_0_0 = 1;
4333
// Compute basisvalues
4334
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4336
// Table(s) of coefficients
4337
const static double coefficients0[1][1] = \
4338
{{1.41421356237309}};
4340
// Extract relevant coefficients
4341
const double coeff0_0 = coefficients0[dof][0];
4344
*values = coeff0_0*basisvalue0;
4347
/// Evaluate all basis functions at given point in cell
4348
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis_all(double* values,
4349
const double* coordinates,
4350
const ufc::cell& c) const
4352
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4355
/// Evaluate order n derivatives of basis function i at given point in cell
4356
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis_derivatives(unsigned int i,
4359
const double* coordinates,
4360
const ufc::cell& c) const
4362
// Extract vertex coordinates
4363
const double * const * element_coordinates = c.coordinates;
4365
// Compute Jacobian of affine map from reference cell
4366
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4367
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4368
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4369
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4371
// Compute determinant of Jacobian
4372
const double detJ = J_00*J_11 - J_01*J_10;
4374
// Compute inverse of Jacobian
4376
// Get coordinates and map to the reference (UFC) element
4377
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4378
element_coordinates[0][0]*element_coordinates[2][1] +\
4379
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4380
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4381
element_coordinates[1][0]*element_coordinates[0][1] -\
4382
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4384
// Map coordinates to the reference square
4385
if (std::abs(y - 1.0) < 1e-14)
4388
x = 2.0 *x/(1.0 - y) - 1.0;
4391
// Compute number of derivatives
4392
unsigned int num_derivatives = 1;
4394
for (unsigned int j = 0; j < n; j++)
4395
num_derivatives *= 2;
4398
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4399
unsigned int **combinations = new unsigned int *[num_derivatives];
4401
for (unsigned int j = 0; j < num_derivatives; j++)
4403
combinations[j] = new unsigned int [n];
4404
for (unsigned int k = 0; k < n; k++)
4405
combinations[j][k] = 0;
4408
// Generate combinations of derivatives
4409
for (unsigned int row = 1; row < num_derivatives; row++)
4411
for (unsigned int num = 0; num < row; num++)
4413
for (unsigned int col = n-1; col+1 > 0; col--)
4415
if (combinations[row][col] + 1 > 1)
4416
combinations[row][col] = 0;
4419
combinations[row][col] += 1;
4426
// Compute inverse of Jacobian
4427
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4429
// Declare transformation matrix
4430
// Declare pointer to two dimensional array and initialise
4431
double **transform = new double *[num_derivatives];
4433
for (unsigned int j = 0; j < num_derivatives; j++)
4435
transform[j] = new double [num_derivatives];
4436
for (unsigned int k = 0; k < num_derivatives; k++)
4437
transform[j][k] = 1;
4440
// Construct transformation matrix
4441
for (unsigned int row = 0; row < num_derivatives; row++)
4443
for (unsigned int col = 0; col < num_derivatives; col++)
4445
for (unsigned int k = 0; k < n; k++)
4446
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4451
for (unsigned int j = 0; j < 1*num_derivatives; j++)
4454
// Map degree of freedom to element degree of freedom
4455
const unsigned int dof = i;
4457
// Generate scalings
4458
const double scalings_y_0 = 1;
4460
// Compute psitilde_a
4461
const double psitilde_a_0 = 1;
4463
// Compute psitilde_bs
4464
const double psitilde_bs_0_0 = 1;
4466
// Compute basisvalues
4467
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4469
// Table(s) of coefficients
4470
const static double coefficients0[1][1] = \
4471
{{1.41421356237309}};
4473
// Interesting (new) part
4474
// Tables of derivatives of the polynomial base (transpose)
4475
const static double dmats0[1][1] = \
4478
const static double dmats1[1][1] = \
4481
// Compute reference derivatives
4482
// Declare pointer to array of derivatives on FIAT element
4483
double *derivatives = new double [num_derivatives];
4485
// Declare coefficients
4486
double coeff0_0 = 0;
4488
// Declare new coefficients
4489
double new_coeff0_0 = 0;
4491
// Loop possible derivatives
4492
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4494
// Get values from coefficients array
4495
new_coeff0_0 = coefficients0[dof][0];
4497
// Loop derivative order
4498
for (unsigned int j = 0; j < n; j++)
4500
// Update old coefficients
4501
coeff0_0 = new_coeff0_0;
4503
if(combinations[deriv_num][j] == 0)
4505
new_coeff0_0 = coeff0_0*dmats0[0][0];
4507
if(combinations[deriv_num][j] == 1)
4509
new_coeff0_0 = coeff0_0*dmats1[0][0];
4513
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4514
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
4517
// Transform derivatives back to physical element
4518
for (unsigned int row = 0; row < num_derivatives; row++)
4520
for (unsigned int col = 0; col < num_derivatives; col++)
4522
values[row] += transform[row][col]*derivatives[col];
4525
// Delete pointer to array of derivatives on FIAT element
4526
delete [] derivatives;
4528
// Delete pointer to array of combinations of derivatives and transform
4529
for (unsigned int row = 0; row < num_derivatives; row++)
4531
delete [] combinations[row];
4532
delete [] transform[row];
4535
delete [] combinations;
4536
delete [] transform;
4539
/// Evaluate order n derivatives of all basis functions at given point in cell
4540
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
4542
const double* coordinates,
4543
const ufc::cell& c) const
4545
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4548
/// Evaluate linear functional for dof i on the function f
4549
double UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_dof(unsigned int i,
4550
const ufc::function& f,
4551
const ufc::cell& c) const
4553
// The reference points, direction and weights:
4554
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
4555
const static double W[1][1] = {{1}};
4556
const static double D[1][1][1] = {{{1}}};
4558
const double * const * x = c.coordinates;
4559
double result = 0.0;
4560
// Iterate over the points:
4561
// Evaluate basis functions for affine mapping
4562
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4563
const double w1 = X[i][0][0];
4564
const double w2 = X[i][0][1];
4566
// Compute affine mapping y = F(X)
4568
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4569
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4571
// Evaluate function at physical points
4573
f.evaluate(values, y, c);
4575
// Map function values using appropriate mapping
4576
// Affine map: Do nothing
4578
// Note that we do not map the weights (yet).
4580
// Take directional components
4581
for(int k = 0; k < 1; k++)
4582
result += values[k]*D[i][0][k];
4583
// Multiply by weights
4589
/// Evaluate linear functionals for all dofs on the function f
4590
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_dofs(double* values,
4591
const ufc::function& f,
4592
const ufc::cell& c) const
4594
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4597
/// Interpolate vertex values from dof values
4598
void UFC_CahnHilliard2DBilinearForm_finite_element_3::interpolate_vertex_values(double* vertex_values,
4599
const double* dof_values,
4600
const ufc::cell& c) const
4602
// Evaluate at vertices and use affine mapping
4603
vertex_values[0] = dof_values[0];
4604
vertex_values[1] = dof_values[0];
4605
vertex_values[2] = dof_values[0];
4608
/// Return the number of sub elements (for a mixed element)
4609
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::num_sub_elements() const
4614
/// Create a new finite element for sub element i (for a mixed element)
4615
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_3::create_sub_element(unsigned int i) const
4617
return new UFC_CahnHilliard2DBilinearForm_finite_element_3();
4622
UFC_CahnHilliard2DBilinearForm_finite_element_4::UFC_CahnHilliard2DBilinearForm_finite_element_4() : ufc::finite_element()
4628
UFC_CahnHilliard2DBilinearForm_finite_element_4::~UFC_CahnHilliard2DBilinearForm_finite_element_4()
4633
/// Return a string identifying the finite element
4634
const char* UFC_CahnHilliard2DBilinearForm_finite_element_4::signature() const
4636
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
4639
/// Return the cell shape
4640
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_4::cell_shape() const
4642
return ufc::triangle;
4645
/// Return the dimension of the finite element function space
4646
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::space_dimension() const
4651
/// Return the rank of the value space
4652
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::value_rank() const
4657
/// Return the dimension of the value space for axis i
4658
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::value_dimension(unsigned int i) const
4663
/// Evaluate basis function i at given point in cell
4664
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis(unsigned int i,
4666
const double* coordinates,
4667
const ufc::cell& c) const
4669
// Extract vertex coordinates
4670
const double * const * element_coordinates = c.coordinates;
4672
// Compute Jacobian of affine map from reference cell
4673
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4674
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4675
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4676
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4678
// Compute determinant of Jacobian
4679
const double detJ = J_00*J_11 - J_01*J_10;
4681
// Compute inverse of Jacobian
4683
// Get coordinates and map to the reference (UFC) element
4684
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4685
element_coordinates[0][0]*element_coordinates[2][1] +\
4686
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4687
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4688
element_coordinates[1][0]*element_coordinates[0][1] -\
4689
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4691
// Map coordinates to the reference square
4692
if (std::abs(y - 1.0) < 1e-14)
4695
x = 2.0 *x/(1.0 - y) - 1.0;
4701
// Map degree of freedom to element degree of freedom
4702
const unsigned int dof = i;
4704
// Generate scalings
4705
const double scalings_y_0 = 1;
4707
// Compute psitilde_a
4708
const double psitilde_a_0 = 1;
4710
// Compute psitilde_bs
4711
const double psitilde_bs_0_0 = 1;
4713
// Compute basisvalues
4714
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4716
// Table(s) of coefficients
4717
const static double coefficients0[1][1] = \
4718
{{1.41421356237309}};
4720
// Extract relevant coefficients
4721
const double coeff0_0 = coefficients0[dof][0];
4724
*values = coeff0_0*basisvalue0;
4727
/// Evaluate all basis functions at given point in cell
4728
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis_all(double* values,
4729
const double* coordinates,
4730
const ufc::cell& c) const
4732
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4735
/// Evaluate order n derivatives of basis function i at given point in cell
4736
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis_derivatives(unsigned int i,
4739
const double* coordinates,
4740
const ufc::cell& c) const
4742
// Extract vertex coordinates
4743
const double * const * element_coordinates = c.coordinates;
4745
// Compute Jacobian of affine map from reference cell
4746
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4747
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4748
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4749
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4751
// Compute determinant of Jacobian
4752
const double detJ = J_00*J_11 - J_01*J_10;
4754
// Compute inverse of Jacobian
4756
// Get coordinates and map to the reference (UFC) element
4757
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4758
element_coordinates[0][0]*element_coordinates[2][1] +\
4759
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4760
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4761
element_coordinates[1][0]*element_coordinates[0][1] -\
4762
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4764
// Map coordinates to the reference square
4765
if (std::abs(y - 1.0) < 1e-14)
4768
x = 2.0 *x/(1.0 - y) - 1.0;
4771
// Compute number of derivatives
4772
unsigned int num_derivatives = 1;
4774
for (unsigned int j = 0; j < n; j++)
4775
num_derivatives *= 2;
4778
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4779
unsigned int **combinations = new unsigned int *[num_derivatives];
4781
for (unsigned int j = 0; j < num_derivatives; j++)
4783
combinations[j] = new unsigned int [n];
4784
for (unsigned int k = 0; k < n; k++)
4785
combinations[j][k] = 0;
4788
// Generate combinations of derivatives
4789
for (unsigned int row = 1; row < num_derivatives; row++)
4791
for (unsigned int num = 0; num < row; num++)
4793
for (unsigned int col = n-1; col+1 > 0; col--)
4795
if (combinations[row][col] + 1 > 1)
4796
combinations[row][col] = 0;
4799
combinations[row][col] += 1;
4806
// Compute inverse of Jacobian
4807
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4809
// Declare transformation matrix
4810
// Declare pointer to two dimensional array and initialise
4811
double **transform = new double *[num_derivatives];
4813
for (unsigned int j = 0; j < num_derivatives; j++)
4815
transform[j] = new double [num_derivatives];
4816
for (unsigned int k = 0; k < num_derivatives; k++)
4817
transform[j][k] = 1;
4820
// Construct transformation matrix
4821
for (unsigned int row = 0; row < num_derivatives; row++)
4823
for (unsigned int col = 0; col < num_derivatives; col++)
4825
for (unsigned int k = 0; k < n; k++)
4826
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4831
for (unsigned int j = 0; j < 1*num_derivatives; j++)
4834
// Map degree of freedom to element degree of freedom
4835
const unsigned int dof = i;
4837
// Generate scalings
4838
const double scalings_y_0 = 1;
4840
// Compute psitilde_a
4841
const double psitilde_a_0 = 1;
4843
// Compute psitilde_bs
4844
const double psitilde_bs_0_0 = 1;
4846
// Compute basisvalues
4847
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4849
// Table(s) of coefficients
4850
const static double coefficients0[1][1] = \
4851
{{1.41421356237309}};
4853
// Interesting (new) part
4854
// Tables of derivatives of the polynomial base (transpose)
4855
const static double dmats0[1][1] = \
4858
const static double dmats1[1][1] = \
4861
// Compute reference derivatives
4862
// Declare pointer to array of derivatives on FIAT element
4863
double *derivatives = new double [num_derivatives];
4865
// Declare coefficients
4866
double coeff0_0 = 0;
4868
// Declare new coefficients
4869
double new_coeff0_0 = 0;
4871
// Loop possible derivatives
4872
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4874
// Get values from coefficients array
4875
new_coeff0_0 = coefficients0[dof][0];
4877
// Loop derivative order
4878
for (unsigned int j = 0; j < n; j++)
4880
// Update old coefficients
4881
coeff0_0 = new_coeff0_0;
4883
if(combinations[deriv_num][j] == 0)
4885
new_coeff0_0 = coeff0_0*dmats0[0][0];
4887
if(combinations[deriv_num][j] == 1)
4889
new_coeff0_0 = coeff0_0*dmats1[0][0];
4893
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4894
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
4897
// Transform derivatives back to physical element
4898
for (unsigned int row = 0; row < num_derivatives; row++)
4900
for (unsigned int col = 0; col < num_derivatives; col++)
4902
values[row] += transform[row][col]*derivatives[col];
4905
// Delete pointer to array of derivatives on FIAT element
4906
delete [] derivatives;
4908
// Delete pointer to array of combinations of derivatives and transform
4909
for (unsigned int row = 0; row < num_derivatives; row++)
4911
delete [] combinations[row];
4912
delete [] transform[row];
4915
delete [] combinations;
4916
delete [] transform;
4919
/// Evaluate order n derivatives of all basis functions at given point in cell
4920
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
4922
const double* coordinates,
4923
const ufc::cell& c) const
4925
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4928
/// Evaluate linear functional for dof i on the function f
4929
double UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_dof(unsigned int i,
4930
const ufc::function& f,
4931
const ufc::cell& c) const
4933
// The reference points, direction and weights:
4934
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
4935
const static double W[1][1] = {{1}};
4936
const static double D[1][1][1] = {{{1}}};
4938
const double * const * x = c.coordinates;
4939
double result = 0.0;
4940
// Iterate over the points:
4941
// Evaluate basis functions for affine mapping
4942
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4943
const double w1 = X[i][0][0];
4944
const double w2 = X[i][0][1];
4946
// Compute affine mapping y = F(X)
4948
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4949
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4951
// Evaluate function at physical points
4953
f.evaluate(values, y, c);
4955
// Map function values using appropriate mapping
4956
// Affine map: Do nothing
4958
// Note that we do not map the weights (yet).
4960
// Take directional components
4961
for(int k = 0; k < 1; k++)
4962
result += values[k]*D[i][0][k];
4963
// Multiply by weights
4969
/// Evaluate linear functionals for all dofs on the function f
4970
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_dofs(double* values,
4971
const ufc::function& f,
4972
const ufc::cell& c) const
4974
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4977
/// Interpolate vertex values from dof values
4978
void UFC_CahnHilliard2DBilinearForm_finite_element_4::interpolate_vertex_values(double* vertex_values,
4979
const double* dof_values,
4980
const ufc::cell& c) const
4982
// Evaluate at vertices and use affine mapping
4983
vertex_values[0] = dof_values[0];
4984
vertex_values[1] = dof_values[0];
4985
vertex_values[2] = dof_values[0];
4988
/// Return the number of sub elements (for a mixed element)
4989
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::num_sub_elements() const
4994
/// Create a new finite element for sub element i (for a mixed element)
4995
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_4::create_sub_element(unsigned int i) const
4997
return new UFC_CahnHilliard2DBilinearForm_finite_element_4();
5002
UFC_CahnHilliard2DBilinearForm_finite_element_5::UFC_CahnHilliard2DBilinearForm_finite_element_5() : ufc::finite_element()
5008
UFC_CahnHilliard2DBilinearForm_finite_element_5::~UFC_CahnHilliard2DBilinearForm_finite_element_5()
5013
/// Return a string identifying the finite element
5014
const char* UFC_CahnHilliard2DBilinearForm_finite_element_5::signature() const
5016
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
5019
/// Return the cell shape
5020
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_5::cell_shape() const
5022
return ufc::triangle;
5025
/// Return the dimension of the finite element function space
5026
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::space_dimension() const
5031
/// Return the rank of the value space
5032
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::value_rank() const
5037
/// Return the dimension of the value space for axis i
5038
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::value_dimension(unsigned int i) const
5043
/// Evaluate basis function i at given point in cell
5044
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis(unsigned int i,
5046
const double* coordinates,
5047
const ufc::cell& c) const
5049
// Extract vertex coordinates
5050
const double * const * element_coordinates = c.coordinates;
5052
// Compute Jacobian of affine map from reference cell
5053
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5054
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5055
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5056
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5058
// Compute determinant of Jacobian
5059
const double detJ = J_00*J_11 - J_01*J_10;
5061
// Compute inverse of Jacobian
5063
// Get coordinates and map to the reference (UFC) element
5064
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5065
element_coordinates[0][0]*element_coordinates[2][1] +\
5066
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5067
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5068
element_coordinates[1][0]*element_coordinates[0][1] -\
5069
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5071
// Map coordinates to the reference square
5072
if (std::abs(y - 1.0) < 1e-14)
5075
x = 2.0 *x/(1.0 - y) - 1.0;
5081
// Map degree of freedom to element degree of freedom
5082
const unsigned int dof = i;
5084
// Generate scalings
5085
const double scalings_y_0 = 1;
5087
// Compute psitilde_a
5088
const double psitilde_a_0 = 1;
5090
// Compute psitilde_bs
5091
const double psitilde_bs_0_0 = 1;
5093
// Compute basisvalues
5094
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5096
// Table(s) of coefficients
5097
const static double coefficients0[1][1] = \
5098
{{1.41421356237309}};
5100
// Extract relevant coefficients
5101
const double coeff0_0 = coefficients0[dof][0];
5104
*values = coeff0_0*basisvalue0;
5107
/// Evaluate all basis functions at given point in cell
5108
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis_all(double* values,
5109
const double* coordinates,
5110
const ufc::cell& c) const
5112
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5115
/// Evaluate order n derivatives of basis function i at given point in cell
5116
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis_derivatives(unsigned int i,
5119
const double* coordinates,
5120
const ufc::cell& c) const
5122
// Extract vertex coordinates
5123
const double * const * element_coordinates = c.coordinates;
5125
// Compute Jacobian of affine map from reference cell
5126
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5127
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5128
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5129
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5131
// Compute determinant of Jacobian
5132
const double detJ = J_00*J_11 - J_01*J_10;
5134
// Compute inverse of Jacobian
5136
// Get coordinates and map to the reference (UFC) element
5137
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5138
element_coordinates[0][0]*element_coordinates[2][1] +\
5139
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5140
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5141
element_coordinates[1][0]*element_coordinates[0][1] -\
5142
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5144
// Map coordinates to the reference square
5145
if (std::abs(y - 1.0) < 1e-14)
5148
x = 2.0 *x/(1.0 - y) - 1.0;
5151
// Compute number of derivatives
5152
unsigned int num_derivatives = 1;
5154
for (unsigned int j = 0; j < n; j++)
5155
num_derivatives *= 2;
5158
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5159
unsigned int **combinations = new unsigned int *[num_derivatives];
5161
for (unsigned int j = 0; j < num_derivatives; j++)
5163
combinations[j] = new unsigned int [n];
5164
for (unsigned int k = 0; k < n; k++)
5165
combinations[j][k] = 0;
5168
// Generate combinations of derivatives
5169
for (unsigned int row = 1; row < num_derivatives; row++)
5171
for (unsigned int num = 0; num < row; num++)
5173
for (unsigned int col = n-1; col+1 > 0; col--)
5175
if (combinations[row][col] + 1 > 1)
5176
combinations[row][col] = 0;
5179
combinations[row][col] += 1;
5186
// Compute inverse of Jacobian
5187
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
5189
// Declare transformation matrix
5190
// Declare pointer to two dimensional array and initialise
5191
double **transform = new double *[num_derivatives];
5193
for (unsigned int j = 0; j < num_derivatives; j++)
5195
transform[j] = new double [num_derivatives];
5196
for (unsigned int k = 0; k < num_derivatives; k++)
5197
transform[j][k] = 1;
5200
// Construct transformation matrix
5201
for (unsigned int row = 0; row < num_derivatives; row++)
5203
for (unsigned int col = 0; col < num_derivatives; col++)
5205
for (unsigned int k = 0; k < n; k++)
5206
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5211
for (unsigned int j = 0; j < 1*num_derivatives; j++)
5214
// Map degree of freedom to element degree of freedom
5215
const unsigned int dof = i;
5217
// Generate scalings
5218
const double scalings_y_0 = 1;
5220
// Compute psitilde_a
5221
const double psitilde_a_0 = 1;
5223
// Compute psitilde_bs
5224
const double psitilde_bs_0_0 = 1;
5226
// Compute basisvalues
5227
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5229
// Table(s) of coefficients
5230
const static double coefficients0[1][1] = \
5231
{{1.41421356237309}};
5233
// Interesting (new) part
5234
// Tables of derivatives of the polynomial base (transpose)
5235
const static double dmats0[1][1] = \
5238
const static double dmats1[1][1] = \
5241
// Compute reference derivatives
5242
// Declare pointer to array of derivatives on FIAT element
5243
double *derivatives = new double [num_derivatives];
5245
// Declare coefficients
5246
double coeff0_0 = 0;
5248
// Declare new coefficients
5249
double new_coeff0_0 = 0;
5251
// Loop possible derivatives
5252
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5254
// Get values from coefficients array
5255
new_coeff0_0 = coefficients0[dof][0];
5257
// Loop derivative order
5258
for (unsigned int j = 0; j < n; j++)
5260
// Update old coefficients
5261
coeff0_0 = new_coeff0_0;
5263
if(combinations[deriv_num][j] == 0)
5265
new_coeff0_0 = coeff0_0*dmats0[0][0];
5267
if(combinations[deriv_num][j] == 1)
5269
new_coeff0_0 = coeff0_0*dmats1[0][0];
5273
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5274
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
5277
// Transform derivatives back to physical element
5278
for (unsigned int row = 0; row < num_derivatives; row++)
5280
for (unsigned int col = 0; col < num_derivatives; col++)
5282
values[row] += transform[row][col]*derivatives[col];
5285
// Delete pointer to array of derivatives on FIAT element
5286
delete [] derivatives;
5288
// Delete pointer to array of combinations of derivatives and transform
5289
for (unsigned int row = 0; row < num_derivatives; row++)
5291
delete [] combinations[row];
5292
delete [] transform[row];
5295
delete [] combinations;
5296
delete [] transform;
5299
/// Evaluate order n derivatives of all basis functions at given point in cell
5300
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
5302
const double* coordinates,
5303
const ufc::cell& c) const
5305
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5308
/// Evaluate linear functional for dof i on the function f
5309
double UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_dof(unsigned int i,
5310
const ufc::function& f,
5311
const ufc::cell& c) const
5313
// The reference points, direction and weights:
5314
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
5315
const static double W[1][1] = {{1}};
5316
const static double D[1][1][1] = {{{1}}};
5318
const double * const * x = c.coordinates;
5319
double result = 0.0;
5320
// Iterate over the points:
5321
// Evaluate basis functions for affine mapping
5322
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
5323
const double w1 = X[i][0][0];
5324
const double w2 = X[i][0][1];
5326
// Compute affine mapping y = F(X)
5328
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
5329
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
5331
// Evaluate function at physical points
5333
f.evaluate(values, y, c);
5335
// Map function values using appropriate mapping
5336
// Affine map: Do nothing
5338
// Note that we do not map the weights (yet).
5340
// Take directional components
5341
for(int k = 0; k < 1; k++)
5342
result += values[k]*D[i][0][k];
5343
// Multiply by weights
5349
/// Evaluate linear functionals for all dofs on the function f
5350
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_dofs(double* values,
5351
const ufc::function& f,
5352
const ufc::cell& c) const
5354
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5357
/// Interpolate vertex values from dof values
5358
void UFC_CahnHilliard2DBilinearForm_finite_element_5::interpolate_vertex_values(double* vertex_values,
5359
const double* dof_values,
5360
const ufc::cell& c) const
5362
// Evaluate at vertices and use affine mapping
5363
vertex_values[0] = dof_values[0];
5364
vertex_values[1] = dof_values[0];
5365
vertex_values[2] = dof_values[0];
5368
/// Return the number of sub elements (for a mixed element)
5369
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::num_sub_elements() const
5374
/// Create a new finite element for sub element i (for a mixed element)
5375
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_5::create_sub_element(unsigned int i) const
5377
return new UFC_CahnHilliard2DBilinearForm_finite_element_5();
5382
UFC_CahnHilliard2DBilinearForm_finite_element_6::UFC_CahnHilliard2DBilinearForm_finite_element_6() : ufc::finite_element()
5388
UFC_CahnHilliard2DBilinearForm_finite_element_6::~UFC_CahnHilliard2DBilinearForm_finite_element_6()
5393
/// Return a string identifying the finite element
5394
const char* UFC_CahnHilliard2DBilinearForm_finite_element_6::signature() const
5396
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
5399
/// Return the cell shape
5400
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_6::cell_shape() const
5402
return ufc::triangle;
5405
/// Return the dimension of the finite element function space
5406
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::space_dimension() const
5411
/// Return the rank of the value space
5412
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::value_rank() const
5417
/// Return the dimension of the value space for axis i
5418
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::value_dimension(unsigned int i) const
5423
/// Evaluate basis function i at given point in cell
5424
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis(unsigned int i,
5426
const double* coordinates,
5427
const ufc::cell& c) const
5429
// Extract vertex coordinates
5430
const double * const * element_coordinates = c.coordinates;
5432
// Compute Jacobian of affine map from reference cell
5433
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5434
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5435
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5436
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5438
// Compute determinant of Jacobian
5439
const double detJ = J_00*J_11 - J_01*J_10;
5441
// Compute inverse of Jacobian
5443
// Get coordinates and map to the reference (UFC) element
5444
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5445
element_coordinates[0][0]*element_coordinates[2][1] +\
5446
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5447
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5448
element_coordinates[1][0]*element_coordinates[0][1] -\
5449
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5451
// Map coordinates to the reference square
5452
if (std::abs(y - 1.0) < 1e-14)
5455
x = 2.0 *x/(1.0 - y) - 1.0;
5461
// Map degree of freedom to element degree of freedom
5462
const unsigned int dof = i;
5464
// Generate scalings
5465
const double scalings_y_0 = 1;
5467
// Compute psitilde_a
5468
const double psitilde_a_0 = 1;
5470
// Compute psitilde_bs
5471
const double psitilde_bs_0_0 = 1;
5473
// Compute basisvalues
5474
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5476
// Table(s) of coefficients
5477
const static double coefficients0[1][1] = \
5478
{{1.41421356237309}};
5480
// Extract relevant coefficients
5481
const double coeff0_0 = coefficients0[dof][0];
5484
*values = coeff0_0*basisvalue0;
5487
/// Evaluate all basis functions at given point in cell
5488
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis_all(double* values,
5489
const double* coordinates,
5490
const ufc::cell& c) const
5492
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5495
/// Evaluate order n derivatives of basis function i at given point in cell
5496
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis_derivatives(unsigned int i,
5499
const double* coordinates,
5500
const ufc::cell& c) const
5502
// Extract vertex coordinates
5503
const double * const * element_coordinates = c.coordinates;
5505
// Compute Jacobian of affine map from reference cell
5506
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5507
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5508
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5509
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5511
// Compute determinant of Jacobian
5512
const double detJ = J_00*J_11 - J_01*J_10;
5514
// Compute inverse of Jacobian
5516
// Get coordinates and map to the reference (UFC) element
5517
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5518
element_coordinates[0][0]*element_coordinates[2][1] +\
5519
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5520
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5521
element_coordinates[1][0]*element_coordinates[0][1] -\
5522
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5524
// Map coordinates to the reference square
5525
if (std::abs(y - 1.0) < 1e-14)
5528
x = 2.0 *x/(1.0 - y) - 1.0;
5531
// Compute number of derivatives
5532
unsigned int num_derivatives = 1;
5534
for (unsigned int j = 0; j < n; j++)
5535
num_derivatives *= 2;
5538
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5539
unsigned int **combinations = new unsigned int *[num_derivatives];
5541
for (unsigned int j = 0; j < num_derivatives; j++)
5543
combinations[j] = new unsigned int [n];
5544
for (unsigned int k = 0; k < n; k++)
5545
combinations[j][k] = 0;
5548
// Generate combinations of derivatives
5549
for (unsigned int row = 1; row < num_derivatives; row++)
5551
for (unsigned int num = 0; num < row; num++)
5553
for (unsigned int col = n-1; col+1 > 0; col--)
5555
if (combinations[row][col] + 1 > 1)
5556
combinations[row][col] = 0;
5559
combinations[row][col] += 1;
5566
// Compute inverse of Jacobian
5567
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
5569
// Declare transformation matrix
5570
// Declare pointer to two dimensional array and initialise
5571
double **transform = new double *[num_derivatives];
5573
for (unsigned int j = 0; j < num_derivatives; j++)
5575
transform[j] = new double [num_derivatives];
5576
for (unsigned int k = 0; k < num_derivatives; k++)
5577
transform[j][k] = 1;
5580
// Construct transformation matrix
5581
for (unsigned int row = 0; row < num_derivatives; row++)
5583
for (unsigned int col = 0; col < num_derivatives; col++)
5585
for (unsigned int k = 0; k < n; k++)
5586
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5591
for (unsigned int j = 0; j < 1*num_derivatives; j++)
5594
// Map degree of freedom to element degree of freedom
5595
const unsigned int dof = i;
5597
// Generate scalings
5598
const double scalings_y_0 = 1;
5600
// Compute psitilde_a
5601
const double psitilde_a_0 = 1;
5603
// Compute psitilde_bs
5604
const double psitilde_bs_0_0 = 1;
5606
// Compute basisvalues
5607
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5609
// Table(s) of coefficients
5610
const static double coefficients0[1][1] = \
5611
{{1.41421356237309}};
5613
// Interesting (new) part
5614
// Tables of derivatives of the polynomial base (transpose)
5615
const static double dmats0[1][1] = \
5618
const static double dmats1[1][1] = \
5621
// Compute reference derivatives
5622
// Declare pointer to array of derivatives on FIAT element
5623
double *derivatives = new double [num_derivatives];
5625
// Declare coefficients
5626
double coeff0_0 = 0;
5628
// Declare new coefficients
5629
double new_coeff0_0 = 0;
5631
// Loop possible derivatives
5632
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5634
// Get values from coefficients array
5635
new_coeff0_0 = coefficients0[dof][0];
5637
// Loop derivative order
5638
for (unsigned int j = 0; j < n; j++)
5640
// Update old coefficients
5641
coeff0_0 = new_coeff0_0;
5643
if(combinations[deriv_num][j] == 0)
5645
new_coeff0_0 = coeff0_0*dmats0[0][0];
5647
if(combinations[deriv_num][j] == 1)
5649
new_coeff0_0 = coeff0_0*dmats1[0][0];
5653
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5654
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
5657
// Transform derivatives back to physical element
5658
for (unsigned int row = 0; row < num_derivatives; row++)
5660
for (unsigned int col = 0; col < num_derivatives; col++)
5662
values[row] += transform[row][col]*derivatives[col];
5665
// Delete pointer to array of derivatives on FIAT element
5666
delete [] derivatives;
5668
// Delete pointer to array of combinations of derivatives and transform
5669
for (unsigned int row = 0; row < num_derivatives; row++)
5671
delete [] combinations[row];
5672
delete [] transform[row];
5675
delete [] combinations;
5676
delete [] transform;
5679
/// Evaluate order n derivatives of all basis functions at given point in cell
5680
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
5682
const double* coordinates,
5683
const ufc::cell& c) const
5685
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5688
/// Evaluate linear functional for dof i on the function f
5689
double UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_dof(unsigned int i,
5690
const ufc::function& f,
5691
const ufc::cell& c) const
5693
// The reference points, direction and weights:
5694
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
5695
const static double W[1][1] = {{1}};
5696
const static double D[1][1][1] = {{{1}}};
5698
const double * const * x = c.coordinates;
5699
double result = 0.0;
5700
// Iterate over the points:
5701
// Evaluate basis functions for affine mapping
5702
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
5703
const double w1 = X[i][0][0];
5704
const double w2 = X[i][0][1];
5706
// Compute affine mapping y = F(X)
5708
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
5709
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
5711
// Evaluate function at physical points
5713
f.evaluate(values, y, c);
5715
// Map function values using appropriate mapping
5716
// Affine map: Do nothing
5718
// Note that we do not map the weights (yet).
5720
// Take directional components
5721
for(int k = 0; k < 1; k++)
5722
result += values[k]*D[i][0][k];
5723
// Multiply by weights
5729
/// Evaluate linear functionals for all dofs on the function f
5730
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_dofs(double* values,
5731
const ufc::function& f,
5732
const ufc::cell& c) const
5734
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5737
/// Interpolate vertex values from dof values
5738
void UFC_CahnHilliard2DBilinearForm_finite_element_6::interpolate_vertex_values(double* vertex_values,
5739
const double* dof_values,
5740
const ufc::cell& c) const
5742
// Evaluate at vertices and use affine mapping
5743
vertex_values[0] = dof_values[0];
5744
vertex_values[1] = dof_values[0];
5745
vertex_values[2] = dof_values[0];
5748
/// Return the number of sub elements (for a mixed element)
5749
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::num_sub_elements() const
5754
/// Create a new finite element for sub element i (for a mixed element)
5755
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_6::create_sub_element(unsigned int i) const
5757
return new UFC_CahnHilliard2DBilinearForm_finite_element_6();
5761
UFC_CahnHilliard2DBilinearForm_dof_map_0_0::UFC_CahnHilliard2DBilinearForm_dof_map_0_0() : ufc::dof_map()
5763
__global_dimension = 0;
5767
UFC_CahnHilliard2DBilinearForm_dof_map_0_0::~UFC_CahnHilliard2DBilinearForm_dof_map_0_0()
5772
/// Return a string identifying the dof map
5773
const char* UFC_CahnHilliard2DBilinearForm_dof_map_0_0::signature() const
5775
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
5778
/// Return true iff mesh entities of topological dimension d are needed
5779
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_0::needs_mesh_entities(unsigned int d) const
5796
/// Initialize dof map for mesh (return true iff init_cell() is needed)
5797
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_0::init_mesh(const ufc::mesh& m)
5799
__global_dimension = m.num_entities[0];
5803
/// Initialize dof map for given cell
5804
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::init_cell(const ufc::mesh& m,
5810
/// Finish initialization of dof map for cells
5811
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::init_cell_finalize()
5816
/// Return the dimension of the global finite element function space
5817
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::global_dimension() const
5819
return __global_dimension;
5822
/// Return the dimension of the local finite element function space
5823
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::local_dimension() const
5828
// Return the geometric dimension of the coordinates this dof map provides
5829
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::geometric_dimension() const
5834
/// Return the number of dofs on each cell facet
5835
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::num_facet_dofs() const
5840
/// Return the number of dofs associated with each cell entity of dimension d
5841
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::num_entity_dofs(unsigned int d) const
5843
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5846
/// Tabulate the local-to-global mapping of dofs on a cell
5847
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
5849
const ufc::cell& c) const
5851
dofs[0] = c.entity_indices[0][0];
5852
dofs[1] = c.entity_indices[0][1];
5853
dofs[2] = c.entity_indices[0][2];
5856
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
5857
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
5858
unsigned int facet) const
5877
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
5878
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
5879
unsigned int d, unsigned int i) const
5881
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5884
/// Tabulate the coordinates of all dofs on a cell
5885
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_coordinates(double** coordinates,
5886
const ufc::cell& c) const
5888
const double * const * x = c.coordinates;
5889
coordinates[0][0] = x[0][0];
5890
coordinates[0][1] = x[0][1];
5891
coordinates[1][0] = x[1][0];
5892
coordinates[1][1] = x[1][1];
5893
coordinates[2][0] = x[2][0];
5894
coordinates[2][1] = x[2][1];
5897
/// Return the number of sub dof maps (for a mixed element)
5898
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::num_sub_dof_maps() const
5903
/// Create a new dof_map for sub dof map i (for a mixed element)
5904
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_0_0::create_sub_dof_map(unsigned int i) const
5906
return new UFC_CahnHilliard2DBilinearForm_dof_map_0_0();
5911
UFC_CahnHilliard2DBilinearForm_dof_map_0_1::UFC_CahnHilliard2DBilinearForm_dof_map_0_1() : ufc::dof_map()
5913
__global_dimension = 0;
5917
UFC_CahnHilliard2DBilinearForm_dof_map_0_1::~UFC_CahnHilliard2DBilinearForm_dof_map_0_1()
5922
/// Return a string identifying the dof map
5923
const char* UFC_CahnHilliard2DBilinearForm_dof_map_0_1::signature() const
5925
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
5928
/// Return true iff mesh entities of topological dimension d are needed
5929
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_1::needs_mesh_entities(unsigned int d) const
5946
/// Initialize dof map for mesh (return true iff init_cell() is needed)
5947
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_1::init_mesh(const ufc::mesh& m)
5949
__global_dimension = m.num_entities[0];
5953
/// Initialize dof map for given cell
5954
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::init_cell(const ufc::mesh& m,
5960
/// Finish initialization of dof map for cells
5961
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::init_cell_finalize()
5966
/// Return the dimension of the global finite element function space
5967
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::global_dimension() const
5969
return __global_dimension;
5972
/// Return the dimension of the local finite element function space
5973
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::local_dimension() const
5978
// Return the geometric dimension of the coordinates this dof map provides
5979
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::geometric_dimension() const
5984
/// Return the number of dofs on each cell facet
5985
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::num_facet_dofs() const
5990
/// Return the number of dofs associated with each cell entity of dimension d
5991
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::num_entity_dofs(unsigned int d) const
5993
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5996
/// Tabulate the local-to-global mapping of dofs on a cell
5997
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
5999
const ufc::cell& c) const
6001
dofs[0] = c.entity_indices[0][0];
6002
dofs[1] = c.entity_indices[0][1];
6003
dofs[2] = c.entity_indices[0][2];
6006
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6007
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
6008
unsigned int facet) const
6027
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6028
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
6029
unsigned int d, unsigned int i) const
6031
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6034
/// Tabulate the coordinates of all dofs on a cell
6035
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_coordinates(double** coordinates,
6036
const ufc::cell& c) const
6038
const double * const * x = c.coordinates;
6039
coordinates[0][0] = x[0][0];
6040
coordinates[0][1] = x[0][1];
6041
coordinates[1][0] = x[1][0];
6042
coordinates[1][1] = x[1][1];
6043
coordinates[2][0] = x[2][0];
6044
coordinates[2][1] = x[2][1];
6047
/// Return the number of sub dof maps (for a mixed element)
6048
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::num_sub_dof_maps() const
6053
/// Create a new dof_map for sub dof map i (for a mixed element)
6054
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_0_1::create_sub_dof_map(unsigned int i) const
6056
return new UFC_CahnHilliard2DBilinearForm_dof_map_0_1();
6061
UFC_CahnHilliard2DBilinearForm_dof_map_0::UFC_CahnHilliard2DBilinearForm_dof_map_0() : ufc::dof_map()
6063
__global_dimension = 0;
6067
UFC_CahnHilliard2DBilinearForm_dof_map_0::~UFC_CahnHilliard2DBilinearForm_dof_map_0()
6072
/// Return a string identifying the dof map
6073
const char* UFC_CahnHilliard2DBilinearForm_dof_map_0::signature() const
6075
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
6078
/// Return true iff mesh entities of topological dimension d are needed
6079
bool UFC_CahnHilliard2DBilinearForm_dof_map_0::needs_mesh_entities(unsigned int d) const
6096
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6097
bool UFC_CahnHilliard2DBilinearForm_dof_map_0::init_mesh(const ufc::mesh& m)
6099
__global_dimension = 2*m.num_entities[0];
6103
/// Initialize dof map for given cell
6104
void UFC_CahnHilliard2DBilinearForm_dof_map_0::init_cell(const ufc::mesh& m,
6110
/// Finish initialization of dof map for cells
6111
void UFC_CahnHilliard2DBilinearForm_dof_map_0::init_cell_finalize()
6116
/// Return the dimension of the global finite element function space
6117
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::global_dimension() const
6119
return __global_dimension;
6122
/// Return the dimension of the local finite element function space
6123
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::local_dimension() const
6128
// Return the geometric dimension of the coordinates this dof map provides
6129
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::geometric_dimension() const
6134
/// Return the number of dofs on each cell facet
6135
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::num_facet_dofs() const
6140
/// Return the number of dofs associated with each cell entity of dimension d
6141
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::num_entity_dofs(unsigned int d) const
6143
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6146
/// Tabulate the local-to-global mapping of dofs on a cell
6147
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_dofs(unsigned int* dofs,
6149
const ufc::cell& c) const
6151
dofs[0] = c.entity_indices[0][0];
6152
dofs[1] = c.entity_indices[0][1];
6153
dofs[2] = c.entity_indices[0][2];
6154
unsigned int offset = m.num_entities[0];
6155
dofs[3] = offset + c.entity_indices[0][0];
6156
dofs[4] = offset + c.entity_indices[0][1];
6157
dofs[5] = offset + c.entity_indices[0][2];
6160
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6161
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
6162
unsigned int facet) const
6187
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6188
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
6189
unsigned int d, unsigned int i) const
6191
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6194
/// Tabulate the coordinates of all dofs on a cell
6195
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_coordinates(double** coordinates,
6196
const ufc::cell& c) const
6198
const double * const * x = c.coordinates;
6199
coordinates[0][0] = x[0][0];
6200
coordinates[0][1] = x[0][1];
6201
coordinates[1][0] = x[1][0];
6202
coordinates[1][1] = x[1][1];
6203
coordinates[2][0] = x[2][0];
6204
coordinates[2][1] = x[2][1];
6205
coordinates[3][0] = x[0][0];
6206
coordinates[3][1] = x[0][1];
6207
coordinates[4][0] = x[1][0];
6208
coordinates[4][1] = x[1][1];
6209
coordinates[5][0] = x[2][0];
6210
coordinates[5][1] = x[2][1];
6213
/// Return the number of sub dof maps (for a mixed element)
6214
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::num_sub_dof_maps() const
6219
/// Create a new dof_map for sub dof map i (for a mixed element)
6220
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_0::create_sub_dof_map(unsigned int i) const
6225
return new UFC_CahnHilliard2DBilinearForm_dof_map_0_0();
6228
return new UFC_CahnHilliard2DBilinearForm_dof_map_0_1();
6236
UFC_CahnHilliard2DBilinearForm_dof_map_1_0::UFC_CahnHilliard2DBilinearForm_dof_map_1_0() : ufc::dof_map()
6238
__global_dimension = 0;
6242
UFC_CahnHilliard2DBilinearForm_dof_map_1_0::~UFC_CahnHilliard2DBilinearForm_dof_map_1_0()
6247
/// Return a string identifying the dof map
6248
const char* UFC_CahnHilliard2DBilinearForm_dof_map_1_0::signature() const
6250
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6253
/// Return true iff mesh entities of topological dimension d are needed
6254
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_0::needs_mesh_entities(unsigned int d) const
6271
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6272
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_0::init_mesh(const ufc::mesh& m)
6274
__global_dimension = m.num_entities[0];
6278
/// Initialize dof map for given cell
6279
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::init_cell(const ufc::mesh& m,
6285
/// Finish initialization of dof map for cells
6286
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::init_cell_finalize()
6291
/// Return the dimension of the global finite element function space
6292
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::global_dimension() const
6294
return __global_dimension;
6297
/// Return the dimension of the local finite element function space
6298
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::local_dimension() const
6303
// Return the geometric dimension of the coordinates this dof map provides
6304
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::geometric_dimension() const
6309
/// Return the number of dofs on each cell facet
6310
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::num_facet_dofs() const
6315
/// Return the number of dofs associated with each cell entity of dimension d
6316
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::num_entity_dofs(unsigned int d) const
6318
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6321
/// Tabulate the local-to-global mapping of dofs on a cell
6322
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
6324
const ufc::cell& c) const
6326
dofs[0] = c.entity_indices[0][0];
6327
dofs[1] = c.entity_indices[0][1];
6328
dofs[2] = c.entity_indices[0][2];
6331
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6332
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
6333
unsigned int facet) const
6352
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6353
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
6354
unsigned int d, unsigned int i) const
6356
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6359
/// Tabulate the coordinates of all dofs on a cell
6360
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_coordinates(double** coordinates,
6361
const ufc::cell& c) const
6363
const double * const * x = c.coordinates;
6364
coordinates[0][0] = x[0][0];
6365
coordinates[0][1] = x[0][1];
6366
coordinates[1][0] = x[1][0];
6367
coordinates[1][1] = x[1][1];
6368
coordinates[2][0] = x[2][0];
6369
coordinates[2][1] = x[2][1];
6372
/// Return the number of sub dof maps (for a mixed element)
6373
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::num_sub_dof_maps() const
6378
/// Create a new dof_map for sub dof map i (for a mixed element)
6379
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_1_0::create_sub_dof_map(unsigned int i) const
6381
return new UFC_CahnHilliard2DBilinearForm_dof_map_1_0();
6386
UFC_CahnHilliard2DBilinearForm_dof_map_1_1::UFC_CahnHilliard2DBilinearForm_dof_map_1_1() : ufc::dof_map()
6388
__global_dimension = 0;
6392
UFC_CahnHilliard2DBilinearForm_dof_map_1_1::~UFC_CahnHilliard2DBilinearForm_dof_map_1_1()
6397
/// Return a string identifying the dof map
6398
const char* UFC_CahnHilliard2DBilinearForm_dof_map_1_1::signature() const
6400
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6403
/// Return true iff mesh entities of topological dimension d are needed
6404
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_1::needs_mesh_entities(unsigned int d) const
6421
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6422
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_1::init_mesh(const ufc::mesh& m)
6424
__global_dimension = m.num_entities[0];
6428
/// Initialize dof map for given cell
6429
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::init_cell(const ufc::mesh& m,
6435
/// Finish initialization of dof map for cells
6436
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::init_cell_finalize()
6441
/// Return the dimension of the global finite element function space
6442
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::global_dimension() const
6444
return __global_dimension;
6447
/// Return the dimension of the local finite element function space
6448
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::local_dimension() const
6453
// Return the geometric dimension of the coordinates this dof map provides
6454
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::geometric_dimension() const
6459
/// Return the number of dofs on each cell facet
6460
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::num_facet_dofs() const
6465
/// Return the number of dofs associated with each cell entity of dimension d
6466
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::num_entity_dofs(unsigned int d) const
6468
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6471
/// Tabulate the local-to-global mapping of dofs on a cell
6472
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
6474
const ufc::cell& c) const
6476
dofs[0] = c.entity_indices[0][0];
6477
dofs[1] = c.entity_indices[0][1];
6478
dofs[2] = c.entity_indices[0][2];
6481
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6482
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
6483
unsigned int facet) const
6502
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6503
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
6504
unsigned int d, unsigned int i) const
6506
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6509
/// Tabulate the coordinates of all dofs on a cell
6510
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_coordinates(double** coordinates,
6511
const ufc::cell& c) const
6513
const double * const * x = c.coordinates;
6514
coordinates[0][0] = x[0][0];
6515
coordinates[0][1] = x[0][1];
6516
coordinates[1][0] = x[1][0];
6517
coordinates[1][1] = x[1][1];
6518
coordinates[2][0] = x[2][0];
6519
coordinates[2][1] = x[2][1];
6522
/// Return the number of sub dof maps (for a mixed element)
6523
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::num_sub_dof_maps() const
6528
/// Create a new dof_map for sub dof map i (for a mixed element)
6529
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_1_1::create_sub_dof_map(unsigned int i) const
6531
return new UFC_CahnHilliard2DBilinearForm_dof_map_1_1();
6536
UFC_CahnHilliard2DBilinearForm_dof_map_1::UFC_CahnHilliard2DBilinearForm_dof_map_1() : ufc::dof_map()
6538
__global_dimension = 0;
6542
UFC_CahnHilliard2DBilinearForm_dof_map_1::~UFC_CahnHilliard2DBilinearForm_dof_map_1()
6547
/// Return a string identifying the dof map
6548
const char* UFC_CahnHilliard2DBilinearForm_dof_map_1::signature() const
6550
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
6553
/// Return true iff mesh entities of topological dimension d are needed
6554
bool UFC_CahnHilliard2DBilinearForm_dof_map_1::needs_mesh_entities(unsigned int d) const
6571
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6572
bool UFC_CahnHilliard2DBilinearForm_dof_map_1::init_mesh(const ufc::mesh& m)
6574
__global_dimension = 2*m.num_entities[0];
6578
/// Initialize dof map for given cell
6579
void UFC_CahnHilliard2DBilinearForm_dof_map_1::init_cell(const ufc::mesh& m,
6585
/// Finish initialization of dof map for cells
6586
void UFC_CahnHilliard2DBilinearForm_dof_map_1::init_cell_finalize()
6591
/// Return the dimension of the global finite element function space
6592
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::global_dimension() const
6594
return __global_dimension;
6597
/// Return the dimension of the local finite element function space
6598
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::local_dimension() const
6603
// Return the geometric dimension of the coordinates this dof map provides
6604
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::geometric_dimension() const
6609
/// Return the number of dofs on each cell facet
6610
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::num_facet_dofs() const
6615
/// Return the number of dofs associated with each cell entity of dimension d
6616
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::num_entity_dofs(unsigned int d) const
6618
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6621
/// Tabulate the local-to-global mapping of dofs on a cell
6622
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_dofs(unsigned int* dofs,
6624
const ufc::cell& c) const
6626
dofs[0] = c.entity_indices[0][0];
6627
dofs[1] = c.entity_indices[0][1];
6628
dofs[2] = c.entity_indices[0][2];
6629
unsigned int offset = m.num_entities[0];
6630
dofs[3] = offset + c.entity_indices[0][0];
6631
dofs[4] = offset + c.entity_indices[0][1];
6632
dofs[5] = offset + c.entity_indices[0][2];
6635
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6636
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
6637
unsigned int facet) const
6662
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6663
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
6664
unsigned int d, unsigned int i) const
6666
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6669
/// Tabulate the coordinates of all dofs on a cell
6670
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_coordinates(double** coordinates,
6671
const ufc::cell& c) const
6673
const double * const * x = c.coordinates;
6674
coordinates[0][0] = x[0][0];
6675
coordinates[0][1] = x[0][1];
6676
coordinates[1][0] = x[1][0];
6677
coordinates[1][1] = x[1][1];
6678
coordinates[2][0] = x[2][0];
6679
coordinates[2][1] = x[2][1];
6680
coordinates[3][0] = x[0][0];
6681
coordinates[3][1] = x[0][1];
6682
coordinates[4][0] = x[1][0];
6683
coordinates[4][1] = x[1][1];
6684
coordinates[5][0] = x[2][0];
6685
coordinates[5][1] = x[2][1];
6688
/// Return the number of sub dof maps (for a mixed element)
6689
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::num_sub_dof_maps() const
6694
/// Create a new dof_map for sub dof map i (for a mixed element)
6695
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_1::create_sub_dof_map(unsigned int i) const
6700
return new UFC_CahnHilliard2DBilinearForm_dof_map_1_0();
6703
return new UFC_CahnHilliard2DBilinearForm_dof_map_1_1();
6711
UFC_CahnHilliard2DBilinearForm_dof_map_2_0::UFC_CahnHilliard2DBilinearForm_dof_map_2_0() : ufc::dof_map()
6713
__global_dimension = 0;
6717
UFC_CahnHilliard2DBilinearForm_dof_map_2_0::~UFC_CahnHilliard2DBilinearForm_dof_map_2_0()
6722
/// Return a string identifying the dof map
6723
const char* UFC_CahnHilliard2DBilinearForm_dof_map_2_0::signature() const
6725
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6728
/// Return true iff mesh entities of topological dimension d are needed
6729
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_0::needs_mesh_entities(unsigned int d) const
6746
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6747
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_0::init_mesh(const ufc::mesh& m)
6749
__global_dimension = m.num_entities[0];
6753
/// Initialize dof map for given cell
6754
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::init_cell(const ufc::mesh& m,
6760
/// Finish initialization of dof map for cells
6761
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::init_cell_finalize()
6766
/// Return the dimension of the global finite element function space
6767
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::global_dimension() const
6769
return __global_dimension;
6772
/// Return the dimension of the local finite element function space
6773
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::local_dimension() const
6778
// Return the geometric dimension of the coordinates this dof map provides
6779
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::geometric_dimension() const
6784
/// Return the number of dofs on each cell facet
6785
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::num_facet_dofs() const
6790
/// Return the number of dofs associated with each cell entity of dimension d
6791
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::num_entity_dofs(unsigned int d) const
6793
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6796
/// Tabulate the local-to-global mapping of dofs on a cell
6797
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
6799
const ufc::cell& c) const
6801
dofs[0] = c.entity_indices[0][0];
6802
dofs[1] = c.entity_indices[0][1];
6803
dofs[2] = c.entity_indices[0][2];
6806
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6807
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
6808
unsigned int facet) const
6827
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6828
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
6829
unsigned int d, unsigned int i) const
6831
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6834
/// Tabulate the coordinates of all dofs on a cell
6835
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_coordinates(double** coordinates,
6836
const ufc::cell& c) const
6838
const double * const * x = c.coordinates;
6839
coordinates[0][0] = x[0][0];
6840
coordinates[0][1] = x[0][1];
6841
coordinates[1][0] = x[1][0];
6842
coordinates[1][1] = x[1][1];
6843
coordinates[2][0] = x[2][0];
6844
coordinates[2][1] = x[2][1];
6847
/// Return the number of sub dof maps (for a mixed element)
6848
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::num_sub_dof_maps() const
6853
/// Create a new dof_map for sub dof map i (for a mixed element)
6854
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_2_0::create_sub_dof_map(unsigned int i) const
6856
return new UFC_CahnHilliard2DBilinearForm_dof_map_2_0();
6861
UFC_CahnHilliard2DBilinearForm_dof_map_2_1::UFC_CahnHilliard2DBilinearForm_dof_map_2_1() : ufc::dof_map()
6863
__global_dimension = 0;
6867
UFC_CahnHilliard2DBilinearForm_dof_map_2_1::~UFC_CahnHilliard2DBilinearForm_dof_map_2_1()
6872
/// Return a string identifying the dof map
6873
const char* UFC_CahnHilliard2DBilinearForm_dof_map_2_1::signature() const
6875
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6878
/// Return true iff mesh entities of topological dimension d are needed
6879
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_1::needs_mesh_entities(unsigned int d) const
6896
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6897
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_1::init_mesh(const ufc::mesh& m)
6899
__global_dimension = m.num_entities[0];
6903
/// Initialize dof map for given cell
6904
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::init_cell(const ufc::mesh& m,
6910
/// Finish initialization of dof map for cells
6911
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::init_cell_finalize()
6916
/// Return the dimension of the global finite element function space
6917
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::global_dimension() const
6919
return __global_dimension;
6922
/// Return the dimension of the local finite element function space
6923
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::local_dimension() const
6928
// Return the geometric dimension of the coordinates this dof map provides
6929
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::geometric_dimension() const
6934
/// Return the number of dofs on each cell facet
6935
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::num_facet_dofs() const
6940
/// Return the number of dofs associated with each cell entity of dimension d
6941
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::num_entity_dofs(unsigned int d) const
6943
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6946
/// Tabulate the local-to-global mapping of dofs on a cell
6947
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
6949
const ufc::cell& c) const
6951
dofs[0] = c.entity_indices[0][0];
6952
dofs[1] = c.entity_indices[0][1];
6953
dofs[2] = c.entity_indices[0][2];
6956
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6957
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
6958
unsigned int facet) const
6977
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6978
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
6979
unsigned int d, unsigned int i) const
6981
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6984
/// Tabulate the coordinates of all dofs on a cell
6985
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_coordinates(double** coordinates,
6986
const ufc::cell& c) const
6988
const double * const * x = c.coordinates;
6989
coordinates[0][0] = x[0][0];
6990
coordinates[0][1] = x[0][1];
6991
coordinates[1][0] = x[1][0];
6992
coordinates[1][1] = x[1][1];
6993
coordinates[2][0] = x[2][0];
6994
coordinates[2][1] = x[2][1];
6997
/// Return the number of sub dof maps (for a mixed element)
6998
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::num_sub_dof_maps() const
7003
/// Create a new dof_map for sub dof map i (for a mixed element)
7004
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_2_1::create_sub_dof_map(unsigned int i) const
7006
return new UFC_CahnHilliard2DBilinearForm_dof_map_2_1();
7011
UFC_CahnHilliard2DBilinearForm_dof_map_2::UFC_CahnHilliard2DBilinearForm_dof_map_2() : ufc::dof_map()
7013
__global_dimension = 0;
7017
UFC_CahnHilliard2DBilinearForm_dof_map_2::~UFC_CahnHilliard2DBilinearForm_dof_map_2()
7022
/// Return a string identifying the dof map
7023
const char* UFC_CahnHilliard2DBilinearForm_dof_map_2::signature() const
7025
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
7028
/// Return true iff mesh entities of topological dimension d are needed
7029
bool UFC_CahnHilliard2DBilinearForm_dof_map_2::needs_mesh_entities(unsigned int d) const
7046
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7047
bool UFC_CahnHilliard2DBilinearForm_dof_map_2::init_mesh(const ufc::mesh& m)
7049
__global_dimension = 2*m.num_entities[0];
7053
/// Initialize dof map for given cell
7054
void UFC_CahnHilliard2DBilinearForm_dof_map_2::init_cell(const ufc::mesh& m,
7060
/// Finish initialization of dof map for cells
7061
void UFC_CahnHilliard2DBilinearForm_dof_map_2::init_cell_finalize()
7066
/// Return the dimension of the global finite element function space
7067
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::global_dimension() const
7069
return __global_dimension;
7072
/// Return the dimension of the local finite element function space
7073
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::local_dimension() const
7078
// Return the geometric dimension of the coordinates this dof map provides
7079
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::geometric_dimension() const
7084
/// Return the number of dofs on each cell facet
7085
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::num_facet_dofs() const
7090
/// Return the number of dofs associated with each cell entity of dimension d
7091
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::num_entity_dofs(unsigned int d) const
7093
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7096
/// Tabulate the local-to-global mapping of dofs on a cell
7097
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_dofs(unsigned int* dofs,
7099
const ufc::cell& c) const
7101
dofs[0] = c.entity_indices[0][0];
7102
dofs[1] = c.entity_indices[0][1];
7103
dofs[2] = c.entity_indices[0][2];
7104
unsigned int offset = m.num_entities[0];
7105
dofs[3] = offset + c.entity_indices[0][0];
7106
dofs[4] = offset + c.entity_indices[0][1];
7107
dofs[5] = offset + c.entity_indices[0][2];
7110
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7111
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
7112
unsigned int facet) const
7137
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7138
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
7139
unsigned int d, unsigned int i) const
7141
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7144
/// Tabulate the coordinates of all dofs on a cell
7145
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_coordinates(double** coordinates,
7146
const ufc::cell& c) const
7148
const double * const * x = c.coordinates;
7149
coordinates[0][0] = x[0][0];
7150
coordinates[0][1] = x[0][1];
7151
coordinates[1][0] = x[1][0];
7152
coordinates[1][1] = x[1][1];
7153
coordinates[2][0] = x[2][0];
7154
coordinates[2][1] = x[2][1];
7155
coordinates[3][0] = x[0][0];
7156
coordinates[3][1] = x[0][1];
7157
coordinates[4][0] = x[1][0];
7158
coordinates[4][1] = x[1][1];
7159
coordinates[5][0] = x[2][0];
7160
coordinates[5][1] = x[2][1];
7163
/// Return the number of sub dof maps (for a mixed element)
7164
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::num_sub_dof_maps() const
7169
/// Create a new dof_map for sub dof map i (for a mixed element)
7170
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_2::create_sub_dof_map(unsigned int i) const
7175
return new UFC_CahnHilliard2DBilinearForm_dof_map_2_0();
7178
return new UFC_CahnHilliard2DBilinearForm_dof_map_2_1();
7186
UFC_CahnHilliard2DBilinearForm_dof_map_3::UFC_CahnHilliard2DBilinearForm_dof_map_3() : ufc::dof_map()
7188
__global_dimension = 0;
7192
UFC_CahnHilliard2DBilinearForm_dof_map_3::~UFC_CahnHilliard2DBilinearForm_dof_map_3()
7197
/// Return a string identifying the dof map
7198
const char* UFC_CahnHilliard2DBilinearForm_dof_map_3::signature() const
7200
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7203
/// Return true iff mesh entities of topological dimension d are needed
7204
bool UFC_CahnHilliard2DBilinearForm_dof_map_3::needs_mesh_entities(unsigned int d) const
7221
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7222
bool UFC_CahnHilliard2DBilinearForm_dof_map_3::init_mesh(const ufc::mesh& m)
7224
__global_dimension = m.num_entities[2];
7228
/// Initialize dof map for given cell
7229
void UFC_CahnHilliard2DBilinearForm_dof_map_3::init_cell(const ufc::mesh& m,
7235
/// Finish initialization of dof map for cells
7236
void UFC_CahnHilliard2DBilinearForm_dof_map_3::init_cell_finalize()
7241
/// Return the dimension of the global finite element function space
7242
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::global_dimension() const
7244
return __global_dimension;
7247
/// Return the dimension of the local finite element function space
7248
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::local_dimension() const
7253
// Return the geometric dimension of the coordinates this dof map provides
7254
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::geometric_dimension() const
7259
/// Return the number of dofs on each cell facet
7260
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::num_facet_dofs() const
7265
/// Return the number of dofs associated with each cell entity of dimension d
7266
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::num_entity_dofs(unsigned int d) const
7268
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7271
/// Tabulate the local-to-global mapping of dofs on a cell
7272
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_dofs(unsigned int* dofs,
7274
const ufc::cell& c) const
7276
dofs[0] = c.entity_indices[2][0];
7279
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7280
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
7281
unsigned int facet) const
7297
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7298
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
7299
unsigned int d, unsigned int i) const
7301
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7304
/// Tabulate the coordinates of all dofs on a cell
7305
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_coordinates(double** coordinates,
7306
const ufc::cell& c) const
7308
const double * const * x = c.coordinates;
7309
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7310
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7313
/// Return the number of sub dof maps (for a mixed element)
7314
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::num_sub_dof_maps() const
7319
/// Create a new dof_map for sub dof map i (for a mixed element)
7320
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_3::create_sub_dof_map(unsigned int i) const
7322
return new UFC_CahnHilliard2DBilinearForm_dof_map_3();
7327
UFC_CahnHilliard2DBilinearForm_dof_map_4::UFC_CahnHilliard2DBilinearForm_dof_map_4() : ufc::dof_map()
7329
__global_dimension = 0;
7333
UFC_CahnHilliard2DBilinearForm_dof_map_4::~UFC_CahnHilliard2DBilinearForm_dof_map_4()
7338
/// Return a string identifying the dof map
7339
const char* UFC_CahnHilliard2DBilinearForm_dof_map_4::signature() const
7341
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7344
/// Return true iff mesh entities of topological dimension d are needed
7345
bool UFC_CahnHilliard2DBilinearForm_dof_map_4::needs_mesh_entities(unsigned int d) const
7362
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7363
bool UFC_CahnHilliard2DBilinearForm_dof_map_4::init_mesh(const ufc::mesh& m)
7365
__global_dimension = m.num_entities[2];
7369
/// Initialize dof map for given cell
7370
void UFC_CahnHilliard2DBilinearForm_dof_map_4::init_cell(const ufc::mesh& m,
7376
/// Finish initialization of dof map for cells
7377
void UFC_CahnHilliard2DBilinearForm_dof_map_4::init_cell_finalize()
7382
/// Return the dimension of the global finite element function space
7383
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::global_dimension() const
7385
return __global_dimension;
7388
/// Return the dimension of the local finite element function space
7389
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::local_dimension() const
7394
// Return the geometric dimension of the coordinates this dof map provides
7395
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::geometric_dimension() const
7400
/// Return the number of dofs on each cell facet
7401
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::num_facet_dofs() const
7406
/// Return the number of dofs associated with each cell entity of dimension d
7407
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::num_entity_dofs(unsigned int d) const
7409
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7412
/// Tabulate the local-to-global mapping of dofs on a cell
7413
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_dofs(unsigned int* dofs,
7415
const ufc::cell& c) const
7417
dofs[0] = c.entity_indices[2][0];
7420
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7421
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
7422
unsigned int facet) const
7438
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7439
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
7440
unsigned int d, unsigned int i) const
7442
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7445
/// Tabulate the coordinates of all dofs on a cell
7446
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_coordinates(double** coordinates,
7447
const ufc::cell& c) const
7449
const double * const * x = c.coordinates;
7450
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7451
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7454
/// Return the number of sub dof maps (for a mixed element)
7455
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::num_sub_dof_maps() const
7460
/// Create a new dof_map for sub dof map i (for a mixed element)
7461
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_4::create_sub_dof_map(unsigned int i) const
7463
return new UFC_CahnHilliard2DBilinearForm_dof_map_4();
7468
UFC_CahnHilliard2DBilinearForm_dof_map_5::UFC_CahnHilliard2DBilinearForm_dof_map_5() : ufc::dof_map()
7470
__global_dimension = 0;
7474
UFC_CahnHilliard2DBilinearForm_dof_map_5::~UFC_CahnHilliard2DBilinearForm_dof_map_5()
7479
/// Return a string identifying the dof map
7480
const char* UFC_CahnHilliard2DBilinearForm_dof_map_5::signature() const
7482
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7485
/// Return true iff mesh entities of topological dimension d are needed
7486
bool UFC_CahnHilliard2DBilinearForm_dof_map_5::needs_mesh_entities(unsigned int d) const
7503
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7504
bool UFC_CahnHilliard2DBilinearForm_dof_map_5::init_mesh(const ufc::mesh& m)
7506
__global_dimension = m.num_entities[2];
7510
/// Initialize dof map for given cell
7511
void UFC_CahnHilliard2DBilinearForm_dof_map_5::init_cell(const ufc::mesh& m,
7517
/// Finish initialization of dof map for cells
7518
void UFC_CahnHilliard2DBilinearForm_dof_map_5::init_cell_finalize()
7523
/// Return the dimension of the global finite element function space
7524
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::global_dimension() const
7526
return __global_dimension;
7529
/// Return the dimension of the local finite element function space
7530
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::local_dimension() const
7535
// Return the geometric dimension of the coordinates this dof map provides
7536
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::geometric_dimension() const
7541
/// Return the number of dofs on each cell facet
7542
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::num_facet_dofs() const
7547
/// Return the number of dofs associated with each cell entity of dimension d
7548
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::num_entity_dofs(unsigned int d) const
7550
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7553
/// Tabulate the local-to-global mapping of dofs on a cell
7554
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_dofs(unsigned int* dofs,
7556
const ufc::cell& c) const
7558
dofs[0] = c.entity_indices[2][0];
7561
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7562
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
7563
unsigned int facet) const
7579
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7580
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
7581
unsigned int d, unsigned int i) const
7583
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7586
/// Tabulate the coordinates of all dofs on a cell
7587
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_coordinates(double** coordinates,
7588
const ufc::cell& c) const
7590
const double * const * x = c.coordinates;
7591
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7592
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7595
/// Return the number of sub dof maps (for a mixed element)
7596
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::num_sub_dof_maps() const
7601
/// Create a new dof_map for sub dof map i (for a mixed element)
7602
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_5::create_sub_dof_map(unsigned int i) const
7604
return new UFC_CahnHilliard2DBilinearForm_dof_map_5();
7609
UFC_CahnHilliard2DBilinearForm_dof_map_6::UFC_CahnHilliard2DBilinearForm_dof_map_6() : ufc::dof_map()
7611
__global_dimension = 0;
7615
UFC_CahnHilliard2DBilinearForm_dof_map_6::~UFC_CahnHilliard2DBilinearForm_dof_map_6()
7620
/// Return a string identifying the dof map
7621
const char* UFC_CahnHilliard2DBilinearForm_dof_map_6::signature() const
7623
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7626
/// Return true iff mesh entities of topological dimension d are needed
7627
bool UFC_CahnHilliard2DBilinearForm_dof_map_6::needs_mesh_entities(unsigned int d) const
7644
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7645
bool UFC_CahnHilliard2DBilinearForm_dof_map_6::init_mesh(const ufc::mesh& m)
7647
__global_dimension = m.num_entities[2];
7651
/// Initialize dof map for given cell
7652
void UFC_CahnHilliard2DBilinearForm_dof_map_6::init_cell(const ufc::mesh& m,
7658
/// Finish initialization of dof map for cells
7659
void UFC_CahnHilliard2DBilinearForm_dof_map_6::init_cell_finalize()
7664
/// Return the dimension of the global finite element function space
7665
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::global_dimension() const
7667
return __global_dimension;
7670
/// Return the dimension of the local finite element function space
7671
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::local_dimension() const
7676
// Return the geometric dimension of the coordinates this dof map provides
7677
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::geometric_dimension() const
7682
/// Return the number of dofs on each cell facet
7683
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::num_facet_dofs() const
7688
/// Return the number of dofs associated with each cell entity of dimension d
7689
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::num_entity_dofs(unsigned int d) const
7691
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7694
/// Tabulate the local-to-global mapping of dofs on a cell
7695
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_dofs(unsigned int* dofs,
7697
const ufc::cell& c) const
7699
dofs[0] = c.entity_indices[2][0];
7702
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7703
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
7704
unsigned int facet) const
7720
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7721
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
7722
unsigned int d, unsigned int i) const
7724
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7727
/// Tabulate the coordinates of all dofs on a cell
7728
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_coordinates(double** coordinates,
7729
const ufc::cell& c) const
7731
const double * const * x = c.coordinates;
7732
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7733
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7736
/// Return the number of sub dof maps (for a mixed element)
7737
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::num_sub_dof_maps() const
7742
/// Create a new dof_map for sub dof map i (for a mixed element)
7743
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_6::create_sub_dof_map(unsigned int i) const
7745
return new UFC_CahnHilliard2DBilinearForm_dof_map_6();
7750
UFC_CahnHilliard2DBilinearForm_cell_integral_0::UFC_CahnHilliard2DBilinearForm_cell_integral_0() : ufc::cell_integral()
7756
UFC_CahnHilliard2DBilinearForm_cell_integral_0::~UFC_CahnHilliard2DBilinearForm_cell_integral_0()
4
cahnhilliard2d_0_finite_element_0_0::cahnhilliard2d_0_finite_element_0_0() : ufc::finite_element()
10
cahnhilliard2d_0_finite_element_0_0::~cahnhilliard2d_0_finite_element_0_0()
15
/// Return a string identifying the finite element
16
const char* cahnhilliard2d_0_finite_element_0_0::signature() const
18
return "FiniteElement('Lagrange', 'triangle', 1)";
21
/// Return the cell shape
22
ufc::shape cahnhilliard2d_0_finite_element_0_0::cell_shape() const
27
/// Return the dimension of the finite element function space
28
unsigned int cahnhilliard2d_0_finite_element_0_0::space_dimension() const
33
/// Return the rank of the value space
34
unsigned int cahnhilliard2d_0_finite_element_0_0::value_rank() const
39
/// Return the dimension of the value space for axis i
40
unsigned int cahnhilliard2d_0_finite_element_0_0::value_dimension(unsigned int i) const
45
/// Evaluate basis function i at given point in cell
46
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis(unsigned int i,
48
const double* coordinates,
49
const ufc::cell& c) const
51
// Extract vertex coordinates
52
const double * const * element_coordinates = c.coordinates;
54
// Compute Jacobian of affine map from reference cell
55
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
56
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
57
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
58
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
60
// Compute determinant of Jacobian
61
const double detJ = J_00*J_11 - J_01*J_10;
63
// Compute inverse of Jacobian
65
// Get coordinates and map to the reference (UFC) element
66
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
67
element_coordinates[0][0]*element_coordinates[2][1] +\
68
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
69
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
70
element_coordinates[1][0]*element_coordinates[0][1] -\
71
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
73
// Map coordinates to the reference square
74
if (std::abs(y - 1.0) < 1e-14)
77
x = 2.0 *x/(1.0 - y) - 1.0;
83
// Map degree of freedom to element degree of freedom
84
const unsigned int dof = i;
87
const double scalings_y_0 = 1;
88
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
91
const double psitilde_a_0 = 1;
92
const double psitilde_a_1 = x;
94
// Compute psitilde_bs
95
const double psitilde_bs_0_0 = 1;
96
const double psitilde_bs_0_1 = 1.5*y + 0.5;
97
const double psitilde_bs_1_0 = 1;
99
// Compute basisvalues
100
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
101
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
102
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
104
// Table(s) of coefficients
105
static const double coefficients0[3][3] = \
106
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
107
{0.471404520791032, 0.288675134594813, -0.166666666666667},
108
{0.471404520791032, 0, 0.333333333333333}};
110
// Extract relevant coefficients
111
const double coeff0_0 = coefficients0[dof][0];
112
const double coeff0_1 = coefficients0[dof][1];
113
const double coeff0_2 = coefficients0[dof][2];
116
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
119
/// Evaluate all basis functions at given point in cell
120
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis_all(double* values,
121
const double* coordinates,
122
const ufc::cell& c) const
124
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
127
/// Evaluate order n derivatives of basis function i at given point in cell
128
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis_derivatives(unsigned int i,
131
const double* coordinates,
132
const ufc::cell& c) const
134
// Extract vertex coordinates
135
const double * const * element_coordinates = c.coordinates;
137
// Compute Jacobian of affine map from reference cell
138
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
139
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
140
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
141
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
143
// Compute determinant of Jacobian
144
const double detJ = J_00*J_11 - J_01*J_10;
146
// Compute inverse of Jacobian
148
// Get coordinates and map to the reference (UFC) element
149
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
150
element_coordinates[0][0]*element_coordinates[2][1] +\
151
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
152
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
153
element_coordinates[1][0]*element_coordinates[0][1] -\
154
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
156
// Map coordinates to the reference square
157
if (std::abs(y - 1.0) < 1e-14)
160
x = 2.0 *x/(1.0 - y) - 1.0;
163
// Compute number of derivatives
164
unsigned int num_derivatives = 1;
166
for (unsigned int j = 0; j < n; j++)
167
num_derivatives *= 2;
170
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
171
unsigned int **combinations = new unsigned int *[num_derivatives];
173
for (unsigned int j = 0; j < num_derivatives; j++)
175
combinations[j] = new unsigned int [n];
176
for (unsigned int k = 0; k < n; k++)
177
combinations[j][k] = 0;
180
// Generate combinations of derivatives
181
for (unsigned int row = 1; row < num_derivatives; row++)
183
for (unsigned int num = 0; num < row; num++)
185
for (unsigned int col = n-1; col+1 > 0; col--)
187
if (combinations[row][col] + 1 > 1)
188
combinations[row][col] = 0;
191
combinations[row][col] += 1;
198
// Compute inverse of Jacobian
199
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
201
// Declare transformation matrix
202
// Declare pointer to two dimensional array and initialise
203
double **transform = new double *[num_derivatives];
205
for (unsigned int j = 0; j < num_derivatives; j++)
207
transform[j] = new double [num_derivatives];
208
for (unsigned int k = 0; k < num_derivatives; k++)
212
// Construct transformation matrix
213
for (unsigned int row = 0; row < num_derivatives; row++)
215
for (unsigned int col = 0; col < num_derivatives; col++)
217
for (unsigned int k = 0; k < n; k++)
218
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
223
for (unsigned int j = 0; j < 1*num_derivatives; j++)
226
// Map degree of freedom to element degree of freedom
227
const unsigned int dof = i;
230
const double scalings_y_0 = 1;
231
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
233
// Compute psitilde_a
234
const double psitilde_a_0 = 1;
235
const double psitilde_a_1 = x;
237
// Compute psitilde_bs
238
const double psitilde_bs_0_0 = 1;
239
const double psitilde_bs_0_1 = 1.5*y + 0.5;
240
const double psitilde_bs_1_0 = 1;
242
// Compute basisvalues
243
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
244
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
245
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
247
// Table(s) of coefficients
248
static const double coefficients0[3][3] = \
249
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
250
{0.471404520791032, 0.288675134594813, -0.166666666666667},
251
{0.471404520791032, 0, 0.333333333333333}};
253
// Interesting (new) part
254
// Tables of derivatives of the polynomial base (transpose)
255
static const double dmats0[3][3] = \
257
{4.89897948556636, 0, 0},
260
static const double dmats1[3][3] = \
262
{2.44948974278318, 0, 0},
263
{4.24264068711928, 0, 0}};
265
// Compute reference derivatives
266
// Declare pointer to array of derivatives on FIAT element
267
double *derivatives = new double [num_derivatives];
269
// Declare coefficients
274
// Declare new coefficients
275
double new_coeff0_0 = 0;
276
double new_coeff0_1 = 0;
277
double new_coeff0_2 = 0;
279
// Loop possible derivatives
280
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
282
// Get values from coefficients array
283
new_coeff0_0 = coefficients0[dof][0];
284
new_coeff0_1 = coefficients0[dof][1];
285
new_coeff0_2 = coefficients0[dof][2];
287
// Loop derivative order
288
for (unsigned int j = 0; j < n; j++)
290
// Update old coefficients
291
coeff0_0 = new_coeff0_0;
292
coeff0_1 = new_coeff0_1;
293
coeff0_2 = new_coeff0_2;
295
if(combinations[deriv_num][j] == 0)
297
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
298
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
299
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
301
if(combinations[deriv_num][j] == 1)
303
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
304
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
305
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
309
// Compute derivatives on reference element as dot product of coefficients and basisvalues
310
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
313
// Transform derivatives back to physical element
314
for (unsigned int row = 0; row < num_derivatives; row++)
316
for (unsigned int col = 0; col < num_derivatives; col++)
318
values[row] += transform[row][col]*derivatives[col];
321
// Delete pointer to array of derivatives on FIAT element
322
delete [] derivatives;
324
// Delete pointer to array of combinations of derivatives and transform
325
for (unsigned int row = 0; row < num_derivatives; row++)
327
delete [] combinations[row];
328
delete [] transform[row];
331
delete [] combinations;
335
/// Evaluate order n derivatives of all basis functions at given point in cell
336
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
338
const double* coordinates,
339
const ufc::cell& c) const
341
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
344
/// Evaluate linear functional for dof i on the function f
345
double cahnhilliard2d_0_finite_element_0_0::evaluate_dof(unsigned int i,
346
const ufc::function& f,
347
const ufc::cell& c) const
349
// The reference points, direction and weights:
350
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
351
static const double W[3][1] = {{1}, {1}, {1}};
352
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
354
const double * const * x = c.coordinates;
356
// Iterate over the points:
357
// Evaluate basis functions for affine mapping
358
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
359
const double w1 = X[i][0][0];
360
const double w2 = X[i][0][1];
362
// Compute affine mapping y = F(X)
364
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
365
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
367
// Evaluate function at physical points
369
f.evaluate(values, y, c);
371
// Map function values using appropriate mapping
372
// Affine map: Do nothing
374
// Note that we do not map the weights (yet).
376
// Take directional components
377
for(int k = 0; k < 1; k++)
378
result += values[k]*D[i][0][k];
379
// Multiply by weights
385
/// Evaluate linear functionals for all dofs on the function f
386
void cahnhilliard2d_0_finite_element_0_0::evaluate_dofs(double* values,
387
const ufc::function& f,
388
const ufc::cell& c) const
390
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
393
/// Interpolate vertex values from dof values
394
void cahnhilliard2d_0_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
395
const double* dof_values,
396
const ufc::cell& c) const
398
// Evaluate at vertices and use affine mapping
399
vertex_values[0] = dof_values[0];
400
vertex_values[1] = dof_values[1];
401
vertex_values[2] = dof_values[2];
404
/// Return the number of sub elements (for a mixed element)
405
unsigned int cahnhilliard2d_0_finite_element_0_0::num_sub_elements() const
410
/// Create a new finite element for sub element i (for a mixed element)
411
ufc::finite_element* cahnhilliard2d_0_finite_element_0_0::create_sub_element(unsigned int i) const
413
return new cahnhilliard2d_0_finite_element_0_0();
418
cahnhilliard2d_0_finite_element_0_1::cahnhilliard2d_0_finite_element_0_1() : ufc::finite_element()
424
cahnhilliard2d_0_finite_element_0_1::~cahnhilliard2d_0_finite_element_0_1()
429
/// Return a string identifying the finite element
430
const char* cahnhilliard2d_0_finite_element_0_1::signature() const
432
return "FiniteElement('Lagrange', 'triangle', 1)";
435
/// Return the cell shape
436
ufc::shape cahnhilliard2d_0_finite_element_0_1::cell_shape() const
438
return ufc::triangle;
441
/// Return the dimension of the finite element function space
442
unsigned int cahnhilliard2d_0_finite_element_0_1::space_dimension() const
447
/// Return the rank of the value space
448
unsigned int cahnhilliard2d_0_finite_element_0_1::value_rank() const
453
/// Return the dimension of the value space for axis i
454
unsigned int cahnhilliard2d_0_finite_element_0_1::value_dimension(unsigned int i) const
459
/// Evaluate basis function i at given point in cell
460
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis(unsigned int i,
462
const double* coordinates,
463
const ufc::cell& c) const
465
// Extract vertex coordinates
466
const double * const * element_coordinates = c.coordinates;
468
// Compute Jacobian of affine map from reference cell
469
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
470
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
471
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
472
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
474
// Compute determinant of Jacobian
475
const double detJ = J_00*J_11 - J_01*J_10;
477
// Compute inverse of Jacobian
479
// Get coordinates and map to the reference (UFC) element
480
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
481
element_coordinates[0][0]*element_coordinates[2][1] +\
482
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
483
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
484
element_coordinates[1][0]*element_coordinates[0][1] -\
485
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
487
// Map coordinates to the reference square
488
if (std::abs(y - 1.0) < 1e-14)
491
x = 2.0 *x/(1.0 - y) - 1.0;
497
// Map degree of freedom to element degree of freedom
498
const unsigned int dof = i;
501
const double scalings_y_0 = 1;
502
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
504
// Compute psitilde_a
505
const double psitilde_a_0 = 1;
506
const double psitilde_a_1 = x;
508
// Compute psitilde_bs
509
const double psitilde_bs_0_0 = 1;
510
const double psitilde_bs_0_1 = 1.5*y + 0.5;
511
const double psitilde_bs_1_0 = 1;
513
// Compute basisvalues
514
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
515
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
516
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
518
// Table(s) of coefficients
519
static const double coefficients0[3][3] = \
520
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
521
{0.471404520791032, 0.288675134594813, -0.166666666666667},
522
{0.471404520791032, 0, 0.333333333333333}};
524
// Extract relevant coefficients
525
const double coeff0_0 = coefficients0[dof][0];
526
const double coeff0_1 = coefficients0[dof][1];
527
const double coeff0_2 = coefficients0[dof][2];
530
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
533
/// Evaluate all basis functions at given point in cell
534
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis_all(double* values,
535
const double* coordinates,
536
const ufc::cell& c) const
538
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
541
/// Evaluate order n derivatives of basis function i at given point in cell
542
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
545
const double* coordinates,
546
const ufc::cell& c) const
548
// Extract vertex coordinates
549
const double * const * element_coordinates = c.coordinates;
551
// Compute Jacobian of affine map from reference cell
552
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
553
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
554
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
555
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
557
// Compute determinant of Jacobian
558
const double detJ = J_00*J_11 - J_01*J_10;
560
// Compute inverse of Jacobian
562
// Get coordinates and map to the reference (UFC) element
563
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
564
element_coordinates[0][0]*element_coordinates[2][1] +\
565
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
566
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
567
element_coordinates[1][0]*element_coordinates[0][1] -\
568
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
570
// Map coordinates to the reference square
571
if (std::abs(y - 1.0) < 1e-14)
574
x = 2.0 *x/(1.0 - y) - 1.0;
577
// Compute number of derivatives
578
unsigned int num_derivatives = 1;
580
for (unsigned int j = 0; j < n; j++)
581
num_derivatives *= 2;
584
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
585
unsigned int **combinations = new unsigned int *[num_derivatives];
587
for (unsigned int j = 0; j < num_derivatives; j++)
589
combinations[j] = new unsigned int [n];
590
for (unsigned int k = 0; k < n; k++)
591
combinations[j][k] = 0;
594
// Generate combinations of derivatives
595
for (unsigned int row = 1; row < num_derivatives; row++)
597
for (unsigned int num = 0; num < row; num++)
599
for (unsigned int col = n-1; col+1 > 0; col--)
601
if (combinations[row][col] + 1 > 1)
602
combinations[row][col] = 0;
605
combinations[row][col] += 1;
612
// Compute inverse of Jacobian
613
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
615
// Declare transformation matrix
616
// Declare pointer to two dimensional array and initialise
617
double **transform = new double *[num_derivatives];
619
for (unsigned int j = 0; j < num_derivatives; j++)
621
transform[j] = new double [num_derivatives];
622
for (unsigned int k = 0; k < num_derivatives; k++)
626
// Construct transformation matrix
627
for (unsigned int row = 0; row < num_derivatives; row++)
629
for (unsigned int col = 0; col < num_derivatives; col++)
631
for (unsigned int k = 0; k < n; k++)
632
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
637
for (unsigned int j = 0; j < 1*num_derivatives; j++)
640
// Map degree of freedom to element degree of freedom
641
const unsigned int dof = i;
644
const double scalings_y_0 = 1;
645
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
647
// Compute psitilde_a
648
const double psitilde_a_0 = 1;
649
const double psitilde_a_1 = x;
651
// Compute psitilde_bs
652
const double psitilde_bs_0_0 = 1;
653
const double psitilde_bs_0_1 = 1.5*y + 0.5;
654
const double psitilde_bs_1_0 = 1;
656
// Compute basisvalues
657
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
658
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
659
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
661
// Table(s) of coefficients
662
static const double coefficients0[3][3] = \
663
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
664
{0.471404520791032, 0.288675134594813, -0.166666666666667},
665
{0.471404520791032, 0, 0.333333333333333}};
667
// Interesting (new) part
668
// Tables of derivatives of the polynomial base (transpose)
669
static const double dmats0[3][3] = \
671
{4.89897948556636, 0, 0},
674
static const double dmats1[3][3] = \
676
{2.44948974278318, 0, 0},
677
{4.24264068711928, 0, 0}};
679
// Compute reference derivatives
680
// Declare pointer to array of derivatives on FIAT element
681
double *derivatives = new double [num_derivatives];
683
// Declare coefficients
688
// Declare new coefficients
689
double new_coeff0_0 = 0;
690
double new_coeff0_1 = 0;
691
double new_coeff0_2 = 0;
693
// Loop possible derivatives
694
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
696
// Get values from coefficients array
697
new_coeff0_0 = coefficients0[dof][0];
698
new_coeff0_1 = coefficients0[dof][1];
699
new_coeff0_2 = coefficients0[dof][2];
701
// Loop derivative order
702
for (unsigned int j = 0; j < n; j++)
704
// Update old coefficients
705
coeff0_0 = new_coeff0_0;
706
coeff0_1 = new_coeff0_1;
707
coeff0_2 = new_coeff0_2;
709
if(combinations[deriv_num][j] == 0)
711
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
712
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
713
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
715
if(combinations[deriv_num][j] == 1)
717
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
718
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
719
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
723
// Compute derivatives on reference element as dot product of coefficients and basisvalues
724
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
727
// Transform derivatives back to physical element
728
for (unsigned int row = 0; row < num_derivatives; row++)
730
for (unsigned int col = 0; col < num_derivatives; col++)
732
values[row] += transform[row][col]*derivatives[col];
735
// Delete pointer to array of derivatives on FIAT element
736
delete [] derivatives;
738
// Delete pointer to array of combinations of derivatives and transform
739
for (unsigned int row = 0; row < num_derivatives; row++)
741
delete [] combinations[row];
742
delete [] transform[row];
745
delete [] combinations;
749
/// Evaluate order n derivatives of all basis functions at given point in cell
750
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
752
const double* coordinates,
753
const ufc::cell& c) const
755
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
758
/// Evaluate linear functional for dof i on the function f
759
double cahnhilliard2d_0_finite_element_0_1::evaluate_dof(unsigned int i,
760
const ufc::function& f,
761
const ufc::cell& c) const
763
// The reference points, direction and weights:
764
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
765
static const double W[3][1] = {{1}, {1}, {1}};
766
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
768
const double * const * x = c.coordinates;
770
// Iterate over the points:
771
// Evaluate basis functions for affine mapping
772
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
773
const double w1 = X[i][0][0];
774
const double w2 = X[i][0][1];
776
// Compute affine mapping y = F(X)
778
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
779
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
781
// Evaluate function at physical points
783
f.evaluate(values, y, c);
785
// Map function values using appropriate mapping
786
// Affine map: Do nothing
788
// Note that we do not map the weights (yet).
790
// Take directional components
791
for(int k = 0; k < 1; k++)
792
result += values[k]*D[i][0][k];
793
// Multiply by weights
799
/// Evaluate linear functionals for all dofs on the function f
800
void cahnhilliard2d_0_finite_element_0_1::evaluate_dofs(double* values,
801
const ufc::function& f,
802
const ufc::cell& c) const
804
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
807
/// Interpolate vertex values from dof values
808
void cahnhilliard2d_0_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
809
const double* dof_values,
810
const ufc::cell& c) const
812
// Evaluate at vertices and use affine mapping
813
vertex_values[0] = dof_values[0];
814
vertex_values[1] = dof_values[1];
815
vertex_values[2] = dof_values[2];
818
/// Return the number of sub elements (for a mixed element)
819
unsigned int cahnhilliard2d_0_finite_element_0_1::num_sub_elements() const
824
/// Create a new finite element for sub element i (for a mixed element)
825
ufc::finite_element* cahnhilliard2d_0_finite_element_0_1::create_sub_element(unsigned int i) const
827
return new cahnhilliard2d_0_finite_element_0_1();
832
cahnhilliard2d_0_finite_element_0::cahnhilliard2d_0_finite_element_0() : ufc::finite_element()
838
cahnhilliard2d_0_finite_element_0::~cahnhilliard2d_0_finite_element_0()
843
/// Return a string identifying the finite element
844
const char* cahnhilliard2d_0_finite_element_0::signature() const
846
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
849
/// Return the cell shape
850
ufc::shape cahnhilliard2d_0_finite_element_0::cell_shape() const
852
return ufc::triangle;
855
/// Return the dimension of the finite element function space
856
unsigned int cahnhilliard2d_0_finite_element_0::space_dimension() const
861
/// Return the rank of the value space
862
unsigned int cahnhilliard2d_0_finite_element_0::value_rank() const
867
/// Return the dimension of the value space for axis i
868
unsigned int cahnhilliard2d_0_finite_element_0::value_dimension(unsigned int i) const
873
/// Evaluate basis function i at given point in cell
874
void cahnhilliard2d_0_finite_element_0::evaluate_basis(unsigned int i,
876
const double* coordinates,
877
const ufc::cell& c) const
879
// Extract vertex coordinates
880
const double * const * element_coordinates = c.coordinates;
882
// Compute Jacobian of affine map from reference cell
883
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
884
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
885
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
886
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
888
// Compute determinant of Jacobian
889
const double detJ = J_00*J_11 - J_01*J_10;
891
// Compute inverse of Jacobian
893
// Get coordinates and map to the reference (UFC) element
894
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
895
element_coordinates[0][0]*element_coordinates[2][1] +\
896
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
897
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
898
element_coordinates[1][0]*element_coordinates[0][1] -\
899
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
901
// Map coordinates to the reference square
902
if (std::abs(y - 1.0) < 1e-14)
905
x = 2.0 *x/(1.0 - y) - 1.0;
912
if (0 <= i && i <= 2)
914
// Map degree of freedom to element degree of freedom
915
const unsigned int dof = i;
918
const double scalings_y_0 = 1;
919
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
921
// Compute psitilde_a
922
const double psitilde_a_0 = 1;
923
const double psitilde_a_1 = x;
925
// Compute psitilde_bs
926
const double psitilde_bs_0_0 = 1;
927
const double psitilde_bs_0_1 = 1.5*y + 0.5;
928
const double psitilde_bs_1_0 = 1;
930
// Compute basisvalues
931
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
932
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
933
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
935
// Table(s) of coefficients
936
static const double coefficients0[3][3] = \
937
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
938
{0.471404520791032, 0.288675134594813, -0.166666666666667},
939
{0.471404520791032, 0, 0.333333333333333}};
941
// Extract relevant coefficients
942
const double coeff0_0 = coefficients0[dof][0];
943
const double coeff0_1 = coefficients0[dof][1];
944
const double coeff0_2 = coefficients0[dof][2];
947
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
950
if (3 <= i && i <= 5)
952
// Map degree of freedom to element degree of freedom
953
const unsigned int dof = i - 3;
956
const double scalings_y_0 = 1;
957
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
959
// Compute psitilde_a
960
const double psitilde_a_0 = 1;
961
const double psitilde_a_1 = x;
963
// Compute psitilde_bs
964
const double psitilde_bs_0_0 = 1;
965
const double psitilde_bs_0_1 = 1.5*y + 0.5;
966
const double psitilde_bs_1_0 = 1;
968
// Compute basisvalues
969
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
970
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
971
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
973
// Table(s) of coefficients
974
static const double coefficients0[3][3] = \
975
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
976
{0.471404520791032, 0.288675134594813, -0.166666666666667},
977
{0.471404520791032, 0, 0.333333333333333}};
979
// Extract relevant coefficients
980
const double coeff0_0 = coefficients0[dof][0];
981
const double coeff0_1 = coefficients0[dof][1];
982
const double coeff0_2 = coefficients0[dof][2];
985
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
990
/// Evaluate all basis functions at given point in cell
991
void cahnhilliard2d_0_finite_element_0::evaluate_basis_all(double* values,
992
const double* coordinates,
993
const ufc::cell& c) const
995
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
998
/// Evaluate order n derivatives of basis function i at given point in cell
999
void cahnhilliard2d_0_finite_element_0::evaluate_basis_derivatives(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-14)
1031
x = 2.0 *x/(1.0 - y) - 1.0;
1034
// Compute number of derivatives
1035
unsigned int num_derivatives = 1;
1037
for (unsigned int j = 0; j < n; j++)
1038
num_derivatives *= 2;
1041
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1042
unsigned int **combinations = new unsigned int *[num_derivatives];
1044
for (unsigned int j = 0; j < num_derivatives; j++)
1046
combinations[j] = new unsigned int [n];
1047
for (unsigned int k = 0; k < n; k++)
1048
combinations[j][k] = 0;
1051
// Generate combinations of derivatives
1052
for (unsigned int row = 1; row < num_derivatives; row++)
1054
for (unsigned int num = 0; num < row; num++)
1056
for (unsigned int col = n-1; col+1 > 0; col--)
1058
if (combinations[row][col] + 1 > 1)
1059
combinations[row][col] = 0;
1062
combinations[row][col] += 1;
1069
// Compute inverse of Jacobian
1070
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1072
// Declare transformation matrix
1073
// Declare pointer to two dimensional array and initialise
1074
double **transform = new double *[num_derivatives];
1076
for (unsigned int j = 0; j < num_derivatives; j++)
1078
transform[j] = new double [num_derivatives];
1079
for (unsigned int k = 0; k < num_derivatives; k++)
1080
transform[j][k] = 1;
1083
// Construct transformation matrix
1084
for (unsigned int row = 0; row < num_derivatives; row++)
1086
for (unsigned int col = 0; col < num_derivatives; col++)
1088
for (unsigned int k = 0; k < n; k++)
1089
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1094
for (unsigned int j = 0; j < 2*num_derivatives; j++)
1097
if (0 <= i && i <= 2)
1099
// Map degree of freedom to element degree of freedom
1100
const unsigned int dof = i;
1102
// Generate scalings
1103
const double scalings_y_0 = 1;
1104
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1106
// Compute psitilde_a
1107
const double psitilde_a_0 = 1;
1108
const double psitilde_a_1 = x;
1110
// Compute psitilde_bs
1111
const double psitilde_bs_0_0 = 1;
1112
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1113
const double psitilde_bs_1_0 = 1;
1115
// Compute basisvalues
1116
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1117
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1118
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1120
// Table(s) of coefficients
1121
static const double coefficients0[3][3] = \
1122
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1123
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1124
{0.471404520791032, 0, 0.333333333333333}};
1126
// Interesting (new) part
1127
// Tables of derivatives of the polynomial base (transpose)
1128
static const double dmats0[3][3] = \
1130
{4.89897948556636, 0, 0},
1133
static const double dmats1[3][3] = \
1135
{2.44948974278318, 0, 0},
1136
{4.24264068711928, 0, 0}};
1138
// Compute reference derivatives
1139
// Declare pointer to array of derivatives on FIAT element
1140
double *derivatives = new double [num_derivatives];
1142
// Declare coefficients
1143
double coeff0_0 = 0;
1144
double coeff0_1 = 0;
1145
double coeff0_2 = 0;
1147
// Declare new coefficients
1148
double new_coeff0_0 = 0;
1149
double new_coeff0_1 = 0;
1150
double new_coeff0_2 = 0;
1152
// Loop possible derivatives
1153
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1155
// Get values from coefficients array
1156
new_coeff0_0 = coefficients0[dof][0];
1157
new_coeff0_1 = coefficients0[dof][1];
1158
new_coeff0_2 = coefficients0[dof][2];
1160
// Loop derivative order
1161
for (unsigned int j = 0; j < n; j++)
1163
// Update old coefficients
1164
coeff0_0 = new_coeff0_0;
1165
coeff0_1 = new_coeff0_1;
1166
coeff0_2 = new_coeff0_2;
1168
if(combinations[deriv_num][j] == 0)
1170
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1171
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1172
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1174
if(combinations[deriv_num][j] == 1)
1176
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1177
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1178
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1182
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1183
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1186
// Transform derivatives back to physical element
1187
for (unsigned int row = 0; row < num_derivatives; row++)
1189
for (unsigned int col = 0; col < num_derivatives; col++)
1191
values[row] += transform[row][col]*derivatives[col];
1194
// Delete pointer to array of derivatives on FIAT element
1195
delete [] derivatives;
1197
// Delete pointer to array of combinations of derivatives and transform
1198
for (unsigned int row = 0; row < num_derivatives; row++)
1200
delete [] combinations[row];
1201
delete [] transform[row];
1204
delete [] combinations;
1205
delete [] transform;
1208
if (3 <= i && i <= 5)
1210
// Map degree of freedom to element degree of freedom
1211
const unsigned int dof = i - 3;
1213
// Generate scalings
1214
const double scalings_y_0 = 1;
1215
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1217
// Compute psitilde_a
1218
const double psitilde_a_0 = 1;
1219
const double psitilde_a_1 = x;
1221
// Compute psitilde_bs
1222
const double psitilde_bs_0_0 = 1;
1223
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1224
const double psitilde_bs_1_0 = 1;
1226
// Compute basisvalues
1227
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1228
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1229
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1231
// Table(s) of coefficients
1232
static const double coefficients0[3][3] = \
1233
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1234
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1235
{0.471404520791032, 0, 0.333333333333333}};
1237
// Interesting (new) part
1238
// Tables of derivatives of the polynomial base (transpose)
1239
static const double dmats0[3][3] = \
1241
{4.89897948556636, 0, 0},
1244
static const double dmats1[3][3] = \
1246
{2.44948974278318, 0, 0},
1247
{4.24264068711928, 0, 0}};
1249
// Compute reference derivatives
1250
// Declare pointer to array of derivatives on FIAT element
1251
double *derivatives = new double [num_derivatives];
1253
// Declare coefficients
1254
double coeff0_0 = 0;
1255
double coeff0_1 = 0;
1256
double coeff0_2 = 0;
1258
// Declare new coefficients
1259
double new_coeff0_0 = 0;
1260
double new_coeff0_1 = 0;
1261
double new_coeff0_2 = 0;
1263
// Loop possible derivatives
1264
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1266
// Get values from coefficients array
1267
new_coeff0_0 = coefficients0[dof][0];
1268
new_coeff0_1 = coefficients0[dof][1];
1269
new_coeff0_2 = coefficients0[dof][2];
1271
// Loop derivative order
1272
for (unsigned int j = 0; j < n; j++)
1274
// Update old coefficients
1275
coeff0_0 = new_coeff0_0;
1276
coeff0_1 = new_coeff0_1;
1277
coeff0_2 = new_coeff0_2;
1279
if(combinations[deriv_num][j] == 0)
1281
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1282
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1283
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1285
if(combinations[deriv_num][j] == 1)
1287
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1288
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1289
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1293
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1294
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1297
// Transform derivatives back to physical element
1298
for (unsigned int row = 0; row < num_derivatives; row++)
1300
for (unsigned int col = 0; col < num_derivatives; col++)
1302
values[num_derivatives + row] += transform[row][col]*derivatives[col];
1305
// Delete pointer to array of derivatives on FIAT element
1306
delete [] derivatives;
1308
// Delete pointer to array of combinations of derivatives and transform
1309
for (unsigned int row = 0; row < num_derivatives; row++)
1311
delete [] combinations[row];
1312
delete [] transform[row];
1315
delete [] combinations;
1316
delete [] transform;
1321
/// Evaluate order n derivatives of all basis functions at given point in cell
1322
void cahnhilliard2d_0_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
1324
const double* coordinates,
1325
const ufc::cell& c) const
1327
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1330
/// Evaluate linear functional for dof i on the function f
1331
double cahnhilliard2d_0_finite_element_0::evaluate_dof(unsigned int i,
1332
const ufc::function& f,
1333
const ufc::cell& c) const
1335
// The reference points, direction and weights:
1336
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
1337
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
1338
static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
1340
const double * const * x = c.coordinates;
1341
double result = 0.0;
1342
// Iterate over the points:
1343
// Evaluate basis functions for affine mapping
1344
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1345
const double w1 = X[i][0][0];
1346
const double w2 = X[i][0][1];
1348
// Compute affine mapping y = F(X)
1350
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1351
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1353
// Evaluate function at physical points
1355
f.evaluate(values, y, c);
1357
// Map function values using appropriate mapping
1358
// Affine map: Do nothing
1360
// Note that we do not map the weights (yet).
1362
// Take directional components
1363
for(int k = 0; k < 2; k++)
1364
result += values[k]*D[i][0][k];
1365
// Multiply by weights
1371
/// Evaluate linear functionals for all dofs on the function f
1372
void cahnhilliard2d_0_finite_element_0::evaluate_dofs(double* values,
1373
const ufc::function& f,
1374
const ufc::cell& c) const
1376
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1379
/// Interpolate vertex values from dof values
1380
void cahnhilliard2d_0_finite_element_0::interpolate_vertex_values(double* vertex_values,
1381
const double* dof_values,
1382
const ufc::cell& c) const
1384
// Evaluate at vertices and use affine mapping
1385
vertex_values[0] = dof_values[0];
1386
vertex_values[2] = dof_values[1];
1387
vertex_values[4] = dof_values[2];
1388
// Evaluate at vertices and use affine mapping
1389
vertex_values[1] = dof_values[3];
1390
vertex_values[3] = dof_values[4];
1391
vertex_values[5] = dof_values[5];
1394
/// Return the number of sub elements (for a mixed element)
1395
unsigned int cahnhilliard2d_0_finite_element_0::num_sub_elements() const
1400
/// Create a new finite element for sub element i (for a mixed element)
1401
ufc::finite_element* cahnhilliard2d_0_finite_element_0::create_sub_element(unsigned int i) const
1406
return new cahnhilliard2d_0_finite_element_0_0();
1409
return new cahnhilliard2d_0_finite_element_0_1();
1417
cahnhilliard2d_0_finite_element_1_0::cahnhilliard2d_0_finite_element_1_0() : ufc::finite_element()
1423
cahnhilliard2d_0_finite_element_1_0::~cahnhilliard2d_0_finite_element_1_0()
1428
/// Return a string identifying the finite element
1429
const char* cahnhilliard2d_0_finite_element_1_0::signature() const
1431
return "FiniteElement('Lagrange', 'triangle', 1)";
1434
/// Return the cell shape
1435
ufc::shape cahnhilliard2d_0_finite_element_1_0::cell_shape() const
1437
return ufc::triangle;
1440
/// Return the dimension of the finite element function space
1441
unsigned int cahnhilliard2d_0_finite_element_1_0::space_dimension() const
1446
/// Return the rank of the value space
1447
unsigned int cahnhilliard2d_0_finite_element_1_0::value_rank() const
1452
/// Return the dimension of the value space for axis i
1453
unsigned int cahnhilliard2d_0_finite_element_1_0::value_dimension(unsigned int i) const
1458
/// Evaluate basis function i at given point in cell
1459
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis(unsigned int i,
1461
const double* coordinates,
1462
const ufc::cell& c) const
1464
// Extract vertex coordinates
1465
const double * const * element_coordinates = c.coordinates;
1467
// Compute Jacobian of affine map from reference cell
1468
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1469
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1470
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1471
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1473
// Compute determinant of Jacobian
1474
const double detJ = J_00*J_11 - J_01*J_10;
1476
// Compute inverse of Jacobian
1478
// Get coordinates and map to the reference (UFC) element
1479
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1480
element_coordinates[0][0]*element_coordinates[2][1] +\
1481
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1482
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1483
element_coordinates[1][0]*element_coordinates[0][1] -\
1484
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1486
// Map coordinates to the reference square
1487
if (std::abs(y - 1.0) < 1e-14)
1490
x = 2.0 *x/(1.0 - y) - 1.0;
1496
// Map degree of freedom to element degree of freedom
1497
const unsigned int dof = i;
1499
// Generate scalings
1500
const double scalings_y_0 = 1;
1501
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1503
// Compute psitilde_a
1504
const double psitilde_a_0 = 1;
1505
const double psitilde_a_1 = x;
1507
// Compute psitilde_bs
1508
const double psitilde_bs_0_0 = 1;
1509
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1510
const double psitilde_bs_1_0 = 1;
1512
// Compute basisvalues
1513
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1514
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1515
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1517
// Table(s) of coefficients
1518
static const double coefficients0[3][3] = \
1519
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1520
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1521
{0.471404520791032, 0, 0.333333333333333}};
1523
// Extract relevant coefficients
1524
const double coeff0_0 = coefficients0[dof][0];
1525
const double coeff0_1 = coefficients0[dof][1];
1526
const double coeff0_2 = coefficients0[dof][2];
1529
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1532
/// Evaluate all basis functions at given point in cell
1533
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis_all(double* values,
1534
const double* coordinates,
1535
const ufc::cell& c) const
1537
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1540
/// Evaluate order n derivatives of basis function i at given point in cell
1541
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
1544
const double* coordinates,
1545
const ufc::cell& c) const
1547
// Extract vertex coordinates
1548
const double * const * element_coordinates = c.coordinates;
1550
// Compute Jacobian of affine map from reference cell
1551
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1552
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1553
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1554
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1556
// Compute determinant of Jacobian
1557
const double detJ = J_00*J_11 - J_01*J_10;
1559
// Compute inverse of Jacobian
1561
// Get coordinates and map to the reference (UFC) element
1562
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1563
element_coordinates[0][0]*element_coordinates[2][1] +\
1564
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1565
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1566
element_coordinates[1][0]*element_coordinates[0][1] -\
1567
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1569
// Map coordinates to the reference square
1570
if (std::abs(y - 1.0) < 1e-14)
1573
x = 2.0 *x/(1.0 - y) - 1.0;
1576
// Compute number of derivatives
1577
unsigned int num_derivatives = 1;
1579
for (unsigned int j = 0; j < n; j++)
1580
num_derivatives *= 2;
1583
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1584
unsigned int **combinations = new unsigned int *[num_derivatives];
1586
for (unsigned int j = 0; j < num_derivatives; j++)
1588
combinations[j] = new unsigned int [n];
1589
for (unsigned int k = 0; k < n; k++)
1590
combinations[j][k] = 0;
1593
// Generate combinations of derivatives
1594
for (unsigned int row = 1; row < num_derivatives; row++)
1596
for (unsigned int num = 0; num < row; num++)
1598
for (unsigned int col = n-1; col+1 > 0; col--)
1600
if (combinations[row][col] + 1 > 1)
1601
combinations[row][col] = 0;
1604
combinations[row][col] += 1;
1611
// Compute inverse of Jacobian
1612
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1614
// Declare transformation matrix
1615
// Declare pointer to two dimensional array and initialise
1616
double **transform = new double *[num_derivatives];
1618
for (unsigned int j = 0; j < num_derivatives; j++)
1620
transform[j] = new double [num_derivatives];
1621
for (unsigned int k = 0; k < num_derivatives; k++)
1622
transform[j][k] = 1;
1625
// Construct transformation matrix
1626
for (unsigned int row = 0; row < num_derivatives; row++)
1628
for (unsigned int col = 0; col < num_derivatives; col++)
1630
for (unsigned int k = 0; k < n; k++)
1631
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1636
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1639
// Map degree of freedom to element degree of freedom
1640
const unsigned int dof = i;
1642
// Generate scalings
1643
const double scalings_y_0 = 1;
1644
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1646
// Compute psitilde_a
1647
const double psitilde_a_0 = 1;
1648
const double psitilde_a_1 = x;
1650
// Compute psitilde_bs
1651
const double psitilde_bs_0_0 = 1;
1652
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1653
const double psitilde_bs_1_0 = 1;
1655
// Compute basisvalues
1656
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1657
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1658
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1660
// Table(s) of coefficients
1661
static const double coefficients0[3][3] = \
1662
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1663
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1664
{0.471404520791032, 0, 0.333333333333333}};
1666
// Interesting (new) part
1667
// Tables of derivatives of the polynomial base (transpose)
1668
static const double dmats0[3][3] = \
1670
{4.89897948556636, 0, 0},
1673
static const double dmats1[3][3] = \
1675
{2.44948974278318, 0, 0},
1676
{4.24264068711928, 0, 0}};
1678
// Compute reference derivatives
1679
// Declare pointer to array of derivatives on FIAT element
1680
double *derivatives = new double [num_derivatives];
1682
// Declare coefficients
1683
double coeff0_0 = 0;
1684
double coeff0_1 = 0;
1685
double coeff0_2 = 0;
1687
// Declare new coefficients
1688
double new_coeff0_0 = 0;
1689
double new_coeff0_1 = 0;
1690
double new_coeff0_2 = 0;
1692
// Loop possible derivatives
1693
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1695
// Get values from coefficients array
1696
new_coeff0_0 = coefficients0[dof][0];
1697
new_coeff0_1 = coefficients0[dof][1];
1698
new_coeff0_2 = coefficients0[dof][2];
1700
// Loop derivative order
1701
for (unsigned int j = 0; j < n; j++)
1703
// Update old coefficients
1704
coeff0_0 = new_coeff0_0;
1705
coeff0_1 = new_coeff0_1;
1706
coeff0_2 = new_coeff0_2;
1708
if(combinations[deriv_num][j] == 0)
1710
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1711
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1712
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1714
if(combinations[deriv_num][j] == 1)
1716
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1717
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1718
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1722
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1723
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1726
// Transform derivatives back to physical element
1727
for (unsigned int row = 0; row < num_derivatives; row++)
1729
for (unsigned int col = 0; col < num_derivatives; col++)
1731
values[row] += transform[row][col]*derivatives[col];
1734
// Delete pointer to array of derivatives on FIAT element
1735
delete [] derivatives;
1737
// Delete pointer to array of combinations of derivatives and transform
1738
for (unsigned int row = 0; row < num_derivatives; row++)
1740
delete [] combinations[row];
1741
delete [] transform[row];
1744
delete [] combinations;
1745
delete [] transform;
1748
/// Evaluate order n derivatives of all basis functions at given point in cell
1749
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
1751
const double* coordinates,
1752
const ufc::cell& c) const
1754
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1757
/// Evaluate linear functional for dof i on the function f
1758
double cahnhilliard2d_0_finite_element_1_0::evaluate_dof(unsigned int i,
1759
const ufc::function& f,
1760
const ufc::cell& c) const
1762
// The reference points, direction and weights:
1763
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
1764
static const double W[3][1] = {{1}, {1}, {1}};
1765
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
1767
const double * const * x = c.coordinates;
1768
double result = 0.0;
1769
// Iterate over the points:
1770
// Evaluate basis functions for affine mapping
1771
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1772
const double w1 = X[i][0][0];
1773
const double w2 = X[i][0][1];
1775
// Compute affine mapping y = F(X)
1777
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1778
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1780
// Evaluate function at physical points
1782
f.evaluate(values, y, c);
1784
// Map function values using appropriate mapping
1785
// Affine map: Do nothing
1787
// Note that we do not map the weights (yet).
1789
// Take directional components
1790
for(int k = 0; k < 1; k++)
1791
result += values[k]*D[i][0][k];
1792
// Multiply by weights
1798
/// Evaluate linear functionals for all dofs on the function f
1799
void cahnhilliard2d_0_finite_element_1_0::evaluate_dofs(double* values,
1800
const ufc::function& f,
1801
const ufc::cell& c) const
1803
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1806
/// Interpolate vertex values from dof values
1807
void cahnhilliard2d_0_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
1808
const double* dof_values,
1809
const ufc::cell& c) const
1811
// Evaluate at vertices and use affine mapping
1812
vertex_values[0] = dof_values[0];
1813
vertex_values[1] = dof_values[1];
1814
vertex_values[2] = dof_values[2];
1817
/// Return the number of sub elements (for a mixed element)
1818
unsigned int cahnhilliard2d_0_finite_element_1_0::num_sub_elements() const
1823
/// Create a new finite element for sub element i (for a mixed element)
1824
ufc::finite_element* cahnhilliard2d_0_finite_element_1_0::create_sub_element(unsigned int i) const
1826
return new cahnhilliard2d_0_finite_element_1_0();
1831
cahnhilliard2d_0_finite_element_1_1::cahnhilliard2d_0_finite_element_1_1() : ufc::finite_element()
1837
cahnhilliard2d_0_finite_element_1_1::~cahnhilliard2d_0_finite_element_1_1()
1842
/// Return a string identifying the finite element
1843
const char* cahnhilliard2d_0_finite_element_1_1::signature() const
1845
return "FiniteElement('Lagrange', 'triangle', 1)";
1848
/// Return the cell shape
1849
ufc::shape cahnhilliard2d_0_finite_element_1_1::cell_shape() const
1851
return ufc::triangle;
1854
/// Return the dimension of the finite element function space
1855
unsigned int cahnhilliard2d_0_finite_element_1_1::space_dimension() const
1860
/// Return the rank of the value space
1861
unsigned int cahnhilliard2d_0_finite_element_1_1::value_rank() const
1866
/// Return the dimension of the value space for axis i
1867
unsigned int cahnhilliard2d_0_finite_element_1_1::value_dimension(unsigned int i) const
1872
/// Evaluate basis function i at given point in cell
1873
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis(unsigned int i,
1875
const double* coordinates,
1876
const ufc::cell& c) const
1878
// Extract vertex coordinates
1879
const double * const * element_coordinates = c.coordinates;
1881
// Compute Jacobian of affine map from reference cell
1882
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1883
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1884
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1885
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1887
// Compute determinant of Jacobian
1888
const double detJ = J_00*J_11 - J_01*J_10;
1890
// Compute inverse of Jacobian
1892
// Get coordinates and map to the reference (UFC) element
1893
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1894
element_coordinates[0][0]*element_coordinates[2][1] +\
1895
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1896
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1897
element_coordinates[1][0]*element_coordinates[0][1] -\
1898
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1900
// Map coordinates to the reference square
1901
if (std::abs(y - 1.0) < 1e-14)
1904
x = 2.0 *x/(1.0 - y) - 1.0;
1910
// Map degree of freedom to element degree of freedom
1911
const unsigned int dof = i;
1913
// Generate scalings
1914
const double scalings_y_0 = 1;
1915
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1917
// Compute psitilde_a
1918
const double psitilde_a_0 = 1;
1919
const double psitilde_a_1 = x;
1921
// Compute psitilde_bs
1922
const double psitilde_bs_0_0 = 1;
1923
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1924
const double psitilde_bs_1_0 = 1;
1926
// Compute basisvalues
1927
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1928
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1929
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1931
// Table(s) of coefficients
1932
static const double coefficients0[3][3] = \
1933
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1934
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1935
{0.471404520791032, 0, 0.333333333333333}};
1937
// Extract relevant coefficients
1938
const double coeff0_0 = coefficients0[dof][0];
1939
const double coeff0_1 = coefficients0[dof][1];
1940
const double coeff0_2 = coefficients0[dof][2];
1943
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1946
/// Evaluate all basis functions at given point in cell
1947
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis_all(double* values,
1948
const double* coordinates,
1949
const ufc::cell& c) const
1951
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1954
/// Evaluate order n derivatives of basis function i at given point in cell
1955
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
1958
const double* coordinates,
1959
const ufc::cell& c) const
1961
// Extract vertex coordinates
1962
const double * const * element_coordinates = c.coordinates;
1964
// Compute Jacobian of affine map from reference cell
1965
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1966
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1967
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1968
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1970
// Compute determinant of Jacobian
1971
const double detJ = J_00*J_11 - J_01*J_10;
1973
// Compute inverse of Jacobian
1975
// Get coordinates and map to the reference (UFC) element
1976
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1977
element_coordinates[0][0]*element_coordinates[2][1] +\
1978
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1979
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1980
element_coordinates[1][0]*element_coordinates[0][1] -\
1981
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1983
// Map coordinates to the reference square
1984
if (std::abs(y - 1.0) < 1e-14)
1987
x = 2.0 *x/(1.0 - y) - 1.0;
1990
// Compute number of derivatives
1991
unsigned int num_derivatives = 1;
1993
for (unsigned int j = 0; j < n; j++)
1994
num_derivatives *= 2;
1997
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1998
unsigned int **combinations = new unsigned int *[num_derivatives];
2000
for (unsigned int j = 0; j < num_derivatives; j++)
2002
combinations[j] = new unsigned int [n];
2003
for (unsigned int k = 0; k < n; k++)
2004
combinations[j][k] = 0;
2007
// Generate combinations of derivatives
2008
for (unsigned int row = 1; row < num_derivatives; row++)
2010
for (unsigned int num = 0; num < row; num++)
2012
for (unsigned int col = n-1; col+1 > 0; col--)
2014
if (combinations[row][col] + 1 > 1)
2015
combinations[row][col] = 0;
2018
combinations[row][col] += 1;
2025
// Compute inverse of Jacobian
2026
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2028
// Declare transformation matrix
2029
// Declare pointer to two dimensional array and initialise
2030
double **transform = new double *[num_derivatives];
2032
for (unsigned int j = 0; j < num_derivatives; j++)
2034
transform[j] = new double [num_derivatives];
2035
for (unsigned int k = 0; k < num_derivatives; k++)
2036
transform[j][k] = 1;
2039
// Construct transformation matrix
2040
for (unsigned int row = 0; row < num_derivatives; row++)
2042
for (unsigned int col = 0; col < num_derivatives; col++)
2044
for (unsigned int k = 0; k < n; k++)
2045
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2050
for (unsigned int j = 0; j < 1*num_derivatives; j++)
2053
// Map degree of freedom to element degree of freedom
2054
const unsigned int dof = i;
2056
// Generate scalings
2057
const double scalings_y_0 = 1;
2058
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2060
// Compute psitilde_a
2061
const double psitilde_a_0 = 1;
2062
const double psitilde_a_1 = x;
2064
// Compute psitilde_bs
2065
const double psitilde_bs_0_0 = 1;
2066
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2067
const double psitilde_bs_1_0 = 1;
2069
// Compute basisvalues
2070
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2071
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2072
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2074
// Table(s) of coefficients
2075
static const double coefficients0[3][3] = \
2076
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2077
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2078
{0.471404520791032, 0, 0.333333333333333}};
2080
// Interesting (new) part
2081
// Tables of derivatives of the polynomial base (transpose)
2082
static const double dmats0[3][3] = \
2084
{4.89897948556636, 0, 0},
2087
static const double dmats1[3][3] = \
2089
{2.44948974278318, 0, 0},
2090
{4.24264068711928, 0, 0}};
2092
// Compute reference derivatives
2093
// Declare pointer to array of derivatives on FIAT element
2094
double *derivatives = new double [num_derivatives];
2096
// Declare coefficients
2097
double coeff0_0 = 0;
2098
double coeff0_1 = 0;
2099
double coeff0_2 = 0;
2101
// Declare new coefficients
2102
double new_coeff0_0 = 0;
2103
double new_coeff0_1 = 0;
2104
double new_coeff0_2 = 0;
2106
// Loop possible derivatives
2107
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2109
// Get values from coefficients array
2110
new_coeff0_0 = coefficients0[dof][0];
2111
new_coeff0_1 = coefficients0[dof][1];
2112
new_coeff0_2 = coefficients0[dof][2];
2114
// Loop derivative order
2115
for (unsigned int j = 0; j < n; j++)
2117
// Update old coefficients
2118
coeff0_0 = new_coeff0_0;
2119
coeff0_1 = new_coeff0_1;
2120
coeff0_2 = new_coeff0_2;
2122
if(combinations[deriv_num][j] == 0)
2124
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2125
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2126
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2128
if(combinations[deriv_num][j] == 1)
2130
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2131
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2132
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2136
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2137
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2140
// Transform derivatives back to physical element
2141
for (unsigned int row = 0; row < num_derivatives; row++)
2143
for (unsigned int col = 0; col < num_derivatives; col++)
2145
values[row] += transform[row][col]*derivatives[col];
2148
// Delete pointer to array of derivatives on FIAT element
2149
delete [] derivatives;
2151
// Delete pointer to array of combinations of derivatives and transform
2152
for (unsigned int row = 0; row < num_derivatives; row++)
2154
delete [] combinations[row];
2155
delete [] transform[row];
2158
delete [] combinations;
2159
delete [] transform;
2162
/// Evaluate order n derivatives of all basis functions at given point in cell
2163
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
2165
const double* coordinates,
2166
const ufc::cell& c) const
2168
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2171
/// Evaluate linear functional for dof i on the function f
2172
double cahnhilliard2d_0_finite_element_1_1::evaluate_dof(unsigned int i,
2173
const ufc::function& f,
2174
const ufc::cell& c) const
2176
// The reference points, direction and weights:
2177
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
2178
static const double W[3][1] = {{1}, {1}, {1}};
2179
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
2181
const double * const * x = c.coordinates;
2182
double result = 0.0;
2183
// Iterate over the points:
2184
// Evaluate basis functions for affine mapping
2185
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2186
const double w1 = X[i][0][0];
2187
const double w2 = X[i][0][1];
2189
// Compute affine mapping y = F(X)
2191
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2192
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2194
// Evaluate function at physical points
2196
f.evaluate(values, y, c);
2198
// Map function values using appropriate mapping
2199
// Affine map: Do nothing
2201
// Note that we do not map the weights (yet).
2203
// Take directional components
2204
for(int k = 0; k < 1; k++)
2205
result += values[k]*D[i][0][k];
2206
// Multiply by weights
2212
/// Evaluate linear functionals for all dofs on the function f
2213
void cahnhilliard2d_0_finite_element_1_1::evaluate_dofs(double* values,
2214
const ufc::function& f,
2215
const ufc::cell& c) const
2217
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2220
/// Interpolate vertex values from dof values
2221
void cahnhilliard2d_0_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
2222
const double* dof_values,
2223
const ufc::cell& c) const
2225
// Evaluate at vertices and use affine mapping
2226
vertex_values[0] = dof_values[0];
2227
vertex_values[1] = dof_values[1];
2228
vertex_values[2] = dof_values[2];
2231
/// Return the number of sub elements (for a mixed element)
2232
unsigned int cahnhilliard2d_0_finite_element_1_1::num_sub_elements() const
2237
/// Create a new finite element for sub element i (for a mixed element)
2238
ufc::finite_element* cahnhilliard2d_0_finite_element_1_1::create_sub_element(unsigned int i) const
2240
return new cahnhilliard2d_0_finite_element_1_1();
2245
cahnhilliard2d_0_finite_element_1::cahnhilliard2d_0_finite_element_1() : ufc::finite_element()
2251
cahnhilliard2d_0_finite_element_1::~cahnhilliard2d_0_finite_element_1()
2256
/// Return a string identifying the finite element
2257
const char* cahnhilliard2d_0_finite_element_1::signature() const
2259
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
2262
/// Return the cell shape
2263
ufc::shape cahnhilliard2d_0_finite_element_1::cell_shape() const
2265
return ufc::triangle;
2268
/// Return the dimension of the finite element function space
2269
unsigned int cahnhilliard2d_0_finite_element_1::space_dimension() const
2274
/// Return the rank of the value space
2275
unsigned int cahnhilliard2d_0_finite_element_1::value_rank() const
2280
/// Return the dimension of the value space for axis i
2281
unsigned int cahnhilliard2d_0_finite_element_1::value_dimension(unsigned int i) const
2286
/// Evaluate basis function i at given point in cell
2287
void cahnhilliard2d_0_finite_element_1::evaluate_basis(unsigned int i,
2289
const double* coordinates,
2290
const ufc::cell& c) const
2292
// Extract vertex coordinates
2293
const double * const * element_coordinates = c.coordinates;
2295
// Compute Jacobian of affine map from reference cell
2296
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2297
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2298
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2299
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2301
// Compute determinant of Jacobian
2302
const double detJ = J_00*J_11 - J_01*J_10;
2304
// Compute inverse of Jacobian
2306
// Get coordinates and map to the reference (UFC) element
2307
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2308
element_coordinates[0][0]*element_coordinates[2][1] +\
2309
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2310
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2311
element_coordinates[1][0]*element_coordinates[0][1] -\
2312
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2314
// Map coordinates to the reference square
2315
if (std::abs(y - 1.0) < 1e-14)
2318
x = 2.0 *x/(1.0 - y) - 1.0;
2325
if (0 <= i && i <= 2)
2327
// Map degree of freedom to element degree of freedom
2328
const unsigned int dof = i;
2330
// Generate scalings
2331
const double scalings_y_0 = 1;
2332
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2334
// Compute psitilde_a
2335
const double psitilde_a_0 = 1;
2336
const double psitilde_a_1 = x;
2338
// Compute psitilde_bs
2339
const double psitilde_bs_0_0 = 1;
2340
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2341
const double psitilde_bs_1_0 = 1;
2343
// Compute basisvalues
2344
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2345
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2346
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2348
// Table(s) of coefficients
2349
static const double coefficients0[3][3] = \
2350
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2351
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2352
{0.471404520791032, 0, 0.333333333333333}};
2354
// Extract relevant coefficients
2355
const double coeff0_0 = coefficients0[dof][0];
2356
const double coeff0_1 = coefficients0[dof][1];
2357
const double coeff0_2 = coefficients0[dof][2];
2360
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2363
if (3 <= i && i <= 5)
2365
// Map degree of freedom to element degree of freedom
2366
const unsigned int dof = i - 3;
2368
// Generate scalings
2369
const double scalings_y_0 = 1;
2370
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2372
// Compute psitilde_a
2373
const double psitilde_a_0 = 1;
2374
const double psitilde_a_1 = x;
2376
// Compute psitilde_bs
2377
const double psitilde_bs_0_0 = 1;
2378
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2379
const double psitilde_bs_1_0 = 1;
2381
// Compute basisvalues
2382
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2383
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2384
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2386
// Table(s) of coefficients
2387
static const double coefficients0[3][3] = \
2388
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2389
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2390
{0.471404520791032, 0, 0.333333333333333}};
2392
// Extract relevant coefficients
2393
const double coeff0_0 = coefficients0[dof][0];
2394
const double coeff0_1 = coefficients0[dof][1];
2395
const double coeff0_2 = coefficients0[dof][2];
2398
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2403
/// Evaluate all basis functions at given point in cell
2404
void cahnhilliard2d_0_finite_element_1::evaluate_basis_all(double* values,
2405
const double* coordinates,
2406
const ufc::cell& c) const
2408
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2411
/// Evaluate order n derivatives of basis function i at given point in cell
2412
void cahnhilliard2d_0_finite_element_1::evaluate_basis_derivatives(unsigned int i,
2415
const double* coordinates,
2416
const ufc::cell& c) const
2418
// Extract vertex coordinates
2419
const double * const * element_coordinates = c.coordinates;
2421
// Compute Jacobian of affine map from reference cell
2422
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2423
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2424
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2425
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2427
// Compute determinant of Jacobian
2428
const double detJ = J_00*J_11 - J_01*J_10;
2430
// Compute inverse of Jacobian
2432
// Get coordinates and map to the reference (UFC) element
2433
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2434
element_coordinates[0][0]*element_coordinates[2][1] +\
2435
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2436
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2437
element_coordinates[1][0]*element_coordinates[0][1] -\
2438
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2440
// Map coordinates to the reference square
2441
if (std::abs(y - 1.0) < 1e-14)
2444
x = 2.0 *x/(1.0 - y) - 1.0;
2447
// Compute number of derivatives
2448
unsigned int num_derivatives = 1;
2450
for (unsigned int j = 0; j < n; j++)
2451
num_derivatives *= 2;
2454
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2455
unsigned int **combinations = new unsigned int *[num_derivatives];
2457
for (unsigned int j = 0; j < num_derivatives; j++)
2459
combinations[j] = new unsigned int [n];
2460
for (unsigned int k = 0; k < n; k++)
2461
combinations[j][k] = 0;
2464
// Generate combinations of derivatives
2465
for (unsigned int row = 1; row < num_derivatives; row++)
2467
for (unsigned int num = 0; num < row; num++)
2469
for (unsigned int col = n-1; col+1 > 0; col--)
2471
if (combinations[row][col] + 1 > 1)
2472
combinations[row][col] = 0;
2475
combinations[row][col] += 1;
2482
// Compute inverse of Jacobian
2483
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2485
// Declare transformation matrix
2486
// Declare pointer to two dimensional array and initialise
2487
double **transform = new double *[num_derivatives];
2489
for (unsigned int j = 0; j < num_derivatives; j++)
2491
transform[j] = new double [num_derivatives];
2492
for (unsigned int k = 0; k < num_derivatives; k++)
2493
transform[j][k] = 1;
2496
// Construct transformation matrix
2497
for (unsigned int row = 0; row < num_derivatives; row++)
2499
for (unsigned int col = 0; col < num_derivatives; col++)
2501
for (unsigned int k = 0; k < n; k++)
2502
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2507
for (unsigned int j = 0; j < 2*num_derivatives; j++)
2510
if (0 <= i && i <= 2)
2512
// Map degree of freedom to element degree of freedom
2513
const unsigned int dof = i;
2515
// Generate scalings
2516
const double scalings_y_0 = 1;
2517
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2519
// Compute psitilde_a
2520
const double psitilde_a_0 = 1;
2521
const double psitilde_a_1 = x;
2523
// Compute psitilde_bs
2524
const double psitilde_bs_0_0 = 1;
2525
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2526
const double psitilde_bs_1_0 = 1;
2528
// Compute basisvalues
2529
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2530
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2531
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2533
// Table(s) of coefficients
2534
static const double coefficients0[3][3] = \
2535
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2536
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2537
{0.471404520791032, 0, 0.333333333333333}};
2539
// Interesting (new) part
2540
// Tables of derivatives of the polynomial base (transpose)
2541
static const double dmats0[3][3] = \
2543
{4.89897948556636, 0, 0},
2546
static const double dmats1[3][3] = \
2548
{2.44948974278318, 0, 0},
2549
{4.24264068711928, 0, 0}};
2551
// Compute reference derivatives
2552
// Declare pointer to array of derivatives on FIAT element
2553
double *derivatives = new double [num_derivatives];
2555
// Declare coefficients
2556
double coeff0_0 = 0;
2557
double coeff0_1 = 0;
2558
double coeff0_2 = 0;
2560
// Declare new coefficients
2561
double new_coeff0_0 = 0;
2562
double new_coeff0_1 = 0;
2563
double new_coeff0_2 = 0;
2565
// Loop possible derivatives
2566
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2568
// Get values from coefficients array
2569
new_coeff0_0 = coefficients0[dof][0];
2570
new_coeff0_1 = coefficients0[dof][1];
2571
new_coeff0_2 = coefficients0[dof][2];
2573
// Loop derivative order
2574
for (unsigned int j = 0; j < n; j++)
2576
// Update old coefficients
2577
coeff0_0 = new_coeff0_0;
2578
coeff0_1 = new_coeff0_1;
2579
coeff0_2 = new_coeff0_2;
2581
if(combinations[deriv_num][j] == 0)
2583
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2584
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2585
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2587
if(combinations[deriv_num][j] == 1)
2589
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2590
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2591
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2595
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2596
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2599
// Transform derivatives back to physical element
2600
for (unsigned int row = 0; row < num_derivatives; row++)
2602
for (unsigned int col = 0; col < num_derivatives; col++)
2604
values[row] += transform[row][col]*derivatives[col];
2607
// Delete pointer to array of derivatives on FIAT element
2608
delete [] derivatives;
2610
// Delete pointer to array of combinations of derivatives and transform
2611
for (unsigned int row = 0; row < num_derivatives; row++)
2613
delete [] combinations[row];
2614
delete [] transform[row];
2617
delete [] combinations;
2618
delete [] transform;
2621
if (3 <= i && i <= 5)
2623
// Map degree of freedom to element degree of freedom
2624
const unsigned int dof = i - 3;
2626
// Generate scalings
2627
const double scalings_y_0 = 1;
2628
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2630
// Compute psitilde_a
2631
const double psitilde_a_0 = 1;
2632
const double psitilde_a_1 = x;
2634
// Compute psitilde_bs
2635
const double psitilde_bs_0_0 = 1;
2636
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2637
const double psitilde_bs_1_0 = 1;
2639
// Compute basisvalues
2640
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2641
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2642
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2644
// Table(s) of coefficients
2645
static const double coefficients0[3][3] = \
2646
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2647
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2648
{0.471404520791032, 0, 0.333333333333333}};
2650
// Interesting (new) part
2651
// Tables of derivatives of the polynomial base (transpose)
2652
static const double dmats0[3][3] = \
2654
{4.89897948556636, 0, 0},
2657
static const double dmats1[3][3] = \
2659
{2.44948974278318, 0, 0},
2660
{4.24264068711928, 0, 0}};
2662
// Compute reference derivatives
2663
// Declare pointer to array of derivatives on FIAT element
2664
double *derivatives = new double [num_derivatives];
2666
// Declare coefficients
2667
double coeff0_0 = 0;
2668
double coeff0_1 = 0;
2669
double coeff0_2 = 0;
2671
// Declare new coefficients
2672
double new_coeff0_0 = 0;
2673
double new_coeff0_1 = 0;
2674
double new_coeff0_2 = 0;
2676
// Loop possible derivatives
2677
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2679
// Get values from coefficients array
2680
new_coeff0_0 = coefficients0[dof][0];
2681
new_coeff0_1 = coefficients0[dof][1];
2682
new_coeff0_2 = coefficients0[dof][2];
2684
// Loop derivative order
2685
for (unsigned int j = 0; j < n; j++)
2687
// Update old coefficients
2688
coeff0_0 = new_coeff0_0;
2689
coeff0_1 = new_coeff0_1;
2690
coeff0_2 = new_coeff0_2;
2692
if(combinations[deriv_num][j] == 0)
2694
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2695
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2696
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2698
if(combinations[deriv_num][j] == 1)
2700
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2701
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2702
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2706
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2707
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2710
// Transform derivatives back to physical element
2711
for (unsigned int row = 0; row < num_derivatives; row++)
2713
for (unsigned int col = 0; col < num_derivatives; col++)
2715
values[num_derivatives + row] += transform[row][col]*derivatives[col];
2718
// Delete pointer to array of derivatives on FIAT element
2719
delete [] derivatives;
2721
// Delete pointer to array of combinations of derivatives and transform
2722
for (unsigned int row = 0; row < num_derivatives; row++)
2724
delete [] combinations[row];
2725
delete [] transform[row];
2728
delete [] combinations;
2729
delete [] transform;
2734
/// Evaluate order n derivatives of all basis functions at given point in cell
2735
void cahnhilliard2d_0_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
2737
const double* coordinates,
2738
const ufc::cell& c) const
2740
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2743
/// Evaluate linear functional for dof i on the function f
2744
double cahnhilliard2d_0_finite_element_1::evaluate_dof(unsigned int i,
2745
const ufc::function& f,
2746
const ufc::cell& c) const
2748
// The reference points, direction and weights:
2749
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
2750
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
2751
static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
2753
const double * const * x = c.coordinates;
2754
double result = 0.0;
2755
// Iterate over the points:
2756
// Evaluate basis functions for affine mapping
2757
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2758
const double w1 = X[i][0][0];
2759
const double w2 = X[i][0][1];
2761
// Compute affine mapping y = F(X)
2763
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2764
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2766
// Evaluate function at physical points
2768
f.evaluate(values, y, c);
2770
// Map function values using appropriate mapping
2771
// Affine map: Do nothing
2773
// Note that we do not map the weights (yet).
2775
// Take directional components
2776
for(int k = 0; k < 2; k++)
2777
result += values[k]*D[i][0][k];
2778
// Multiply by weights
2784
/// Evaluate linear functionals for all dofs on the function f
2785
void cahnhilliard2d_0_finite_element_1::evaluate_dofs(double* values,
2786
const ufc::function& f,
2787
const ufc::cell& c) const
2789
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2792
/// Interpolate vertex values from dof values
2793
void cahnhilliard2d_0_finite_element_1::interpolate_vertex_values(double* vertex_values,
2794
const double* dof_values,
2795
const ufc::cell& c) const
2797
// Evaluate at vertices and use affine mapping
2798
vertex_values[0] = dof_values[0];
2799
vertex_values[2] = dof_values[1];
2800
vertex_values[4] = dof_values[2];
2801
// Evaluate at vertices and use affine mapping
2802
vertex_values[1] = dof_values[3];
2803
vertex_values[3] = dof_values[4];
2804
vertex_values[5] = dof_values[5];
2807
/// Return the number of sub elements (for a mixed element)
2808
unsigned int cahnhilliard2d_0_finite_element_1::num_sub_elements() const
2813
/// Create a new finite element for sub element i (for a mixed element)
2814
ufc::finite_element* cahnhilliard2d_0_finite_element_1::create_sub_element(unsigned int i) const
2819
return new cahnhilliard2d_0_finite_element_1_0();
2822
return new cahnhilliard2d_0_finite_element_1_1();
2830
cahnhilliard2d_0_finite_element_2_0::cahnhilliard2d_0_finite_element_2_0() : ufc::finite_element()
2836
cahnhilliard2d_0_finite_element_2_0::~cahnhilliard2d_0_finite_element_2_0()
2841
/// Return a string identifying the finite element
2842
const char* cahnhilliard2d_0_finite_element_2_0::signature() const
2844
return "FiniteElement('Lagrange', 'triangle', 1)";
2847
/// Return the cell shape
2848
ufc::shape cahnhilliard2d_0_finite_element_2_0::cell_shape() const
2850
return ufc::triangle;
2853
/// Return the dimension of the finite element function space
2854
unsigned int cahnhilliard2d_0_finite_element_2_0::space_dimension() const
2859
/// Return the rank of the value space
2860
unsigned int cahnhilliard2d_0_finite_element_2_0::value_rank() const
2865
/// Return the dimension of the value space for axis i
2866
unsigned int cahnhilliard2d_0_finite_element_2_0::value_dimension(unsigned int i) const
2871
/// Evaluate basis function i at given point in cell
2872
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis(unsigned int i,
2874
const double* coordinates,
2875
const ufc::cell& c) const
2877
// Extract vertex coordinates
2878
const double * const * element_coordinates = c.coordinates;
2880
// Compute Jacobian of affine map from reference cell
2881
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2882
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2883
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2884
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2886
// Compute determinant of Jacobian
2887
const double detJ = J_00*J_11 - J_01*J_10;
2889
// Compute inverse of Jacobian
2891
// Get coordinates and map to the reference (UFC) element
2892
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2893
element_coordinates[0][0]*element_coordinates[2][1] +\
2894
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2895
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2896
element_coordinates[1][0]*element_coordinates[0][1] -\
2897
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2899
// Map coordinates to the reference square
2900
if (std::abs(y - 1.0) < 1e-14)
2903
x = 2.0 *x/(1.0 - y) - 1.0;
2909
// Map degree of freedom to element degree of freedom
2910
const unsigned int dof = i;
2912
// Generate scalings
2913
const double scalings_y_0 = 1;
2914
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2916
// Compute psitilde_a
2917
const double psitilde_a_0 = 1;
2918
const double psitilde_a_1 = x;
2920
// Compute psitilde_bs
2921
const double psitilde_bs_0_0 = 1;
2922
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2923
const double psitilde_bs_1_0 = 1;
2925
// Compute basisvalues
2926
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2927
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2928
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2930
// Table(s) of coefficients
2931
static const double coefficients0[3][3] = \
2932
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2933
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2934
{0.471404520791032, 0, 0.333333333333333}};
2936
// Extract relevant coefficients
2937
const double coeff0_0 = coefficients0[dof][0];
2938
const double coeff0_1 = coefficients0[dof][1];
2939
const double coeff0_2 = coefficients0[dof][2];
2942
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2945
/// Evaluate all basis functions at given point in cell
2946
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis_all(double* values,
2947
const double* coordinates,
2948
const ufc::cell& c) const
2950
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2953
/// Evaluate order n derivatives of basis function i at given point in cell
2954
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis_derivatives(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-14)
2986
x = 2.0 *x/(1.0 - y) - 1.0;
2989
// Compute number of derivatives
2990
unsigned int num_derivatives = 1;
2992
for (unsigned int j = 0; j < n; j++)
2993
num_derivatives *= 2;
2996
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2997
unsigned int **combinations = new unsigned int *[num_derivatives];
2999
for (unsigned int j = 0; j < num_derivatives; j++)
3001
combinations[j] = new unsigned int [n];
3002
for (unsigned int k = 0; k < n; k++)
3003
combinations[j][k] = 0;
3006
// Generate combinations of derivatives
3007
for (unsigned int row = 1; row < num_derivatives; row++)
3009
for (unsigned int num = 0; num < row; num++)
3011
for (unsigned int col = n-1; col+1 > 0; col--)
3013
if (combinations[row][col] + 1 > 1)
3014
combinations[row][col] = 0;
3017
combinations[row][col] += 1;
3024
// Compute inverse of Jacobian
3025
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3027
// Declare transformation matrix
3028
// Declare pointer to two dimensional array and initialise
3029
double **transform = new double *[num_derivatives];
3031
for (unsigned int j = 0; j < num_derivatives; j++)
3033
transform[j] = new double [num_derivatives];
3034
for (unsigned int k = 0; k < num_derivatives; k++)
3035
transform[j][k] = 1;
3038
// Construct transformation matrix
3039
for (unsigned int row = 0; row < num_derivatives; row++)
3041
for (unsigned int col = 0; col < num_derivatives; col++)
3043
for (unsigned int k = 0; k < n; k++)
3044
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3049
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3052
// Map degree of freedom to element degree of freedom
3053
const unsigned int dof = i;
3055
// Generate scalings
3056
const double scalings_y_0 = 1;
3057
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3059
// Compute psitilde_a
3060
const double psitilde_a_0 = 1;
3061
const double psitilde_a_1 = x;
3063
// Compute psitilde_bs
3064
const double psitilde_bs_0_0 = 1;
3065
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3066
const double psitilde_bs_1_0 = 1;
3068
// Compute basisvalues
3069
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3070
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3071
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3073
// Table(s) of coefficients
3074
static const double coefficients0[3][3] = \
3075
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3076
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3077
{0.471404520791032, 0, 0.333333333333333}};
3079
// Interesting (new) part
3080
// Tables of derivatives of the polynomial base (transpose)
3081
static const double dmats0[3][3] = \
3083
{4.89897948556636, 0, 0},
3086
static const double dmats1[3][3] = \
3088
{2.44948974278318, 0, 0},
3089
{4.24264068711928, 0, 0}};
3091
// Compute reference derivatives
3092
// Declare pointer to array of derivatives on FIAT element
3093
double *derivatives = new double [num_derivatives];
3095
// Declare coefficients
3096
double coeff0_0 = 0;
3097
double coeff0_1 = 0;
3098
double coeff0_2 = 0;
3100
// Declare new coefficients
3101
double new_coeff0_0 = 0;
3102
double new_coeff0_1 = 0;
3103
double new_coeff0_2 = 0;
3105
// Loop possible derivatives
3106
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3108
// Get values from coefficients array
3109
new_coeff0_0 = coefficients0[dof][0];
3110
new_coeff0_1 = coefficients0[dof][1];
3111
new_coeff0_2 = coefficients0[dof][2];
3113
// Loop derivative order
3114
for (unsigned int j = 0; j < n; j++)
3116
// Update old coefficients
3117
coeff0_0 = new_coeff0_0;
3118
coeff0_1 = new_coeff0_1;
3119
coeff0_2 = new_coeff0_2;
3121
if(combinations[deriv_num][j] == 0)
3123
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3124
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3125
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3127
if(combinations[deriv_num][j] == 1)
3129
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3130
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3131
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3135
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3136
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3139
// Transform derivatives back to physical element
3140
for (unsigned int row = 0; row < num_derivatives; row++)
3142
for (unsigned int col = 0; col < num_derivatives; col++)
3144
values[row] += transform[row][col]*derivatives[col];
3147
// Delete pointer to array of derivatives on FIAT element
3148
delete [] derivatives;
3150
// Delete pointer to array of combinations of derivatives and transform
3151
for (unsigned int row = 0; row < num_derivatives; row++)
3153
delete [] combinations[row];
3154
delete [] transform[row];
3157
delete [] combinations;
3158
delete [] transform;
3161
/// Evaluate order n derivatives of all basis functions at given point in cell
3162
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
3164
const double* coordinates,
3165
const ufc::cell& c) const
3167
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3170
/// Evaluate linear functional for dof i on the function f
3171
double cahnhilliard2d_0_finite_element_2_0::evaluate_dof(unsigned int i,
3172
const ufc::function& f,
3173
const ufc::cell& c) const
3175
// The reference points, direction and weights:
3176
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3177
static const double W[3][1] = {{1}, {1}, {1}};
3178
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3180
const double * const * x = c.coordinates;
3181
double result = 0.0;
3182
// Iterate over the points:
3183
// Evaluate basis functions for affine mapping
3184
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3185
const double w1 = X[i][0][0];
3186
const double w2 = X[i][0][1];
3188
// Compute affine mapping y = F(X)
3190
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3191
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3193
// Evaluate function at physical points
3195
f.evaluate(values, y, c);
3197
// Map function values using appropriate mapping
3198
// Affine map: Do nothing
3200
// Note that we do not map the weights (yet).
3202
// Take directional components
3203
for(int k = 0; k < 1; k++)
3204
result += values[k]*D[i][0][k];
3205
// Multiply by weights
3211
/// Evaluate linear functionals for all dofs on the function f
3212
void cahnhilliard2d_0_finite_element_2_0::evaluate_dofs(double* values,
3213
const ufc::function& f,
3214
const ufc::cell& c) const
3216
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3219
/// Interpolate vertex values from dof values
3220
void cahnhilliard2d_0_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
3221
const double* dof_values,
3222
const ufc::cell& c) const
3224
// Evaluate at vertices and use affine mapping
3225
vertex_values[0] = dof_values[0];
3226
vertex_values[1] = dof_values[1];
3227
vertex_values[2] = dof_values[2];
3230
/// Return the number of sub elements (for a mixed element)
3231
unsigned int cahnhilliard2d_0_finite_element_2_0::num_sub_elements() const
3236
/// Create a new finite element for sub element i (for a mixed element)
3237
ufc::finite_element* cahnhilliard2d_0_finite_element_2_0::create_sub_element(unsigned int i) const
3239
return new cahnhilliard2d_0_finite_element_2_0();
3244
cahnhilliard2d_0_finite_element_2_1::cahnhilliard2d_0_finite_element_2_1() : ufc::finite_element()
3250
cahnhilliard2d_0_finite_element_2_1::~cahnhilliard2d_0_finite_element_2_1()
3255
/// Return a string identifying the finite element
3256
const char* cahnhilliard2d_0_finite_element_2_1::signature() const
3258
return "FiniteElement('Lagrange', 'triangle', 1)";
3261
/// Return the cell shape
3262
ufc::shape cahnhilliard2d_0_finite_element_2_1::cell_shape() const
3264
return ufc::triangle;
3267
/// Return the dimension of the finite element function space
3268
unsigned int cahnhilliard2d_0_finite_element_2_1::space_dimension() const
3273
/// Return the rank of the value space
3274
unsigned int cahnhilliard2d_0_finite_element_2_1::value_rank() const
3279
/// Return the dimension of the value space for axis i
3280
unsigned int cahnhilliard2d_0_finite_element_2_1::value_dimension(unsigned int i) const
3285
/// Evaluate basis function i at given point in cell
3286
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis(unsigned int i,
3288
const double* coordinates,
3289
const ufc::cell& c) const
3291
// Extract vertex coordinates
3292
const double * const * element_coordinates = c.coordinates;
3294
// Compute Jacobian of affine map from reference cell
3295
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3296
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3297
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3298
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3300
// Compute determinant of Jacobian
3301
const double detJ = J_00*J_11 - J_01*J_10;
3303
// Compute inverse of Jacobian
3305
// Get coordinates and map to the reference (UFC) element
3306
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3307
element_coordinates[0][0]*element_coordinates[2][1] +\
3308
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3309
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3310
element_coordinates[1][0]*element_coordinates[0][1] -\
3311
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3313
// Map coordinates to the reference square
3314
if (std::abs(y - 1.0) < 1e-14)
3317
x = 2.0 *x/(1.0 - y) - 1.0;
3323
// Map degree of freedom to element degree of freedom
3324
const unsigned int dof = i;
3326
// Generate scalings
3327
const double scalings_y_0 = 1;
3328
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3330
// Compute psitilde_a
3331
const double psitilde_a_0 = 1;
3332
const double psitilde_a_1 = x;
3334
// Compute psitilde_bs
3335
const double psitilde_bs_0_0 = 1;
3336
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3337
const double psitilde_bs_1_0 = 1;
3339
// Compute basisvalues
3340
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3341
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3342
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3344
// Table(s) of coefficients
3345
static const double coefficients0[3][3] = \
3346
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3347
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3348
{0.471404520791032, 0, 0.333333333333333}};
3350
// Extract relevant coefficients
3351
const double coeff0_0 = coefficients0[dof][0];
3352
const double coeff0_1 = coefficients0[dof][1];
3353
const double coeff0_2 = coefficients0[dof][2];
3356
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3359
/// Evaluate all basis functions at given point in cell
3360
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis_all(double* values,
3361
const double* coordinates,
3362
const ufc::cell& c) const
3364
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3367
/// Evaluate order n derivatives of basis function i at given point in cell
3368
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
3371
const double* coordinates,
3372
const ufc::cell& c) const
3374
// Extract vertex coordinates
3375
const double * const * element_coordinates = c.coordinates;
3377
// Compute Jacobian of affine map from reference cell
3378
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3379
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3380
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3381
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3383
// Compute determinant of Jacobian
3384
const double detJ = J_00*J_11 - J_01*J_10;
3386
// Compute inverse of Jacobian
3388
// Get coordinates and map to the reference (UFC) element
3389
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3390
element_coordinates[0][0]*element_coordinates[2][1] +\
3391
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3392
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3393
element_coordinates[1][0]*element_coordinates[0][1] -\
3394
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3396
// Map coordinates to the reference square
3397
if (std::abs(y - 1.0) < 1e-14)
3400
x = 2.0 *x/(1.0 - y) - 1.0;
3403
// Compute number of derivatives
3404
unsigned int num_derivatives = 1;
3406
for (unsigned int j = 0; j < n; j++)
3407
num_derivatives *= 2;
3410
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3411
unsigned int **combinations = new unsigned int *[num_derivatives];
3413
for (unsigned int j = 0; j < num_derivatives; j++)
3415
combinations[j] = new unsigned int [n];
3416
for (unsigned int k = 0; k < n; k++)
3417
combinations[j][k] = 0;
3420
// Generate combinations of derivatives
3421
for (unsigned int row = 1; row < num_derivatives; row++)
3423
for (unsigned int num = 0; num < row; num++)
3425
for (unsigned int col = n-1; col+1 > 0; col--)
3427
if (combinations[row][col] + 1 > 1)
3428
combinations[row][col] = 0;
3431
combinations[row][col] += 1;
3438
// Compute inverse of Jacobian
3439
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3441
// Declare transformation matrix
3442
// Declare pointer to two dimensional array and initialise
3443
double **transform = new double *[num_derivatives];
3445
for (unsigned int j = 0; j < num_derivatives; j++)
3447
transform[j] = new double [num_derivatives];
3448
for (unsigned int k = 0; k < num_derivatives; k++)
3449
transform[j][k] = 1;
3452
// Construct transformation matrix
3453
for (unsigned int row = 0; row < num_derivatives; row++)
3455
for (unsigned int col = 0; col < num_derivatives; col++)
3457
for (unsigned int k = 0; k < n; k++)
3458
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3463
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3466
// Map degree of freedom to element degree of freedom
3467
const unsigned int dof = i;
3469
// Generate scalings
3470
const double scalings_y_0 = 1;
3471
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3473
// Compute psitilde_a
3474
const double psitilde_a_0 = 1;
3475
const double psitilde_a_1 = x;
3477
// Compute psitilde_bs
3478
const double psitilde_bs_0_0 = 1;
3479
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3480
const double psitilde_bs_1_0 = 1;
3482
// Compute basisvalues
3483
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3484
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3485
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3487
// Table(s) of coefficients
3488
static const double coefficients0[3][3] = \
3489
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3490
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3491
{0.471404520791032, 0, 0.333333333333333}};
3493
// Interesting (new) part
3494
// Tables of derivatives of the polynomial base (transpose)
3495
static const double dmats0[3][3] = \
3497
{4.89897948556636, 0, 0},
3500
static const double dmats1[3][3] = \
3502
{2.44948974278318, 0, 0},
3503
{4.24264068711928, 0, 0}};
3505
// Compute reference derivatives
3506
// Declare pointer to array of derivatives on FIAT element
3507
double *derivatives = new double [num_derivatives];
3509
// Declare coefficients
3510
double coeff0_0 = 0;
3511
double coeff0_1 = 0;
3512
double coeff0_2 = 0;
3514
// Declare new coefficients
3515
double new_coeff0_0 = 0;
3516
double new_coeff0_1 = 0;
3517
double new_coeff0_2 = 0;
3519
// Loop possible derivatives
3520
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3522
// Get values from coefficients array
3523
new_coeff0_0 = coefficients0[dof][0];
3524
new_coeff0_1 = coefficients0[dof][1];
3525
new_coeff0_2 = coefficients0[dof][2];
3527
// Loop derivative order
3528
for (unsigned int j = 0; j < n; j++)
3530
// Update old coefficients
3531
coeff0_0 = new_coeff0_0;
3532
coeff0_1 = new_coeff0_1;
3533
coeff0_2 = new_coeff0_2;
3535
if(combinations[deriv_num][j] == 0)
3537
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3538
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3539
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3541
if(combinations[deriv_num][j] == 1)
3543
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3544
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3545
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3549
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3550
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3553
// Transform derivatives back to physical element
3554
for (unsigned int row = 0; row < num_derivatives; row++)
3556
for (unsigned int col = 0; col < num_derivatives; col++)
3558
values[row] += transform[row][col]*derivatives[col];
3561
// Delete pointer to array of derivatives on FIAT element
3562
delete [] derivatives;
3564
// Delete pointer to array of combinations of derivatives and transform
3565
for (unsigned int row = 0; row < num_derivatives; row++)
3567
delete [] combinations[row];
3568
delete [] transform[row];
3571
delete [] combinations;
3572
delete [] transform;
3575
/// Evaluate order n derivatives of all basis functions at given point in cell
3576
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
3578
const double* coordinates,
3579
const ufc::cell& c) const
3581
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3584
/// Evaluate linear functional for dof i on the function f
3585
double cahnhilliard2d_0_finite_element_2_1::evaluate_dof(unsigned int i,
3586
const ufc::function& f,
3587
const ufc::cell& c) const
3589
// The reference points, direction and weights:
3590
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3591
static const double W[3][1] = {{1}, {1}, {1}};
3592
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3594
const double * const * x = c.coordinates;
3595
double result = 0.0;
3596
// Iterate over the points:
3597
// Evaluate basis functions for affine mapping
3598
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3599
const double w1 = X[i][0][0];
3600
const double w2 = X[i][0][1];
3602
// Compute affine mapping y = F(X)
3604
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3605
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3607
// Evaluate function at physical points
3609
f.evaluate(values, y, c);
3611
// Map function values using appropriate mapping
3612
// Affine map: Do nothing
3614
// Note that we do not map the weights (yet).
3616
// Take directional components
3617
for(int k = 0; k < 1; k++)
3618
result += values[k]*D[i][0][k];
3619
// Multiply by weights
3625
/// Evaluate linear functionals for all dofs on the function f
3626
void cahnhilliard2d_0_finite_element_2_1::evaluate_dofs(double* values,
3627
const ufc::function& f,
3628
const ufc::cell& c) const
3630
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3633
/// Interpolate vertex values from dof values
3634
void cahnhilliard2d_0_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
3635
const double* dof_values,
3636
const ufc::cell& c) const
3638
// Evaluate at vertices and use affine mapping
3639
vertex_values[0] = dof_values[0];
3640
vertex_values[1] = dof_values[1];
3641
vertex_values[2] = dof_values[2];
3644
/// Return the number of sub elements (for a mixed element)
3645
unsigned int cahnhilliard2d_0_finite_element_2_1::num_sub_elements() const
3650
/// Create a new finite element for sub element i (for a mixed element)
3651
ufc::finite_element* cahnhilliard2d_0_finite_element_2_1::create_sub_element(unsigned int i) const
3653
return new cahnhilliard2d_0_finite_element_2_1();
3658
cahnhilliard2d_0_finite_element_2::cahnhilliard2d_0_finite_element_2() : ufc::finite_element()
3664
cahnhilliard2d_0_finite_element_2::~cahnhilliard2d_0_finite_element_2()
3669
/// Return a string identifying the finite element
3670
const char* cahnhilliard2d_0_finite_element_2::signature() const
3672
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
3675
/// Return the cell shape
3676
ufc::shape cahnhilliard2d_0_finite_element_2::cell_shape() const
3678
return ufc::triangle;
3681
/// Return the dimension of the finite element function space
3682
unsigned int cahnhilliard2d_0_finite_element_2::space_dimension() const
3687
/// Return the rank of the value space
3688
unsigned int cahnhilliard2d_0_finite_element_2::value_rank() const
3693
/// Return the dimension of the value space for axis i
3694
unsigned int cahnhilliard2d_0_finite_element_2::value_dimension(unsigned int i) const
3699
/// Evaluate basis function i at given point in cell
3700
void cahnhilliard2d_0_finite_element_2::evaluate_basis(unsigned int i,
3702
const double* coordinates,
3703
const ufc::cell& c) const
3705
// Extract vertex coordinates
3706
const double * const * element_coordinates = c.coordinates;
3708
// Compute Jacobian of affine map from reference cell
3709
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3710
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3711
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3712
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3714
// Compute determinant of Jacobian
3715
const double detJ = J_00*J_11 - J_01*J_10;
3717
// Compute inverse of Jacobian
3719
// Get coordinates and map to the reference (UFC) element
3720
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3721
element_coordinates[0][0]*element_coordinates[2][1] +\
3722
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3723
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3724
element_coordinates[1][0]*element_coordinates[0][1] -\
3725
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3727
// Map coordinates to the reference square
3728
if (std::abs(y - 1.0) < 1e-14)
3731
x = 2.0 *x/(1.0 - y) - 1.0;
3738
if (0 <= i && i <= 2)
3740
// Map degree of freedom to element degree of freedom
3741
const unsigned int dof = i;
3743
// Generate scalings
3744
const double scalings_y_0 = 1;
3745
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3747
// Compute psitilde_a
3748
const double psitilde_a_0 = 1;
3749
const double psitilde_a_1 = x;
3751
// Compute psitilde_bs
3752
const double psitilde_bs_0_0 = 1;
3753
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3754
const double psitilde_bs_1_0 = 1;
3756
// Compute basisvalues
3757
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3758
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3759
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3761
// Table(s) of coefficients
3762
static const double coefficients0[3][3] = \
3763
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3764
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3765
{0.471404520791032, 0, 0.333333333333333}};
3767
// Extract relevant coefficients
3768
const double coeff0_0 = coefficients0[dof][0];
3769
const double coeff0_1 = coefficients0[dof][1];
3770
const double coeff0_2 = coefficients0[dof][2];
3773
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3776
if (3 <= i && i <= 5)
3778
// Map degree of freedom to element degree of freedom
3779
const unsigned int dof = i - 3;
3781
// Generate scalings
3782
const double scalings_y_0 = 1;
3783
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3785
// Compute psitilde_a
3786
const double psitilde_a_0 = 1;
3787
const double psitilde_a_1 = x;
3789
// Compute psitilde_bs
3790
const double psitilde_bs_0_0 = 1;
3791
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3792
const double psitilde_bs_1_0 = 1;
3794
// Compute basisvalues
3795
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3796
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3797
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3799
// Table(s) of coefficients
3800
static const double coefficients0[3][3] = \
3801
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3802
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3803
{0.471404520791032, 0, 0.333333333333333}};
3805
// Extract relevant coefficients
3806
const double coeff0_0 = coefficients0[dof][0];
3807
const double coeff0_1 = coefficients0[dof][1];
3808
const double coeff0_2 = coefficients0[dof][2];
3811
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3816
/// Evaluate all basis functions at given point in cell
3817
void cahnhilliard2d_0_finite_element_2::evaluate_basis_all(double* values,
3818
const double* coordinates,
3819
const ufc::cell& c) const
3821
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3824
/// Evaluate order n derivatives of basis function i at given point in cell
3825
void cahnhilliard2d_0_finite_element_2::evaluate_basis_derivatives(unsigned int i,
3828
const double* coordinates,
3829
const ufc::cell& c) const
3831
// Extract vertex coordinates
3832
const double * const * element_coordinates = c.coordinates;
3834
// Compute Jacobian of affine map from reference cell
3835
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3836
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3837
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3838
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3840
// Compute determinant of Jacobian
3841
const double detJ = J_00*J_11 - J_01*J_10;
3843
// Compute inverse of Jacobian
3845
// Get coordinates and map to the reference (UFC) element
3846
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3847
element_coordinates[0][0]*element_coordinates[2][1] +\
3848
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3849
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3850
element_coordinates[1][0]*element_coordinates[0][1] -\
3851
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3853
// Map coordinates to the reference square
3854
if (std::abs(y - 1.0) < 1e-14)
3857
x = 2.0 *x/(1.0 - y) - 1.0;
3860
// Compute number of derivatives
3861
unsigned int num_derivatives = 1;
3863
for (unsigned int j = 0; j < n; j++)
3864
num_derivatives *= 2;
3867
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3868
unsigned int **combinations = new unsigned int *[num_derivatives];
3870
for (unsigned int j = 0; j < num_derivatives; j++)
3872
combinations[j] = new unsigned int [n];
3873
for (unsigned int k = 0; k < n; k++)
3874
combinations[j][k] = 0;
3877
// Generate combinations of derivatives
3878
for (unsigned int row = 1; row < num_derivatives; row++)
3880
for (unsigned int num = 0; num < row; num++)
3882
for (unsigned int col = n-1; col+1 > 0; col--)
3884
if (combinations[row][col] + 1 > 1)
3885
combinations[row][col] = 0;
3888
combinations[row][col] += 1;
3895
// Compute inverse of Jacobian
3896
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3898
// Declare transformation matrix
3899
// Declare pointer to two dimensional array and initialise
3900
double **transform = new double *[num_derivatives];
3902
for (unsigned int j = 0; j < num_derivatives; j++)
3904
transform[j] = new double [num_derivatives];
3905
for (unsigned int k = 0; k < num_derivatives; k++)
3906
transform[j][k] = 1;
3909
// Construct transformation matrix
3910
for (unsigned int row = 0; row < num_derivatives; row++)
3912
for (unsigned int col = 0; col < num_derivatives; col++)
3914
for (unsigned int k = 0; k < n; k++)
3915
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3920
for (unsigned int j = 0; j < 2*num_derivatives; j++)
3923
if (0 <= i && i <= 2)
3925
// Map degree of freedom to element degree of freedom
3926
const unsigned int dof = i;
3928
// Generate scalings
3929
const double scalings_y_0 = 1;
3930
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3932
// Compute psitilde_a
3933
const double psitilde_a_0 = 1;
3934
const double psitilde_a_1 = x;
3936
// Compute psitilde_bs
3937
const double psitilde_bs_0_0 = 1;
3938
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3939
const double psitilde_bs_1_0 = 1;
3941
// Compute basisvalues
3942
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3943
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3944
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3946
// Table(s) of coefficients
3947
static const double coefficients0[3][3] = \
3948
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
3949
{0.471404520791032, 0.288675134594813, -0.166666666666667},
3950
{0.471404520791032, 0, 0.333333333333333}};
3952
// Interesting (new) part
3953
// Tables of derivatives of the polynomial base (transpose)
3954
static const double dmats0[3][3] = \
3956
{4.89897948556636, 0, 0},
3959
static const double dmats1[3][3] = \
3961
{2.44948974278318, 0, 0},
3962
{4.24264068711928, 0, 0}};
3964
// Compute reference derivatives
3965
// Declare pointer to array of derivatives on FIAT element
3966
double *derivatives = new double [num_derivatives];
3968
// Declare coefficients
3969
double coeff0_0 = 0;
3970
double coeff0_1 = 0;
3971
double coeff0_2 = 0;
3973
// Declare new coefficients
3974
double new_coeff0_0 = 0;
3975
double new_coeff0_1 = 0;
3976
double new_coeff0_2 = 0;
3978
// Loop possible derivatives
3979
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3981
// Get values from coefficients array
3982
new_coeff0_0 = coefficients0[dof][0];
3983
new_coeff0_1 = coefficients0[dof][1];
3984
new_coeff0_2 = coefficients0[dof][2];
3986
// Loop derivative order
3987
for (unsigned int j = 0; j < n; j++)
3989
// Update old coefficients
3990
coeff0_0 = new_coeff0_0;
3991
coeff0_1 = new_coeff0_1;
3992
coeff0_2 = new_coeff0_2;
3994
if(combinations[deriv_num][j] == 0)
3996
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3997
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3998
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
4000
if(combinations[deriv_num][j] == 1)
4002
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
4003
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
4004
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
4008
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4009
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
4012
// Transform derivatives back to physical element
4013
for (unsigned int row = 0; row < num_derivatives; row++)
4015
for (unsigned int col = 0; col < num_derivatives; col++)
4017
values[row] += transform[row][col]*derivatives[col];
4020
// Delete pointer to array of derivatives on FIAT element
4021
delete [] derivatives;
4023
// Delete pointer to array of combinations of derivatives and transform
4024
for (unsigned int row = 0; row < num_derivatives; row++)
4026
delete [] combinations[row];
4027
delete [] transform[row];
4030
delete [] combinations;
4031
delete [] transform;
4034
if (3 <= i && i <= 5)
4036
// Map degree of freedom to element degree of freedom
4037
const unsigned int dof = i - 3;
4039
// Generate scalings
4040
const double scalings_y_0 = 1;
4041
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4043
// Compute psitilde_a
4044
const double psitilde_a_0 = 1;
4045
const double psitilde_a_1 = x;
4047
// Compute psitilde_bs
4048
const double psitilde_bs_0_0 = 1;
4049
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4050
const double psitilde_bs_1_0 = 1;
4052
// Compute basisvalues
4053
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4054
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4055
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4057
// Table(s) of coefficients
4058
static const double coefficients0[3][3] = \
4059
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
4060
{0.471404520791032, 0.288675134594813, -0.166666666666667},
4061
{0.471404520791032, 0, 0.333333333333333}};
4063
// Interesting (new) part
4064
// Tables of derivatives of the polynomial base (transpose)
4065
static const double dmats0[3][3] = \
4067
{4.89897948556636, 0, 0},
4070
static const double dmats1[3][3] = \
4072
{2.44948974278318, 0, 0},
4073
{4.24264068711928, 0, 0}};
4075
// Compute reference derivatives
4076
// Declare pointer to array of derivatives on FIAT element
4077
double *derivatives = new double [num_derivatives];
4079
// Declare coefficients
4080
double coeff0_0 = 0;
4081
double coeff0_1 = 0;
4082
double coeff0_2 = 0;
4084
// Declare new coefficients
4085
double new_coeff0_0 = 0;
4086
double new_coeff0_1 = 0;
4087
double new_coeff0_2 = 0;
4089
// Loop possible derivatives
4090
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4092
// Get values from coefficients array
4093
new_coeff0_0 = coefficients0[dof][0];
4094
new_coeff0_1 = coefficients0[dof][1];
4095
new_coeff0_2 = coefficients0[dof][2];
4097
// Loop derivative order
4098
for (unsigned int j = 0; j < n; j++)
4100
// Update old coefficients
4101
coeff0_0 = new_coeff0_0;
4102
coeff0_1 = new_coeff0_1;
4103
coeff0_2 = new_coeff0_2;
4105
if(combinations[deriv_num][j] == 0)
4107
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
4108
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
4109
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
4111
if(combinations[deriv_num][j] == 1)
4113
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
4114
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
4115
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
4119
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4120
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
4123
// Transform derivatives back to physical element
4124
for (unsigned int row = 0; row < num_derivatives; row++)
4126
for (unsigned int col = 0; col < num_derivatives; col++)
4128
values[num_derivatives + row] += transform[row][col]*derivatives[col];
4131
// Delete pointer to array of derivatives on FIAT element
4132
delete [] derivatives;
4134
// Delete pointer to array of combinations of derivatives and transform
4135
for (unsigned int row = 0; row < num_derivatives; row++)
4137
delete [] combinations[row];
4138
delete [] transform[row];
4141
delete [] combinations;
4142
delete [] transform;
4147
/// Evaluate order n derivatives of all basis functions at given point in cell
4148
void cahnhilliard2d_0_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
4150
const double* coordinates,
4151
const ufc::cell& c) const
4153
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4156
/// Evaluate linear functional for dof i on the function f
4157
double cahnhilliard2d_0_finite_element_2::evaluate_dof(unsigned int i,
4158
const ufc::function& f,
4159
const ufc::cell& c) const
4161
// The reference points, direction and weights:
4162
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
4163
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
4164
static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
4166
const double * const * x = c.coordinates;
4167
double result = 0.0;
4168
// Iterate over the points:
4169
// Evaluate basis functions for affine mapping
4170
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4171
const double w1 = X[i][0][0];
4172
const double w2 = X[i][0][1];
4174
// Compute affine mapping y = F(X)
4176
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4177
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4179
// Evaluate function at physical points
4181
f.evaluate(values, y, c);
4183
// Map function values using appropriate mapping
4184
// Affine map: Do nothing
4186
// Note that we do not map the weights (yet).
4188
// Take directional components
4189
for(int k = 0; k < 2; k++)
4190
result += values[k]*D[i][0][k];
4191
// Multiply by weights
4197
/// Evaluate linear functionals for all dofs on the function f
4198
void cahnhilliard2d_0_finite_element_2::evaluate_dofs(double* values,
4199
const ufc::function& f,
4200
const ufc::cell& c) const
4202
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4205
/// Interpolate vertex values from dof values
4206
void cahnhilliard2d_0_finite_element_2::interpolate_vertex_values(double* vertex_values,
4207
const double* dof_values,
4208
const ufc::cell& c) const
4210
// Evaluate at vertices and use affine mapping
4211
vertex_values[0] = dof_values[0];
4212
vertex_values[2] = dof_values[1];
4213
vertex_values[4] = dof_values[2];
4214
// Evaluate at vertices and use affine mapping
4215
vertex_values[1] = dof_values[3];
4216
vertex_values[3] = dof_values[4];
4217
vertex_values[5] = dof_values[5];
4220
/// Return the number of sub elements (for a mixed element)
4221
unsigned int cahnhilliard2d_0_finite_element_2::num_sub_elements() const
4226
/// Create a new finite element for sub element i (for a mixed element)
4227
ufc::finite_element* cahnhilliard2d_0_finite_element_2::create_sub_element(unsigned int i) const
4232
return new cahnhilliard2d_0_finite_element_2_0();
4235
return new cahnhilliard2d_0_finite_element_2_1();
4243
cahnhilliard2d_0_finite_element_3::cahnhilliard2d_0_finite_element_3() : ufc::finite_element()
4249
cahnhilliard2d_0_finite_element_3::~cahnhilliard2d_0_finite_element_3()
4254
/// Return a string identifying the finite element
4255
const char* cahnhilliard2d_0_finite_element_3::signature() const
4257
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
4260
/// Return the cell shape
4261
ufc::shape cahnhilliard2d_0_finite_element_3::cell_shape() const
4263
return ufc::triangle;
4266
/// Return the dimension of the finite element function space
4267
unsigned int cahnhilliard2d_0_finite_element_3::space_dimension() const
4272
/// Return the rank of the value space
4273
unsigned int cahnhilliard2d_0_finite_element_3::value_rank() const
4278
/// Return the dimension of the value space for axis i
4279
unsigned int cahnhilliard2d_0_finite_element_3::value_dimension(unsigned int i) const
4284
/// Evaluate basis function i at given point in cell
4285
void cahnhilliard2d_0_finite_element_3::evaluate_basis(unsigned int i,
4287
const double* coordinates,
4288
const ufc::cell& c) const
4290
// Extract vertex coordinates
4291
const double * const * element_coordinates = c.coordinates;
4293
// Compute Jacobian of affine map from reference cell
4294
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4295
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4296
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4297
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4299
// Compute determinant of Jacobian
4300
const double detJ = J_00*J_11 - J_01*J_10;
4302
// Compute inverse of Jacobian
4304
// Get coordinates and map to the reference (UFC) element
4305
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4306
element_coordinates[0][0]*element_coordinates[2][1] +\
4307
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4308
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4309
element_coordinates[1][0]*element_coordinates[0][1] -\
4310
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4312
// Map coordinates to the reference square
4313
if (std::abs(y - 1.0) < 1e-14)
4316
x = 2.0 *x/(1.0 - y) - 1.0;
4322
// Map degree of freedom to element degree of freedom
4323
const unsigned int dof = i;
4325
// Generate scalings
4326
const double scalings_y_0 = 1;
4328
// Compute psitilde_a
4329
const double psitilde_a_0 = 1;
4331
// Compute psitilde_bs
4332
const double psitilde_bs_0_0 = 1;
4334
// Compute basisvalues
4335
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4337
// Table(s) of coefficients
4338
static const double coefficients0[1][1] = \
4339
{{1.41421356237309}};
4341
// Extract relevant coefficients
4342
const double coeff0_0 = coefficients0[dof][0];
4345
*values = coeff0_0*basisvalue0;
4348
/// Evaluate all basis functions at given point in cell
4349
void cahnhilliard2d_0_finite_element_3::evaluate_basis_all(double* values,
4350
const double* coordinates,
4351
const ufc::cell& c) const
4353
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4356
/// Evaluate order n derivatives of basis function i at given point in cell
4357
void cahnhilliard2d_0_finite_element_3::evaluate_basis_derivatives(unsigned int i,
4360
const double* coordinates,
4361
const ufc::cell& c) const
4363
// Extract vertex coordinates
4364
const double * const * element_coordinates = c.coordinates;
4366
// Compute Jacobian of affine map from reference cell
4367
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4368
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4369
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4370
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4372
// Compute determinant of Jacobian
4373
const double detJ = J_00*J_11 - J_01*J_10;
4375
// Compute inverse of Jacobian
4377
// Get coordinates and map to the reference (UFC) element
4378
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4379
element_coordinates[0][0]*element_coordinates[2][1] +\
4380
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4381
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4382
element_coordinates[1][0]*element_coordinates[0][1] -\
4383
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4385
// Map coordinates to the reference square
4386
if (std::abs(y - 1.0) < 1e-14)
4389
x = 2.0 *x/(1.0 - y) - 1.0;
4392
// Compute number of derivatives
4393
unsigned int num_derivatives = 1;
4395
for (unsigned int j = 0; j < n; j++)
4396
num_derivatives *= 2;
4399
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4400
unsigned int **combinations = new unsigned int *[num_derivatives];
4402
for (unsigned int j = 0; j < num_derivatives; j++)
4404
combinations[j] = new unsigned int [n];
4405
for (unsigned int k = 0; k < n; k++)
4406
combinations[j][k] = 0;
4409
// Generate combinations of derivatives
4410
for (unsigned int row = 1; row < num_derivatives; row++)
4412
for (unsigned int num = 0; num < row; num++)
4414
for (unsigned int col = n-1; col+1 > 0; col--)
4416
if (combinations[row][col] + 1 > 1)
4417
combinations[row][col] = 0;
4420
combinations[row][col] += 1;
4427
// Compute inverse of Jacobian
4428
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4430
// Declare transformation matrix
4431
// Declare pointer to two dimensional array and initialise
4432
double **transform = new double *[num_derivatives];
4434
for (unsigned int j = 0; j < num_derivatives; j++)
4436
transform[j] = new double [num_derivatives];
4437
for (unsigned int k = 0; k < num_derivatives; k++)
4438
transform[j][k] = 1;
4441
// Construct transformation matrix
4442
for (unsigned int row = 0; row < num_derivatives; row++)
4444
for (unsigned int col = 0; col < num_derivatives; col++)
4446
for (unsigned int k = 0; k < n; k++)
4447
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4452
for (unsigned int j = 0; j < 1*num_derivatives; j++)
4455
// Map degree of freedom to element degree of freedom
4456
const unsigned int dof = i;
4458
// Generate scalings
4459
const double scalings_y_0 = 1;
4461
// Compute psitilde_a
4462
const double psitilde_a_0 = 1;
4464
// Compute psitilde_bs
4465
const double psitilde_bs_0_0 = 1;
4467
// Compute basisvalues
4468
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4470
// Table(s) of coefficients
4471
static const double coefficients0[1][1] = \
4472
{{1.41421356237309}};
4474
// Interesting (new) part
4475
// Tables of derivatives of the polynomial base (transpose)
4476
static const double dmats0[1][1] = \
4479
static const double dmats1[1][1] = \
4482
// Compute reference derivatives
4483
// Declare pointer to array of derivatives on FIAT element
4484
double *derivatives = new double [num_derivatives];
4486
// Declare coefficients
4487
double coeff0_0 = 0;
4489
// Declare new coefficients
4490
double new_coeff0_0 = 0;
4492
// Loop possible derivatives
4493
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4495
// Get values from coefficients array
4496
new_coeff0_0 = coefficients0[dof][0];
4498
// Loop derivative order
4499
for (unsigned int j = 0; j < n; j++)
4501
// Update old coefficients
4502
coeff0_0 = new_coeff0_0;
4504
if(combinations[deriv_num][j] == 0)
4506
new_coeff0_0 = coeff0_0*dmats0[0][0];
4508
if(combinations[deriv_num][j] == 1)
4510
new_coeff0_0 = coeff0_0*dmats1[0][0];
4514
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4515
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
4518
// Transform derivatives back to physical element
4519
for (unsigned int row = 0; row < num_derivatives; row++)
4521
for (unsigned int col = 0; col < num_derivatives; col++)
4523
values[row] += transform[row][col]*derivatives[col];
4526
// Delete pointer to array of derivatives on FIAT element
4527
delete [] derivatives;
4529
// Delete pointer to array of combinations of derivatives and transform
4530
for (unsigned int row = 0; row < num_derivatives; row++)
4532
delete [] combinations[row];
4533
delete [] transform[row];
4536
delete [] combinations;
4537
delete [] transform;
4540
/// Evaluate order n derivatives of all basis functions at given point in cell
4541
void cahnhilliard2d_0_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
4543
const double* coordinates,
4544
const ufc::cell& c) const
4546
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4549
/// Evaluate linear functional for dof i on the function f
4550
double cahnhilliard2d_0_finite_element_3::evaluate_dof(unsigned int i,
4551
const ufc::function& f,
4552
const ufc::cell& c) const
4554
// The reference points, direction and weights:
4555
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
4556
static const double W[1][1] = {{1}};
4557
static const double D[1][1][1] = {{{1}}};
4559
const double * const * x = c.coordinates;
4560
double result = 0.0;
4561
// Iterate over the points:
4562
// Evaluate basis functions for affine mapping
4563
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4564
const double w1 = X[i][0][0];
4565
const double w2 = X[i][0][1];
4567
// Compute affine mapping y = F(X)
4569
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4570
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4572
// Evaluate function at physical points
4574
f.evaluate(values, y, c);
4576
// Map function values using appropriate mapping
4577
// Affine map: Do nothing
4579
// Note that we do not map the weights (yet).
4581
// Take directional components
4582
for(int k = 0; k < 1; k++)
4583
result += values[k]*D[i][0][k];
4584
// Multiply by weights
4590
/// Evaluate linear functionals for all dofs on the function f
4591
void cahnhilliard2d_0_finite_element_3::evaluate_dofs(double* values,
4592
const ufc::function& f,
4593
const ufc::cell& c) const
4595
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4598
/// Interpolate vertex values from dof values
4599
void cahnhilliard2d_0_finite_element_3::interpolate_vertex_values(double* vertex_values,
4600
const double* dof_values,
4601
const ufc::cell& c) const
4603
// Evaluate at vertices and use affine mapping
4604
vertex_values[0] = dof_values[0];
4605
vertex_values[1] = dof_values[0];
4606
vertex_values[2] = dof_values[0];
4609
/// Return the number of sub elements (for a mixed element)
4610
unsigned int cahnhilliard2d_0_finite_element_3::num_sub_elements() const
4615
/// Create a new finite element for sub element i (for a mixed element)
4616
ufc::finite_element* cahnhilliard2d_0_finite_element_3::create_sub_element(unsigned int i) const
4618
return new cahnhilliard2d_0_finite_element_3();
4623
cahnhilliard2d_0_finite_element_4::cahnhilliard2d_0_finite_element_4() : ufc::finite_element()
4629
cahnhilliard2d_0_finite_element_4::~cahnhilliard2d_0_finite_element_4()
4634
/// Return a string identifying the finite element
4635
const char* cahnhilliard2d_0_finite_element_4::signature() const
4637
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
4640
/// Return the cell shape
4641
ufc::shape cahnhilliard2d_0_finite_element_4::cell_shape() const
4643
return ufc::triangle;
4646
/// Return the dimension of the finite element function space
4647
unsigned int cahnhilliard2d_0_finite_element_4::space_dimension() const
4652
/// Return the rank of the value space
4653
unsigned int cahnhilliard2d_0_finite_element_4::value_rank() const
4658
/// Return the dimension of the value space for axis i
4659
unsigned int cahnhilliard2d_0_finite_element_4::value_dimension(unsigned int i) const
4664
/// Evaluate basis function i at given point in cell
4665
void cahnhilliard2d_0_finite_element_4::evaluate_basis(unsigned int i,
4667
const double* coordinates,
4668
const ufc::cell& c) const
4670
// Extract vertex coordinates
4671
const double * const * element_coordinates = c.coordinates;
4673
// Compute Jacobian of affine map from reference cell
4674
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4675
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4676
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4677
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4679
// Compute determinant of Jacobian
4680
const double detJ = J_00*J_11 - J_01*J_10;
4682
// Compute inverse of Jacobian
4684
// Get coordinates and map to the reference (UFC) element
4685
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4686
element_coordinates[0][0]*element_coordinates[2][1] +\
4687
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4688
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4689
element_coordinates[1][0]*element_coordinates[0][1] -\
4690
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4692
// Map coordinates to the reference square
4693
if (std::abs(y - 1.0) < 1e-14)
4696
x = 2.0 *x/(1.0 - y) - 1.0;
4702
// Map degree of freedom to element degree of freedom
4703
const unsigned int dof = i;
4705
// Generate scalings
4706
const double scalings_y_0 = 1;
4708
// Compute psitilde_a
4709
const double psitilde_a_0 = 1;
4711
// Compute psitilde_bs
4712
const double psitilde_bs_0_0 = 1;
4714
// Compute basisvalues
4715
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4717
// Table(s) of coefficients
4718
static const double coefficients0[1][1] = \
4719
{{1.41421356237309}};
4721
// Extract relevant coefficients
4722
const double coeff0_0 = coefficients0[dof][0];
4725
*values = coeff0_0*basisvalue0;
4728
/// Evaluate all basis functions at given point in cell
4729
void cahnhilliard2d_0_finite_element_4::evaluate_basis_all(double* values,
4730
const double* coordinates,
4731
const ufc::cell& c) const
4733
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4736
/// Evaluate order n derivatives of basis function i at given point in cell
4737
void cahnhilliard2d_0_finite_element_4::evaluate_basis_derivatives(unsigned int i,
4740
const double* coordinates,
4741
const ufc::cell& c) const
4743
// Extract vertex coordinates
4744
const double * const * element_coordinates = c.coordinates;
4746
// Compute Jacobian of affine map from reference cell
4747
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4748
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4749
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4750
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4752
// Compute determinant of Jacobian
4753
const double detJ = J_00*J_11 - J_01*J_10;
4755
// Compute inverse of Jacobian
4757
// Get coordinates and map to the reference (UFC) element
4758
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4759
element_coordinates[0][0]*element_coordinates[2][1] +\
4760
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4761
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4762
element_coordinates[1][0]*element_coordinates[0][1] -\
4763
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4765
// Map coordinates to the reference square
4766
if (std::abs(y - 1.0) < 1e-14)
4769
x = 2.0 *x/(1.0 - y) - 1.0;
4772
// Compute number of derivatives
4773
unsigned int num_derivatives = 1;
4775
for (unsigned int j = 0; j < n; j++)
4776
num_derivatives *= 2;
4779
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4780
unsigned int **combinations = new unsigned int *[num_derivatives];
4782
for (unsigned int j = 0; j < num_derivatives; j++)
4784
combinations[j] = new unsigned int [n];
4785
for (unsigned int k = 0; k < n; k++)
4786
combinations[j][k] = 0;
4789
// Generate combinations of derivatives
4790
for (unsigned int row = 1; row < num_derivatives; row++)
4792
for (unsigned int num = 0; num < row; num++)
4794
for (unsigned int col = n-1; col+1 > 0; col--)
4796
if (combinations[row][col] + 1 > 1)
4797
combinations[row][col] = 0;
4800
combinations[row][col] += 1;
4807
// Compute inverse of Jacobian
4808
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4810
// Declare transformation matrix
4811
// Declare pointer to two dimensional array and initialise
4812
double **transform = new double *[num_derivatives];
4814
for (unsigned int j = 0; j < num_derivatives; j++)
4816
transform[j] = new double [num_derivatives];
4817
for (unsigned int k = 0; k < num_derivatives; k++)
4818
transform[j][k] = 1;
4821
// Construct transformation matrix
4822
for (unsigned int row = 0; row < num_derivatives; row++)
4824
for (unsigned int col = 0; col < num_derivatives; col++)
4826
for (unsigned int k = 0; k < n; k++)
4827
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4832
for (unsigned int j = 0; j < 1*num_derivatives; j++)
4835
// Map degree of freedom to element degree of freedom
4836
const unsigned int dof = i;
4838
// Generate scalings
4839
const double scalings_y_0 = 1;
4841
// Compute psitilde_a
4842
const double psitilde_a_0 = 1;
4844
// Compute psitilde_bs
4845
const double psitilde_bs_0_0 = 1;
4847
// Compute basisvalues
4848
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4850
// Table(s) of coefficients
4851
static const double coefficients0[1][1] = \
4852
{{1.41421356237309}};
4854
// Interesting (new) part
4855
// Tables of derivatives of the polynomial base (transpose)
4856
static const double dmats0[1][1] = \
4859
static const double dmats1[1][1] = \
4862
// Compute reference derivatives
4863
// Declare pointer to array of derivatives on FIAT element
4864
double *derivatives = new double [num_derivatives];
4866
// Declare coefficients
4867
double coeff0_0 = 0;
4869
// Declare new coefficients
4870
double new_coeff0_0 = 0;
4872
// Loop possible derivatives
4873
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4875
// Get values from coefficients array
4876
new_coeff0_0 = coefficients0[dof][0];
4878
// Loop derivative order
4879
for (unsigned int j = 0; j < n; j++)
4881
// Update old coefficients
4882
coeff0_0 = new_coeff0_0;
4884
if(combinations[deriv_num][j] == 0)
4886
new_coeff0_0 = coeff0_0*dmats0[0][0];
4888
if(combinations[deriv_num][j] == 1)
4890
new_coeff0_0 = coeff0_0*dmats1[0][0];
4894
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4895
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
4898
// Transform derivatives back to physical element
4899
for (unsigned int row = 0; row < num_derivatives; row++)
4901
for (unsigned int col = 0; col < num_derivatives; col++)
4903
values[row] += transform[row][col]*derivatives[col];
4906
// Delete pointer to array of derivatives on FIAT element
4907
delete [] derivatives;
4909
// Delete pointer to array of combinations of derivatives and transform
4910
for (unsigned int row = 0; row < num_derivatives; row++)
4912
delete [] combinations[row];
4913
delete [] transform[row];
4916
delete [] combinations;
4917
delete [] transform;
4920
/// Evaluate order n derivatives of all basis functions at given point in cell
4921
void cahnhilliard2d_0_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
4923
const double* coordinates,
4924
const ufc::cell& c) const
4926
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4929
/// Evaluate linear functional for dof i on the function f
4930
double cahnhilliard2d_0_finite_element_4::evaluate_dof(unsigned int i,
4931
const ufc::function& f,
4932
const ufc::cell& c) const
4934
// The reference points, direction and weights:
4935
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
4936
static const double W[1][1] = {{1}};
4937
static const double D[1][1][1] = {{{1}}};
4939
const double * const * x = c.coordinates;
4940
double result = 0.0;
4941
// Iterate over the points:
4942
// Evaluate basis functions for affine mapping
4943
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4944
const double w1 = X[i][0][0];
4945
const double w2 = X[i][0][1];
4947
// Compute affine mapping y = F(X)
4949
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4950
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4952
// Evaluate function at physical points
4954
f.evaluate(values, y, c);
4956
// Map function values using appropriate mapping
4957
// Affine map: Do nothing
4959
// Note that we do not map the weights (yet).
4961
// Take directional components
4962
for(int k = 0; k < 1; k++)
4963
result += values[k]*D[i][0][k];
4964
// Multiply by weights
4970
/// Evaluate linear functionals for all dofs on the function f
4971
void cahnhilliard2d_0_finite_element_4::evaluate_dofs(double* values,
4972
const ufc::function& f,
4973
const ufc::cell& c) const
4975
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4978
/// Interpolate vertex values from dof values
4979
void cahnhilliard2d_0_finite_element_4::interpolate_vertex_values(double* vertex_values,
4980
const double* dof_values,
4981
const ufc::cell& c) const
4983
// Evaluate at vertices and use affine mapping
4984
vertex_values[0] = dof_values[0];
4985
vertex_values[1] = dof_values[0];
4986
vertex_values[2] = dof_values[0];
4989
/// Return the number of sub elements (for a mixed element)
4990
unsigned int cahnhilliard2d_0_finite_element_4::num_sub_elements() const
4995
/// Create a new finite element for sub element i (for a mixed element)
4996
ufc::finite_element* cahnhilliard2d_0_finite_element_4::create_sub_element(unsigned int i) const
4998
return new cahnhilliard2d_0_finite_element_4();
5003
cahnhilliard2d_0_finite_element_5::cahnhilliard2d_0_finite_element_5() : ufc::finite_element()
5009
cahnhilliard2d_0_finite_element_5::~cahnhilliard2d_0_finite_element_5()
5014
/// Return a string identifying the finite element
5015
const char* cahnhilliard2d_0_finite_element_5::signature() const
5017
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
5020
/// Return the cell shape
5021
ufc::shape cahnhilliard2d_0_finite_element_5::cell_shape() const
5023
return ufc::triangle;
5026
/// Return the dimension of the finite element function space
5027
unsigned int cahnhilliard2d_0_finite_element_5::space_dimension() const
5032
/// Return the rank of the value space
5033
unsigned int cahnhilliard2d_0_finite_element_5::value_rank() const
5038
/// Return the dimension of the value space for axis i
5039
unsigned int cahnhilliard2d_0_finite_element_5::value_dimension(unsigned int i) const
5044
/// Evaluate basis function i at given point in cell
5045
void cahnhilliard2d_0_finite_element_5::evaluate_basis(unsigned int i,
5047
const double* coordinates,
5048
const ufc::cell& c) const
5050
// Extract vertex coordinates
5051
const double * const * element_coordinates = c.coordinates;
5053
// Compute Jacobian of affine map from reference cell
5054
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5055
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5056
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5057
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5059
// Compute determinant of Jacobian
5060
const double detJ = J_00*J_11 - J_01*J_10;
5062
// Compute inverse of Jacobian
5064
// Get coordinates and map to the reference (UFC) element
5065
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5066
element_coordinates[0][0]*element_coordinates[2][1] +\
5067
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5068
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5069
element_coordinates[1][0]*element_coordinates[0][1] -\
5070
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5072
// Map coordinates to the reference square
5073
if (std::abs(y - 1.0) < 1e-14)
5076
x = 2.0 *x/(1.0 - y) - 1.0;
5082
// Map degree of freedom to element degree of freedom
5083
const unsigned int dof = i;
5085
// Generate scalings
5086
const double scalings_y_0 = 1;
5088
// Compute psitilde_a
5089
const double psitilde_a_0 = 1;
5091
// Compute psitilde_bs
5092
const double psitilde_bs_0_0 = 1;
5094
// Compute basisvalues
5095
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5097
// Table(s) of coefficients
5098
static const double coefficients0[1][1] = \
5099
{{1.41421356237309}};
5101
// Extract relevant coefficients
5102
const double coeff0_0 = coefficients0[dof][0];
5105
*values = coeff0_0*basisvalue0;
5108
/// Evaluate all basis functions at given point in cell
5109
void cahnhilliard2d_0_finite_element_5::evaluate_basis_all(double* values,
5110
const double* coordinates,
5111
const ufc::cell& c) const
5113
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5116
/// Evaluate order n derivatives of basis function i at given point in cell
5117
void cahnhilliard2d_0_finite_element_5::evaluate_basis_derivatives(unsigned int i,
5120
const double* coordinates,
5121
const ufc::cell& c) const
5123
// Extract vertex coordinates
5124
const double * const * element_coordinates = c.coordinates;
5126
// Compute Jacobian of affine map from reference cell
5127
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5128
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5129
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5130
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5132
// Compute determinant of Jacobian
5133
const double detJ = J_00*J_11 - J_01*J_10;
5135
// Compute inverse of Jacobian
5137
// Get coordinates and map to the reference (UFC) element
5138
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5139
element_coordinates[0][0]*element_coordinates[2][1] +\
5140
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5141
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5142
element_coordinates[1][0]*element_coordinates[0][1] -\
5143
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5145
// Map coordinates to the reference square
5146
if (std::abs(y - 1.0) < 1e-14)
5149
x = 2.0 *x/(1.0 - y) - 1.0;
5152
// Compute number of derivatives
5153
unsigned int num_derivatives = 1;
5155
for (unsigned int j = 0; j < n; j++)
5156
num_derivatives *= 2;
5159
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5160
unsigned int **combinations = new unsigned int *[num_derivatives];
5162
for (unsigned int j = 0; j < num_derivatives; j++)
5164
combinations[j] = new unsigned int [n];
5165
for (unsigned int k = 0; k < n; k++)
5166
combinations[j][k] = 0;
5169
// Generate combinations of derivatives
5170
for (unsigned int row = 1; row < num_derivatives; row++)
5172
for (unsigned int num = 0; num < row; num++)
5174
for (unsigned int col = n-1; col+1 > 0; col--)
5176
if (combinations[row][col] + 1 > 1)
5177
combinations[row][col] = 0;
5180
combinations[row][col] += 1;
5187
// Compute inverse of Jacobian
5188
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
5190
// Declare transformation matrix
5191
// Declare pointer to two dimensional array and initialise
5192
double **transform = new double *[num_derivatives];
5194
for (unsigned int j = 0; j < num_derivatives; j++)
5196
transform[j] = new double [num_derivatives];
5197
for (unsigned int k = 0; k < num_derivatives; k++)
5198
transform[j][k] = 1;
5201
// Construct transformation matrix
5202
for (unsigned int row = 0; row < num_derivatives; row++)
5204
for (unsigned int col = 0; col < num_derivatives; col++)
5206
for (unsigned int k = 0; k < n; k++)
5207
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5212
for (unsigned int j = 0; j < 1*num_derivatives; j++)
5215
// Map degree of freedom to element degree of freedom
5216
const unsigned int dof = i;
5218
// Generate scalings
5219
const double scalings_y_0 = 1;
5221
// Compute psitilde_a
5222
const double psitilde_a_0 = 1;
5224
// Compute psitilde_bs
5225
const double psitilde_bs_0_0 = 1;
5227
// Compute basisvalues
5228
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5230
// Table(s) of coefficients
5231
static const double coefficients0[1][1] = \
5232
{{1.41421356237309}};
5234
// Interesting (new) part
5235
// Tables of derivatives of the polynomial base (transpose)
5236
static const double dmats0[1][1] = \
5239
static const double dmats1[1][1] = \
5242
// Compute reference derivatives
5243
// Declare pointer to array of derivatives on FIAT element
5244
double *derivatives = new double [num_derivatives];
5246
// Declare coefficients
5247
double coeff0_0 = 0;
5249
// Declare new coefficients
5250
double new_coeff0_0 = 0;
5252
// Loop possible derivatives
5253
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5255
// Get values from coefficients array
5256
new_coeff0_0 = coefficients0[dof][0];
5258
// Loop derivative order
5259
for (unsigned int j = 0; j < n; j++)
5261
// Update old coefficients
5262
coeff0_0 = new_coeff0_0;
5264
if(combinations[deriv_num][j] == 0)
5266
new_coeff0_0 = coeff0_0*dmats0[0][0];
5268
if(combinations[deriv_num][j] == 1)
5270
new_coeff0_0 = coeff0_0*dmats1[0][0];
5274
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5275
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
5278
// Transform derivatives back to physical element
5279
for (unsigned int row = 0; row < num_derivatives; row++)
5281
for (unsigned int col = 0; col < num_derivatives; col++)
5283
values[row] += transform[row][col]*derivatives[col];
5286
// Delete pointer to array of derivatives on FIAT element
5287
delete [] derivatives;
5289
// Delete pointer to array of combinations of derivatives and transform
5290
for (unsigned int row = 0; row < num_derivatives; row++)
5292
delete [] combinations[row];
5293
delete [] transform[row];
5296
delete [] combinations;
5297
delete [] transform;
5300
/// Evaluate order n derivatives of all basis functions at given point in cell
5301
void cahnhilliard2d_0_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
5303
const double* coordinates,
5304
const ufc::cell& c) const
5306
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5309
/// Evaluate linear functional for dof i on the function f
5310
double cahnhilliard2d_0_finite_element_5::evaluate_dof(unsigned int i,
5311
const ufc::function& f,
5312
const ufc::cell& c) const
5314
// The reference points, direction and weights:
5315
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
5316
static const double W[1][1] = {{1}};
5317
static const double D[1][1][1] = {{{1}}};
5319
const double * const * x = c.coordinates;
5320
double result = 0.0;
5321
// Iterate over the points:
5322
// Evaluate basis functions for affine mapping
5323
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
5324
const double w1 = X[i][0][0];
5325
const double w2 = X[i][0][1];
5327
// Compute affine mapping y = F(X)
5329
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
5330
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
5332
// Evaluate function at physical points
5334
f.evaluate(values, y, c);
5336
// Map function values using appropriate mapping
5337
// Affine map: Do nothing
5339
// Note that we do not map the weights (yet).
5341
// Take directional components
5342
for(int k = 0; k < 1; k++)
5343
result += values[k]*D[i][0][k];
5344
// Multiply by weights
5350
/// Evaluate linear functionals for all dofs on the function f
5351
void cahnhilliard2d_0_finite_element_5::evaluate_dofs(double* values,
5352
const ufc::function& f,
5353
const ufc::cell& c) const
5355
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5358
/// Interpolate vertex values from dof values
5359
void cahnhilliard2d_0_finite_element_5::interpolate_vertex_values(double* vertex_values,
5360
const double* dof_values,
5361
const ufc::cell& c) const
5363
// Evaluate at vertices and use affine mapping
5364
vertex_values[0] = dof_values[0];
5365
vertex_values[1] = dof_values[0];
5366
vertex_values[2] = dof_values[0];
5369
/// Return the number of sub elements (for a mixed element)
5370
unsigned int cahnhilliard2d_0_finite_element_5::num_sub_elements() const
5375
/// Create a new finite element for sub element i (for a mixed element)
5376
ufc::finite_element* cahnhilliard2d_0_finite_element_5::create_sub_element(unsigned int i) const
5378
return new cahnhilliard2d_0_finite_element_5();
5383
cahnhilliard2d_0_finite_element_6::cahnhilliard2d_0_finite_element_6() : ufc::finite_element()
5389
cahnhilliard2d_0_finite_element_6::~cahnhilliard2d_0_finite_element_6()
5394
/// Return a string identifying the finite element
5395
const char* cahnhilliard2d_0_finite_element_6::signature() const
5397
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
5400
/// Return the cell shape
5401
ufc::shape cahnhilliard2d_0_finite_element_6::cell_shape() const
5403
return ufc::triangle;
5406
/// Return the dimension of the finite element function space
5407
unsigned int cahnhilliard2d_0_finite_element_6::space_dimension() const
5412
/// Return the rank of the value space
5413
unsigned int cahnhilliard2d_0_finite_element_6::value_rank() const
5418
/// Return the dimension of the value space for axis i
5419
unsigned int cahnhilliard2d_0_finite_element_6::value_dimension(unsigned int i) const
5424
/// Evaluate basis function i at given point in cell
5425
void cahnhilliard2d_0_finite_element_6::evaluate_basis(unsigned int i,
5427
const double* coordinates,
5428
const ufc::cell& c) const
5430
// Extract vertex coordinates
5431
const double * const * element_coordinates = c.coordinates;
5433
// Compute Jacobian of affine map from reference cell
5434
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5435
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5436
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5437
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5439
// Compute determinant of Jacobian
5440
const double detJ = J_00*J_11 - J_01*J_10;
5442
// Compute inverse of Jacobian
5444
// Get coordinates and map to the reference (UFC) element
5445
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5446
element_coordinates[0][0]*element_coordinates[2][1] +\
5447
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5448
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5449
element_coordinates[1][0]*element_coordinates[0][1] -\
5450
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5452
// Map coordinates to the reference square
5453
if (std::abs(y - 1.0) < 1e-14)
5456
x = 2.0 *x/(1.0 - y) - 1.0;
5462
// Map degree of freedom to element degree of freedom
5463
const unsigned int dof = i;
5465
// Generate scalings
5466
const double scalings_y_0 = 1;
5468
// Compute psitilde_a
5469
const double psitilde_a_0 = 1;
5471
// Compute psitilde_bs
5472
const double psitilde_bs_0_0 = 1;
5474
// Compute basisvalues
5475
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5477
// Table(s) of coefficients
5478
static const double coefficients0[1][1] = \
5479
{{1.41421356237309}};
5481
// Extract relevant coefficients
5482
const double coeff0_0 = coefficients0[dof][0];
5485
*values = coeff0_0*basisvalue0;
5488
/// Evaluate all basis functions at given point in cell
5489
void cahnhilliard2d_0_finite_element_6::evaluate_basis_all(double* values,
5490
const double* coordinates,
5491
const ufc::cell& c) const
5493
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5496
/// Evaluate order n derivatives of basis function i at given point in cell
5497
void cahnhilliard2d_0_finite_element_6::evaluate_basis_derivatives(unsigned int i,
5500
const double* coordinates,
5501
const ufc::cell& c) const
5503
// Extract vertex coordinates
5504
const double * const * element_coordinates = c.coordinates;
5506
// Compute Jacobian of affine map from reference cell
5507
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5508
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5509
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5510
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5512
// Compute determinant of Jacobian
5513
const double detJ = J_00*J_11 - J_01*J_10;
5515
// Compute inverse of Jacobian
5517
// Get coordinates and map to the reference (UFC) element
5518
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5519
element_coordinates[0][0]*element_coordinates[2][1] +\
5520
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5521
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5522
element_coordinates[1][0]*element_coordinates[0][1] -\
5523
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5525
// Map coordinates to the reference square
5526
if (std::abs(y - 1.0) < 1e-14)
5529
x = 2.0 *x/(1.0 - y) - 1.0;
5532
// Compute number of derivatives
5533
unsigned int num_derivatives = 1;
5535
for (unsigned int j = 0; j < n; j++)
5536
num_derivatives *= 2;
5539
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5540
unsigned int **combinations = new unsigned int *[num_derivatives];
5542
for (unsigned int j = 0; j < num_derivatives; j++)
5544
combinations[j] = new unsigned int [n];
5545
for (unsigned int k = 0; k < n; k++)
5546
combinations[j][k] = 0;
5549
// Generate combinations of derivatives
5550
for (unsigned int row = 1; row < num_derivatives; row++)
5552
for (unsigned int num = 0; num < row; num++)
5554
for (unsigned int col = n-1; col+1 > 0; col--)
5556
if (combinations[row][col] + 1 > 1)
5557
combinations[row][col] = 0;
5560
combinations[row][col] += 1;
5567
// Compute inverse of Jacobian
5568
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
5570
// Declare transformation matrix
5571
// Declare pointer to two dimensional array and initialise
5572
double **transform = new double *[num_derivatives];
5574
for (unsigned int j = 0; j < num_derivatives; j++)
5576
transform[j] = new double [num_derivatives];
5577
for (unsigned int k = 0; k < num_derivatives; k++)
5578
transform[j][k] = 1;
5581
// Construct transformation matrix
5582
for (unsigned int row = 0; row < num_derivatives; row++)
5584
for (unsigned int col = 0; col < num_derivatives; col++)
5586
for (unsigned int k = 0; k < n; k++)
5587
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5592
for (unsigned int j = 0; j < 1*num_derivatives; j++)
5595
// Map degree of freedom to element degree of freedom
5596
const unsigned int dof = i;
5598
// Generate scalings
5599
const double scalings_y_0 = 1;
5601
// Compute psitilde_a
5602
const double psitilde_a_0 = 1;
5604
// Compute psitilde_bs
5605
const double psitilde_bs_0_0 = 1;
5607
// Compute basisvalues
5608
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5610
// Table(s) of coefficients
5611
static const double coefficients0[1][1] = \
5612
{{1.41421356237309}};
5614
// Interesting (new) part
5615
// Tables of derivatives of the polynomial base (transpose)
5616
static const double dmats0[1][1] = \
5619
static const double dmats1[1][1] = \
5622
// Compute reference derivatives
5623
// Declare pointer to array of derivatives on FIAT element
5624
double *derivatives = new double [num_derivatives];
5626
// Declare coefficients
5627
double coeff0_0 = 0;
5629
// Declare new coefficients
5630
double new_coeff0_0 = 0;
5632
// Loop possible derivatives
5633
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5635
// Get values from coefficients array
5636
new_coeff0_0 = coefficients0[dof][0];
5638
// Loop derivative order
5639
for (unsigned int j = 0; j < n; j++)
5641
// Update old coefficients
5642
coeff0_0 = new_coeff0_0;
5644
if(combinations[deriv_num][j] == 0)
5646
new_coeff0_0 = coeff0_0*dmats0[0][0];
5648
if(combinations[deriv_num][j] == 1)
5650
new_coeff0_0 = coeff0_0*dmats1[0][0];
5654
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5655
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
5658
// Transform derivatives back to physical element
5659
for (unsigned int row = 0; row < num_derivatives; row++)
5661
for (unsigned int col = 0; col < num_derivatives; col++)
5663
values[row] += transform[row][col]*derivatives[col];
5666
// Delete pointer to array of derivatives on FIAT element
5667
delete [] derivatives;
5669
// Delete pointer to array of combinations of derivatives and transform
5670
for (unsigned int row = 0; row < num_derivatives; row++)
5672
delete [] combinations[row];
5673
delete [] transform[row];
5676
delete [] combinations;
5677
delete [] transform;
5680
/// Evaluate order n derivatives of all basis functions at given point in cell
5681
void cahnhilliard2d_0_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
5683
const double* coordinates,
5684
const ufc::cell& c) const
5686
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5689
/// Evaluate linear functional for dof i on the function f
5690
double cahnhilliard2d_0_finite_element_6::evaluate_dof(unsigned int i,
5691
const ufc::function& f,
5692
const ufc::cell& c) const
5694
// The reference points, direction and weights:
5695
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
5696
static const double W[1][1] = {{1}};
5697
static const double D[1][1][1] = {{{1}}};
5699
const double * const * x = c.coordinates;
5700
double result = 0.0;
5701
// Iterate over the points:
5702
// Evaluate basis functions for affine mapping
5703
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
5704
const double w1 = X[i][0][0];
5705
const double w2 = X[i][0][1];
5707
// Compute affine mapping y = F(X)
5709
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
5710
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
5712
// Evaluate function at physical points
5714
f.evaluate(values, y, c);
5716
// Map function values using appropriate mapping
5717
// Affine map: Do nothing
5719
// Note that we do not map the weights (yet).
5721
// Take directional components
5722
for(int k = 0; k < 1; k++)
5723
result += values[k]*D[i][0][k];
5724
// Multiply by weights
5730
/// Evaluate linear functionals for all dofs on the function f
5731
void cahnhilliard2d_0_finite_element_6::evaluate_dofs(double* values,
5732
const ufc::function& f,
5733
const ufc::cell& c) const
5735
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5738
/// Interpolate vertex values from dof values
5739
void cahnhilliard2d_0_finite_element_6::interpolate_vertex_values(double* vertex_values,
5740
const double* dof_values,
5741
const ufc::cell& c) const
5743
// Evaluate at vertices and use affine mapping
5744
vertex_values[0] = dof_values[0];
5745
vertex_values[1] = dof_values[0];
5746
vertex_values[2] = dof_values[0];
5749
/// Return the number of sub elements (for a mixed element)
5750
unsigned int cahnhilliard2d_0_finite_element_6::num_sub_elements() const
5755
/// Create a new finite element for sub element i (for a mixed element)
5756
ufc::finite_element* cahnhilliard2d_0_finite_element_6::create_sub_element(unsigned int i) const
5758
return new cahnhilliard2d_0_finite_element_6();
5762
cahnhilliard2d_0_dof_map_0_0::cahnhilliard2d_0_dof_map_0_0() : ufc::dof_map()
5764
__global_dimension = 0;
5768
cahnhilliard2d_0_dof_map_0_0::~cahnhilliard2d_0_dof_map_0_0()
5773
/// Return a string identifying the dof map
5774
const char* cahnhilliard2d_0_dof_map_0_0::signature() const
5776
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
5779
/// Return true iff mesh entities of topological dimension d are needed
5780
bool cahnhilliard2d_0_dof_map_0_0::needs_mesh_entities(unsigned int d) const
5797
/// Initialize dof map for mesh (return true iff init_cell() is needed)
5798
bool cahnhilliard2d_0_dof_map_0_0::init_mesh(const ufc::mesh& m)
5800
__global_dimension = m.num_entities[0];
5804
/// Initialize dof map for given cell
5805
void cahnhilliard2d_0_dof_map_0_0::init_cell(const ufc::mesh& m,
5811
/// Finish initialization of dof map for cells
5812
void cahnhilliard2d_0_dof_map_0_0::init_cell_finalize()
5817
/// Return the dimension of the global finite element function space
5818
unsigned int cahnhilliard2d_0_dof_map_0_0::global_dimension() const
5820
return __global_dimension;
5823
/// Return the dimension of the local finite element function space for a cell
5824
unsigned int cahnhilliard2d_0_dof_map_0_0::local_dimension(const ufc::cell& c) const
5829
/// Return the maximum dimension of the local finite element function space
5830
unsigned int cahnhilliard2d_0_dof_map_0_0::max_local_dimension() const
5835
// Return the geometric dimension of the coordinates this dof map provides
5836
unsigned int cahnhilliard2d_0_dof_map_0_0::geometric_dimension() const
5841
/// Return the number of dofs on each cell facet
5842
unsigned int cahnhilliard2d_0_dof_map_0_0::num_facet_dofs() const
5847
/// Return the number of dofs associated with each cell entity of dimension d
5848
unsigned int cahnhilliard2d_0_dof_map_0_0::num_entity_dofs(unsigned int d) const
5850
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5853
/// Tabulate the local-to-global mapping of dofs on a cell
5854
void cahnhilliard2d_0_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
5856
const ufc::cell& c) const
5858
dofs[0] = c.entity_indices[0][0];
5859
dofs[1] = c.entity_indices[0][1];
5860
dofs[2] = c.entity_indices[0][2];
5863
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
5864
void cahnhilliard2d_0_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
5865
unsigned int facet) const
5884
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
5885
void cahnhilliard2d_0_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
5886
unsigned int d, unsigned int i) const
5888
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5891
/// Tabulate the coordinates of all dofs on a cell
5892
void cahnhilliard2d_0_dof_map_0_0::tabulate_coordinates(double** coordinates,
5893
const ufc::cell& c) const
5895
const double * const * x = c.coordinates;
5896
coordinates[0][0] = x[0][0];
5897
coordinates[0][1] = x[0][1];
5898
coordinates[1][0] = x[1][0];
5899
coordinates[1][1] = x[1][1];
5900
coordinates[2][0] = x[2][0];
5901
coordinates[2][1] = x[2][1];
5904
/// Return the number of sub dof maps (for a mixed element)
5905
unsigned int cahnhilliard2d_0_dof_map_0_0::num_sub_dof_maps() const
5910
/// Create a new dof_map for sub dof map i (for a mixed element)
5911
ufc::dof_map* cahnhilliard2d_0_dof_map_0_0::create_sub_dof_map(unsigned int i) const
5913
return new cahnhilliard2d_0_dof_map_0_0();
5918
cahnhilliard2d_0_dof_map_0_1::cahnhilliard2d_0_dof_map_0_1() : ufc::dof_map()
5920
__global_dimension = 0;
5924
cahnhilliard2d_0_dof_map_0_1::~cahnhilliard2d_0_dof_map_0_1()
5929
/// Return a string identifying the dof map
5930
const char* cahnhilliard2d_0_dof_map_0_1::signature() const
5932
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
5935
/// Return true iff mesh entities of topological dimension d are needed
5936
bool cahnhilliard2d_0_dof_map_0_1::needs_mesh_entities(unsigned int d) const
5953
/// Initialize dof map for mesh (return true iff init_cell() is needed)
5954
bool cahnhilliard2d_0_dof_map_0_1::init_mesh(const ufc::mesh& m)
5956
__global_dimension = m.num_entities[0];
5960
/// Initialize dof map for given cell
5961
void cahnhilliard2d_0_dof_map_0_1::init_cell(const ufc::mesh& m,
5967
/// Finish initialization of dof map for cells
5968
void cahnhilliard2d_0_dof_map_0_1::init_cell_finalize()
5973
/// Return the dimension of the global finite element function space
5974
unsigned int cahnhilliard2d_0_dof_map_0_1::global_dimension() const
5976
return __global_dimension;
5979
/// Return the dimension of the local finite element function space for a cell
5980
unsigned int cahnhilliard2d_0_dof_map_0_1::local_dimension(const ufc::cell& c) const
5985
/// Return the maximum dimension of the local finite element function space
5986
unsigned int cahnhilliard2d_0_dof_map_0_1::max_local_dimension() const
5991
// Return the geometric dimension of the coordinates this dof map provides
5992
unsigned int cahnhilliard2d_0_dof_map_0_1::geometric_dimension() const
5997
/// Return the number of dofs on each cell facet
5998
unsigned int cahnhilliard2d_0_dof_map_0_1::num_facet_dofs() const
6003
/// Return the number of dofs associated with each cell entity of dimension d
6004
unsigned int cahnhilliard2d_0_dof_map_0_1::num_entity_dofs(unsigned int d) const
6006
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6009
/// Tabulate the local-to-global mapping of dofs on a cell
6010
void cahnhilliard2d_0_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
6012
const ufc::cell& c) const
6014
dofs[0] = c.entity_indices[0][0];
6015
dofs[1] = c.entity_indices[0][1];
6016
dofs[2] = c.entity_indices[0][2];
6019
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6020
void cahnhilliard2d_0_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
6021
unsigned int facet) const
6040
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6041
void cahnhilliard2d_0_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
6042
unsigned int d, unsigned int i) const
6044
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6047
/// Tabulate the coordinates of all dofs on a cell
6048
void cahnhilliard2d_0_dof_map_0_1::tabulate_coordinates(double** coordinates,
6049
const ufc::cell& c) const
6051
const double * const * x = c.coordinates;
6052
coordinates[0][0] = x[0][0];
6053
coordinates[0][1] = x[0][1];
6054
coordinates[1][0] = x[1][0];
6055
coordinates[1][1] = x[1][1];
6056
coordinates[2][0] = x[2][0];
6057
coordinates[2][1] = x[2][1];
6060
/// Return the number of sub dof maps (for a mixed element)
6061
unsigned int cahnhilliard2d_0_dof_map_0_1::num_sub_dof_maps() const
6066
/// Create a new dof_map for sub dof map i (for a mixed element)
6067
ufc::dof_map* cahnhilliard2d_0_dof_map_0_1::create_sub_dof_map(unsigned int i) const
6069
return new cahnhilliard2d_0_dof_map_0_1();
6074
cahnhilliard2d_0_dof_map_0::cahnhilliard2d_0_dof_map_0() : ufc::dof_map()
6076
__global_dimension = 0;
6080
cahnhilliard2d_0_dof_map_0::~cahnhilliard2d_0_dof_map_0()
6085
/// Return a string identifying the dof map
6086
const char* cahnhilliard2d_0_dof_map_0::signature() const
6088
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
6091
/// Return true iff mesh entities of topological dimension d are needed
6092
bool cahnhilliard2d_0_dof_map_0::needs_mesh_entities(unsigned int d) const
6109
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6110
bool cahnhilliard2d_0_dof_map_0::init_mesh(const ufc::mesh& m)
6112
__global_dimension = 2*m.num_entities[0];
6116
/// Initialize dof map for given cell
6117
void cahnhilliard2d_0_dof_map_0::init_cell(const ufc::mesh& m,
6123
/// Finish initialization of dof map for cells
6124
void cahnhilliard2d_0_dof_map_0::init_cell_finalize()
6129
/// Return the dimension of the global finite element function space
6130
unsigned int cahnhilliard2d_0_dof_map_0::global_dimension() const
6132
return __global_dimension;
6135
/// Return the dimension of the local finite element function space for a cell
6136
unsigned int cahnhilliard2d_0_dof_map_0::local_dimension(const ufc::cell& c) const
6141
/// Return the maximum dimension of the local finite element function space
6142
unsigned int cahnhilliard2d_0_dof_map_0::max_local_dimension() const
6147
// Return the geometric dimension of the coordinates this dof map provides
6148
unsigned int cahnhilliard2d_0_dof_map_0::geometric_dimension() const
6153
/// Return the number of dofs on each cell facet
6154
unsigned int cahnhilliard2d_0_dof_map_0::num_facet_dofs() const
6159
/// Return the number of dofs associated with each cell entity of dimension d
6160
unsigned int cahnhilliard2d_0_dof_map_0::num_entity_dofs(unsigned int d) const
6162
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6165
/// Tabulate the local-to-global mapping of dofs on a cell
6166
void cahnhilliard2d_0_dof_map_0::tabulate_dofs(unsigned int* dofs,
6168
const ufc::cell& c) const
6170
dofs[0] = c.entity_indices[0][0];
6171
dofs[1] = c.entity_indices[0][1];
6172
dofs[2] = c.entity_indices[0][2];
6173
unsigned int offset = m.num_entities[0];
6174
dofs[3] = offset + c.entity_indices[0][0];
6175
dofs[4] = offset + c.entity_indices[0][1];
6176
dofs[5] = offset + c.entity_indices[0][2];
6179
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6180
void cahnhilliard2d_0_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
6181
unsigned int facet) const
6206
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6207
void cahnhilliard2d_0_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
6208
unsigned int d, unsigned int i) const
6210
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6213
/// Tabulate the coordinates of all dofs on a cell
6214
void cahnhilliard2d_0_dof_map_0::tabulate_coordinates(double** coordinates,
6215
const ufc::cell& c) const
6217
const double * const * x = c.coordinates;
6218
coordinates[0][0] = x[0][0];
6219
coordinates[0][1] = x[0][1];
6220
coordinates[1][0] = x[1][0];
6221
coordinates[1][1] = x[1][1];
6222
coordinates[2][0] = x[2][0];
6223
coordinates[2][1] = x[2][1];
6224
coordinates[3][0] = x[0][0];
6225
coordinates[3][1] = x[0][1];
6226
coordinates[4][0] = x[1][0];
6227
coordinates[4][1] = x[1][1];
6228
coordinates[5][0] = x[2][0];
6229
coordinates[5][1] = x[2][1];
6232
/// Return the number of sub dof maps (for a mixed element)
6233
unsigned int cahnhilliard2d_0_dof_map_0::num_sub_dof_maps() const
6238
/// Create a new dof_map for sub dof map i (for a mixed element)
6239
ufc::dof_map* cahnhilliard2d_0_dof_map_0::create_sub_dof_map(unsigned int i) const
6244
return new cahnhilliard2d_0_dof_map_0_0();
6247
return new cahnhilliard2d_0_dof_map_0_1();
6255
cahnhilliard2d_0_dof_map_1_0::cahnhilliard2d_0_dof_map_1_0() : ufc::dof_map()
6257
__global_dimension = 0;
6261
cahnhilliard2d_0_dof_map_1_0::~cahnhilliard2d_0_dof_map_1_0()
6266
/// Return a string identifying the dof map
6267
const char* cahnhilliard2d_0_dof_map_1_0::signature() const
6269
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6272
/// Return true iff mesh entities of topological dimension d are needed
6273
bool cahnhilliard2d_0_dof_map_1_0::needs_mesh_entities(unsigned int d) const
6290
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6291
bool cahnhilliard2d_0_dof_map_1_0::init_mesh(const ufc::mesh& m)
6293
__global_dimension = m.num_entities[0];
6297
/// Initialize dof map for given cell
6298
void cahnhilliard2d_0_dof_map_1_0::init_cell(const ufc::mesh& m,
6304
/// Finish initialization of dof map for cells
6305
void cahnhilliard2d_0_dof_map_1_0::init_cell_finalize()
6310
/// Return the dimension of the global finite element function space
6311
unsigned int cahnhilliard2d_0_dof_map_1_0::global_dimension() const
6313
return __global_dimension;
6316
/// Return the dimension of the local finite element function space for a cell
6317
unsigned int cahnhilliard2d_0_dof_map_1_0::local_dimension(const ufc::cell& c) const
6322
/// Return the maximum dimension of the local finite element function space
6323
unsigned int cahnhilliard2d_0_dof_map_1_0::max_local_dimension() const
6328
// Return the geometric dimension of the coordinates this dof map provides
6329
unsigned int cahnhilliard2d_0_dof_map_1_0::geometric_dimension() const
6334
/// Return the number of dofs on each cell facet
6335
unsigned int cahnhilliard2d_0_dof_map_1_0::num_facet_dofs() const
6340
/// Return the number of dofs associated with each cell entity of dimension d
6341
unsigned int cahnhilliard2d_0_dof_map_1_0::num_entity_dofs(unsigned int d) const
6343
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6346
/// Tabulate the local-to-global mapping of dofs on a cell
6347
void cahnhilliard2d_0_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
6349
const ufc::cell& c) const
6351
dofs[0] = c.entity_indices[0][0];
6352
dofs[1] = c.entity_indices[0][1];
6353
dofs[2] = c.entity_indices[0][2];
6356
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6357
void cahnhilliard2d_0_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
6358
unsigned int facet) const
6377
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6378
void cahnhilliard2d_0_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
6379
unsigned int d, unsigned int i) const
6381
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6384
/// Tabulate the coordinates of all dofs on a cell
6385
void cahnhilliard2d_0_dof_map_1_0::tabulate_coordinates(double** coordinates,
6386
const ufc::cell& c) const
6388
const double * const * x = c.coordinates;
6389
coordinates[0][0] = x[0][0];
6390
coordinates[0][1] = x[0][1];
6391
coordinates[1][0] = x[1][0];
6392
coordinates[1][1] = x[1][1];
6393
coordinates[2][0] = x[2][0];
6394
coordinates[2][1] = x[2][1];
6397
/// Return the number of sub dof maps (for a mixed element)
6398
unsigned int cahnhilliard2d_0_dof_map_1_0::num_sub_dof_maps() const
6403
/// Create a new dof_map for sub dof map i (for a mixed element)
6404
ufc::dof_map* cahnhilliard2d_0_dof_map_1_0::create_sub_dof_map(unsigned int i) const
6406
return new cahnhilliard2d_0_dof_map_1_0();
6411
cahnhilliard2d_0_dof_map_1_1::cahnhilliard2d_0_dof_map_1_1() : ufc::dof_map()
6413
__global_dimension = 0;
6417
cahnhilliard2d_0_dof_map_1_1::~cahnhilliard2d_0_dof_map_1_1()
6422
/// Return a string identifying the dof map
6423
const char* cahnhilliard2d_0_dof_map_1_1::signature() const
6425
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6428
/// Return true iff mesh entities of topological dimension d are needed
6429
bool cahnhilliard2d_0_dof_map_1_1::needs_mesh_entities(unsigned int d) const
6446
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6447
bool cahnhilliard2d_0_dof_map_1_1::init_mesh(const ufc::mesh& m)
6449
__global_dimension = m.num_entities[0];
6453
/// Initialize dof map for given cell
6454
void cahnhilliard2d_0_dof_map_1_1::init_cell(const ufc::mesh& m,
6460
/// Finish initialization of dof map for cells
6461
void cahnhilliard2d_0_dof_map_1_1::init_cell_finalize()
6466
/// Return the dimension of the global finite element function space
6467
unsigned int cahnhilliard2d_0_dof_map_1_1::global_dimension() const
6469
return __global_dimension;
6472
/// Return the dimension of the local finite element function space for a cell
6473
unsigned int cahnhilliard2d_0_dof_map_1_1::local_dimension(const ufc::cell& c) const
6478
/// Return the maximum dimension of the local finite element function space
6479
unsigned int cahnhilliard2d_0_dof_map_1_1::max_local_dimension() const
6484
// Return the geometric dimension of the coordinates this dof map provides
6485
unsigned int cahnhilliard2d_0_dof_map_1_1::geometric_dimension() const
6490
/// Return the number of dofs on each cell facet
6491
unsigned int cahnhilliard2d_0_dof_map_1_1::num_facet_dofs() const
6496
/// Return the number of dofs associated with each cell entity of dimension d
6497
unsigned int cahnhilliard2d_0_dof_map_1_1::num_entity_dofs(unsigned int d) const
6499
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6502
/// Tabulate the local-to-global mapping of dofs on a cell
6503
void cahnhilliard2d_0_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
6505
const ufc::cell& c) const
6507
dofs[0] = c.entity_indices[0][0];
6508
dofs[1] = c.entity_indices[0][1];
6509
dofs[2] = c.entity_indices[0][2];
6512
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6513
void cahnhilliard2d_0_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
6514
unsigned int facet) const
6533
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6534
void cahnhilliard2d_0_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
6535
unsigned int d, unsigned int i) const
6537
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6540
/// Tabulate the coordinates of all dofs on a cell
6541
void cahnhilliard2d_0_dof_map_1_1::tabulate_coordinates(double** coordinates,
6542
const ufc::cell& c) const
6544
const double * const * x = c.coordinates;
6545
coordinates[0][0] = x[0][0];
6546
coordinates[0][1] = x[0][1];
6547
coordinates[1][0] = x[1][0];
6548
coordinates[1][1] = x[1][1];
6549
coordinates[2][0] = x[2][0];
6550
coordinates[2][1] = x[2][1];
6553
/// Return the number of sub dof maps (for a mixed element)
6554
unsigned int cahnhilliard2d_0_dof_map_1_1::num_sub_dof_maps() const
6559
/// Create a new dof_map for sub dof map i (for a mixed element)
6560
ufc::dof_map* cahnhilliard2d_0_dof_map_1_1::create_sub_dof_map(unsigned int i) const
6562
return new cahnhilliard2d_0_dof_map_1_1();
6567
cahnhilliard2d_0_dof_map_1::cahnhilliard2d_0_dof_map_1() : ufc::dof_map()
6569
__global_dimension = 0;
6573
cahnhilliard2d_0_dof_map_1::~cahnhilliard2d_0_dof_map_1()
6578
/// Return a string identifying the dof map
6579
const char* cahnhilliard2d_0_dof_map_1::signature() const
6581
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
6584
/// Return true iff mesh entities of topological dimension d are needed
6585
bool cahnhilliard2d_0_dof_map_1::needs_mesh_entities(unsigned int d) const
6602
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6603
bool cahnhilliard2d_0_dof_map_1::init_mesh(const ufc::mesh& m)
6605
__global_dimension = 2*m.num_entities[0];
6609
/// Initialize dof map for given cell
6610
void cahnhilliard2d_0_dof_map_1::init_cell(const ufc::mesh& m,
6616
/// Finish initialization of dof map for cells
6617
void cahnhilliard2d_0_dof_map_1::init_cell_finalize()
6622
/// Return the dimension of the global finite element function space
6623
unsigned int cahnhilliard2d_0_dof_map_1::global_dimension() const
6625
return __global_dimension;
6628
/// Return the dimension of the local finite element function space for a cell
6629
unsigned int cahnhilliard2d_0_dof_map_1::local_dimension(const ufc::cell& c) const
6634
/// Return the maximum dimension of the local finite element function space
6635
unsigned int cahnhilliard2d_0_dof_map_1::max_local_dimension() const
6640
// Return the geometric dimension of the coordinates this dof map provides
6641
unsigned int cahnhilliard2d_0_dof_map_1::geometric_dimension() const
6646
/// Return the number of dofs on each cell facet
6647
unsigned int cahnhilliard2d_0_dof_map_1::num_facet_dofs() const
6652
/// Return the number of dofs associated with each cell entity of dimension d
6653
unsigned int cahnhilliard2d_0_dof_map_1::num_entity_dofs(unsigned int d) const
6655
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6658
/// Tabulate the local-to-global mapping of dofs on a cell
6659
void cahnhilliard2d_0_dof_map_1::tabulate_dofs(unsigned int* dofs,
6661
const ufc::cell& c) const
6663
dofs[0] = c.entity_indices[0][0];
6664
dofs[1] = c.entity_indices[0][1];
6665
dofs[2] = c.entity_indices[0][2];
6666
unsigned int offset = m.num_entities[0];
6667
dofs[3] = offset + c.entity_indices[0][0];
6668
dofs[4] = offset + c.entity_indices[0][1];
6669
dofs[5] = offset + c.entity_indices[0][2];
6672
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6673
void cahnhilliard2d_0_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
6674
unsigned int facet) const
6699
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6700
void cahnhilliard2d_0_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
6701
unsigned int d, unsigned int i) const
6703
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6706
/// Tabulate the coordinates of all dofs on a cell
6707
void cahnhilliard2d_0_dof_map_1::tabulate_coordinates(double** coordinates,
6708
const ufc::cell& c) const
6710
const double * const * x = c.coordinates;
6711
coordinates[0][0] = x[0][0];
6712
coordinates[0][1] = x[0][1];
6713
coordinates[1][0] = x[1][0];
6714
coordinates[1][1] = x[1][1];
6715
coordinates[2][0] = x[2][0];
6716
coordinates[2][1] = x[2][1];
6717
coordinates[3][0] = x[0][0];
6718
coordinates[3][1] = x[0][1];
6719
coordinates[4][0] = x[1][0];
6720
coordinates[4][1] = x[1][1];
6721
coordinates[5][0] = x[2][0];
6722
coordinates[5][1] = x[2][1];
6725
/// Return the number of sub dof maps (for a mixed element)
6726
unsigned int cahnhilliard2d_0_dof_map_1::num_sub_dof_maps() const
6731
/// Create a new dof_map for sub dof map i (for a mixed element)
6732
ufc::dof_map* cahnhilliard2d_0_dof_map_1::create_sub_dof_map(unsigned int i) const
6737
return new cahnhilliard2d_0_dof_map_1_0();
6740
return new cahnhilliard2d_0_dof_map_1_1();
6748
cahnhilliard2d_0_dof_map_2_0::cahnhilliard2d_0_dof_map_2_0() : ufc::dof_map()
6750
__global_dimension = 0;
6754
cahnhilliard2d_0_dof_map_2_0::~cahnhilliard2d_0_dof_map_2_0()
6759
/// Return a string identifying the dof map
6760
const char* cahnhilliard2d_0_dof_map_2_0::signature() const
6762
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6765
/// Return true iff mesh entities of topological dimension d are needed
6766
bool cahnhilliard2d_0_dof_map_2_0::needs_mesh_entities(unsigned int d) const
6783
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6784
bool cahnhilliard2d_0_dof_map_2_0::init_mesh(const ufc::mesh& m)
6786
__global_dimension = m.num_entities[0];
6790
/// Initialize dof map for given cell
6791
void cahnhilliard2d_0_dof_map_2_0::init_cell(const ufc::mesh& m,
6797
/// Finish initialization of dof map for cells
6798
void cahnhilliard2d_0_dof_map_2_0::init_cell_finalize()
6803
/// Return the dimension of the global finite element function space
6804
unsigned int cahnhilliard2d_0_dof_map_2_0::global_dimension() const
6806
return __global_dimension;
6809
/// Return the dimension of the local finite element function space for a cell
6810
unsigned int cahnhilliard2d_0_dof_map_2_0::local_dimension(const ufc::cell& c) const
6815
/// Return the maximum dimension of the local finite element function space
6816
unsigned int cahnhilliard2d_0_dof_map_2_0::max_local_dimension() const
6821
// Return the geometric dimension of the coordinates this dof map provides
6822
unsigned int cahnhilliard2d_0_dof_map_2_0::geometric_dimension() const
6827
/// Return the number of dofs on each cell facet
6828
unsigned int cahnhilliard2d_0_dof_map_2_0::num_facet_dofs() const
6833
/// Return the number of dofs associated with each cell entity of dimension d
6834
unsigned int cahnhilliard2d_0_dof_map_2_0::num_entity_dofs(unsigned int d) const
6836
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6839
/// Tabulate the local-to-global mapping of dofs on a cell
6840
void cahnhilliard2d_0_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
6842
const ufc::cell& c) const
6844
dofs[0] = c.entity_indices[0][0];
6845
dofs[1] = c.entity_indices[0][1];
6846
dofs[2] = c.entity_indices[0][2];
6849
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6850
void cahnhilliard2d_0_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
6851
unsigned int facet) const
6870
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6871
void cahnhilliard2d_0_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
6872
unsigned int d, unsigned int i) const
6874
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6877
/// Tabulate the coordinates of all dofs on a cell
6878
void cahnhilliard2d_0_dof_map_2_0::tabulate_coordinates(double** coordinates,
6879
const ufc::cell& c) const
6881
const double * const * x = c.coordinates;
6882
coordinates[0][0] = x[0][0];
6883
coordinates[0][1] = x[0][1];
6884
coordinates[1][0] = x[1][0];
6885
coordinates[1][1] = x[1][1];
6886
coordinates[2][0] = x[2][0];
6887
coordinates[2][1] = x[2][1];
6890
/// Return the number of sub dof maps (for a mixed element)
6891
unsigned int cahnhilliard2d_0_dof_map_2_0::num_sub_dof_maps() const
6896
/// Create a new dof_map for sub dof map i (for a mixed element)
6897
ufc::dof_map* cahnhilliard2d_0_dof_map_2_0::create_sub_dof_map(unsigned int i) const
6899
return new cahnhilliard2d_0_dof_map_2_0();
6904
cahnhilliard2d_0_dof_map_2_1::cahnhilliard2d_0_dof_map_2_1() : ufc::dof_map()
6906
__global_dimension = 0;
6910
cahnhilliard2d_0_dof_map_2_1::~cahnhilliard2d_0_dof_map_2_1()
6915
/// Return a string identifying the dof map
6916
const char* cahnhilliard2d_0_dof_map_2_1::signature() const
6918
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6921
/// Return true iff mesh entities of topological dimension d are needed
6922
bool cahnhilliard2d_0_dof_map_2_1::needs_mesh_entities(unsigned int d) const
6939
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6940
bool cahnhilliard2d_0_dof_map_2_1::init_mesh(const ufc::mesh& m)
6942
__global_dimension = m.num_entities[0];
6946
/// Initialize dof map for given cell
6947
void cahnhilliard2d_0_dof_map_2_1::init_cell(const ufc::mesh& m,
6953
/// Finish initialization of dof map for cells
6954
void cahnhilliard2d_0_dof_map_2_1::init_cell_finalize()
6959
/// Return the dimension of the global finite element function space
6960
unsigned int cahnhilliard2d_0_dof_map_2_1::global_dimension() const
6962
return __global_dimension;
6965
/// Return the dimension of the local finite element function space for a cell
6966
unsigned int cahnhilliard2d_0_dof_map_2_1::local_dimension(const ufc::cell& c) const
6971
/// Return the maximum dimension of the local finite element function space
6972
unsigned int cahnhilliard2d_0_dof_map_2_1::max_local_dimension() const
6977
// Return the geometric dimension of the coordinates this dof map provides
6978
unsigned int cahnhilliard2d_0_dof_map_2_1::geometric_dimension() const
6983
/// Return the number of dofs on each cell facet
6984
unsigned int cahnhilliard2d_0_dof_map_2_1::num_facet_dofs() const
6989
/// Return the number of dofs associated with each cell entity of dimension d
6990
unsigned int cahnhilliard2d_0_dof_map_2_1::num_entity_dofs(unsigned int d) const
6992
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6995
/// Tabulate the local-to-global mapping of dofs on a cell
6996
void cahnhilliard2d_0_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
6998
const ufc::cell& c) const
7000
dofs[0] = c.entity_indices[0][0];
7001
dofs[1] = c.entity_indices[0][1];
7002
dofs[2] = c.entity_indices[0][2];
7005
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7006
void cahnhilliard2d_0_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
7007
unsigned int facet) const
7026
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7027
void cahnhilliard2d_0_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
7028
unsigned int d, unsigned int i) const
7030
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7033
/// Tabulate the coordinates of all dofs on a cell
7034
void cahnhilliard2d_0_dof_map_2_1::tabulate_coordinates(double** coordinates,
7035
const ufc::cell& c) const
7037
const double * const * x = c.coordinates;
7038
coordinates[0][0] = x[0][0];
7039
coordinates[0][1] = x[0][1];
7040
coordinates[1][0] = x[1][0];
7041
coordinates[1][1] = x[1][1];
7042
coordinates[2][0] = x[2][0];
7043
coordinates[2][1] = x[2][1];
7046
/// Return the number of sub dof maps (for a mixed element)
7047
unsigned int cahnhilliard2d_0_dof_map_2_1::num_sub_dof_maps() const
7052
/// Create a new dof_map for sub dof map i (for a mixed element)
7053
ufc::dof_map* cahnhilliard2d_0_dof_map_2_1::create_sub_dof_map(unsigned int i) const
7055
return new cahnhilliard2d_0_dof_map_2_1();
7060
cahnhilliard2d_0_dof_map_2::cahnhilliard2d_0_dof_map_2() : ufc::dof_map()
7062
__global_dimension = 0;
7066
cahnhilliard2d_0_dof_map_2::~cahnhilliard2d_0_dof_map_2()
7071
/// Return a string identifying the dof map
7072
const char* cahnhilliard2d_0_dof_map_2::signature() const
7074
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
7077
/// Return true iff mesh entities of topological dimension d are needed
7078
bool cahnhilliard2d_0_dof_map_2::needs_mesh_entities(unsigned int d) const
7095
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7096
bool cahnhilliard2d_0_dof_map_2::init_mesh(const ufc::mesh& m)
7098
__global_dimension = 2*m.num_entities[0];
7102
/// Initialize dof map for given cell
7103
void cahnhilliard2d_0_dof_map_2::init_cell(const ufc::mesh& m,
7109
/// Finish initialization of dof map for cells
7110
void cahnhilliard2d_0_dof_map_2::init_cell_finalize()
7115
/// Return the dimension of the global finite element function space
7116
unsigned int cahnhilliard2d_0_dof_map_2::global_dimension() const
7118
return __global_dimension;
7121
/// Return the dimension of the local finite element function space for a cell
7122
unsigned int cahnhilliard2d_0_dof_map_2::local_dimension(const ufc::cell& c) const
7127
/// Return the maximum dimension of the local finite element function space
7128
unsigned int cahnhilliard2d_0_dof_map_2::max_local_dimension() const
7133
// Return the geometric dimension of the coordinates this dof map provides
7134
unsigned int cahnhilliard2d_0_dof_map_2::geometric_dimension() const
7139
/// Return the number of dofs on each cell facet
7140
unsigned int cahnhilliard2d_0_dof_map_2::num_facet_dofs() const
7145
/// Return the number of dofs associated with each cell entity of dimension d
7146
unsigned int cahnhilliard2d_0_dof_map_2::num_entity_dofs(unsigned int d) const
7148
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7151
/// Tabulate the local-to-global mapping of dofs on a cell
7152
void cahnhilliard2d_0_dof_map_2::tabulate_dofs(unsigned int* dofs,
7154
const ufc::cell& c) const
7156
dofs[0] = c.entity_indices[0][0];
7157
dofs[1] = c.entity_indices[0][1];
7158
dofs[2] = c.entity_indices[0][2];
7159
unsigned int offset = m.num_entities[0];
7160
dofs[3] = offset + c.entity_indices[0][0];
7161
dofs[4] = offset + c.entity_indices[0][1];
7162
dofs[5] = offset + c.entity_indices[0][2];
7165
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7166
void cahnhilliard2d_0_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
7167
unsigned int facet) const
7192
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7193
void cahnhilliard2d_0_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
7194
unsigned int d, unsigned int i) const
7196
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7199
/// Tabulate the coordinates of all dofs on a cell
7200
void cahnhilliard2d_0_dof_map_2::tabulate_coordinates(double** coordinates,
7201
const ufc::cell& c) const
7203
const double * const * x = c.coordinates;
7204
coordinates[0][0] = x[0][0];
7205
coordinates[0][1] = x[0][1];
7206
coordinates[1][0] = x[1][0];
7207
coordinates[1][1] = x[1][1];
7208
coordinates[2][0] = x[2][0];
7209
coordinates[2][1] = x[2][1];
7210
coordinates[3][0] = x[0][0];
7211
coordinates[3][1] = x[0][1];
7212
coordinates[4][0] = x[1][0];
7213
coordinates[4][1] = x[1][1];
7214
coordinates[5][0] = x[2][0];
7215
coordinates[5][1] = x[2][1];
7218
/// Return the number of sub dof maps (for a mixed element)
7219
unsigned int cahnhilliard2d_0_dof_map_2::num_sub_dof_maps() const
7224
/// Create a new dof_map for sub dof map i (for a mixed element)
7225
ufc::dof_map* cahnhilliard2d_0_dof_map_2::create_sub_dof_map(unsigned int i) const
7230
return new cahnhilliard2d_0_dof_map_2_0();
7233
return new cahnhilliard2d_0_dof_map_2_1();
7241
cahnhilliard2d_0_dof_map_3::cahnhilliard2d_0_dof_map_3() : ufc::dof_map()
7243
__global_dimension = 0;
7247
cahnhilliard2d_0_dof_map_3::~cahnhilliard2d_0_dof_map_3()
7252
/// Return a string identifying the dof map
7253
const char* cahnhilliard2d_0_dof_map_3::signature() const
7255
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7258
/// Return true iff mesh entities of topological dimension d are needed
7259
bool cahnhilliard2d_0_dof_map_3::needs_mesh_entities(unsigned int d) const
7276
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7277
bool cahnhilliard2d_0_dof_map_3::init_mesh(const ufc::mesh& m)
7279
__global_dimension = m.num_entities[2];
7283
/// Initialize dof map for given cell
7284
void cahnhilliard2d_0_dof_map_3::init_cell(const ufc::mesh& m,
7290
/// Finish initialization of dof map for cells
7291
void cahnhilliard2d_0_dof_map_3::init_cell_finalize()
7296
/// Return the dimension of the global finite element function space
7297
unsigned int cahnhilliard2d_0_dof_map_3::global_dimension() const
7299
return __global_dimension;
7302
/// Return the dimension of the local finite element function space for a cell
7303
unsigned int cahnhilliard2d_0_dof_map_3::local_dimension(const ufc::cell& c) const
7308
/// Return the maximum dimension of the local finite element function space
7309
unsigned int cahnhilliard2d_0_dof_map_3::max_local_dimension() const
7314
// Return the geometric dimension of the coordinates this dof map provides
7315
unsigned int cahnhilliard2d_0_dof_map_3::geometric_dimension() const
7320
/// Return the number of dofs on each cell facet
7321
unsigned int cahnhilliard2d_0_dof_map_3::num_facet_dofs() const
7326
/// Return the number of dofs associated with each cell entity of dimension d
7327
unsigned int cahnhilliard2d_0_dof_map_3::num_entity_dofs(unsigned int d) const
7329
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7332
/// Tabulate the local-to-global mapping of dofs on a cell
7333
void cahnhilliard2d_0_dof_map_3::tabulate_dofs(unsigned int* dofs,
7335
const ufc::cell& c) const
7337
dofs[0] = c.entity_indices[2][0];
7340
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7341
void cahnhilliard2d_0_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
7342
unsigned int facet) const
7358
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7359
void cahnhilliard2d_0_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
7360
unsigned int d, unsigned int i) const
7362
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7365
/// Tabulate the coordinates of all dofs on a cell
7366
void cahnhilliard2d_0_dof_map_3::tabulate_coordinates(double** coordinates,
7367
const ufc::cell& c) const
7369
const double * const * x = c.coordinates;
7370
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7371
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7374
/// Return the number of sub dof maps (for a mixed element)
7375
unsigned int cahnhilliard2d_0_dof_map_3::num_sub_dof_maps() const
7380
/// Create a new dof_map for sub dof map i (for a mixed element)
7381
ufc::dof_map* cahnhilliard2d_0_dof_map_3::create_sub_dof_map(unsigned int i) const
7383
return new cahnhilliard2d_0_dof_map_3();
7388
cahnhilliard2d_0_dof_map_4::cahnhilliard2d_0_dof_map_4() : ufc::dof_map()
7390
__global_dimension = 0;
7394
cahnhilliard2d_0_dof_map_4::~cahnhilliard2d_0_dof_map_4()
7399
/// Return a string identifying the dof map
7400
const char* cahnhilliard2d_0_dof_map_4::signature() const
7402
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7405
/// Return true iff mesh entities of topological dimension d are needed
7406
bool cahnhilliard2d_0_dof_map_4::needs_mesh_entities(unsigned int d) const
7423
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7424
bool cahnhilliard2d_0_dof_map_4::init_mesh(const ufc::mesh& m)
7426
__global_dimension = m.num_entities[2];
7430
/// Initialize dof map for given cell
7431
void cahnhilliard2d_0_dof_map_4::init_cell(const ufc::mesh& m,
7437
/// Finish initialization of dof map for cells
7438
void cahnhilliard2d_0_dof_map_4::init_cell_finalize()
7443
/// Return the dimension of the global finite element function space
7444
unsigned int cahnhilliard2d_0_dof_map_4::global_dimension() const
7446
return __global_dimension;
7449
/// Return the dimension of the local finite element function space for a cell
7450
unsigned int cahnhilliard2d_0_dof_map_4::local_dimension(const ufc::cell& c) const
7455
/// Return the maximum dimension of the local finite element function space
7456
unsigned int cahnhilliard2d_0_dof_map_4::max_local_dimension() const
7461
// Return the geometric dimension of the coordinates this dof map provides
7462
unsigned int cahnhilliard2d_0_dof_map_4::geometric_dimension() const
7467
/// Return the number of dofs on each cell facet
7468
unsigned int cahnhilliard2d_0_dof_map_4::num_facet_dofs() const
7473
/// Return the number of dofs associated with each cell entity of dimension d
7474
unsigned int cahnhilliard2d_0_dof_map_4::num_entity_dofs(unsigned int d) const
7476
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7479
/// Tabulate the local-to-global mapping of dofs on a cell
7480
void cahnhilliard2d_0_dof_map_4::tabulate_dofs(unsigned int* dofs,
7482
const ufc::cell& c) const
7484
dofs[0] = c.entity_indices[2][0];
7487
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7488
void cahnhilliard2d_0_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
7489
unsigned int facet) const
7505
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7506
void cahnhilliard2d_0_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
7507
unsigned int d, unsigned int i) const
7509
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7512
/// Tabulate the coordinates of all dofs on a cell
7513
void cahnhilliard2d_0_dof_map_4::tabulate_coordinates(double** coordinates,
7514
const ufc::cell& c) const
7516
const double * const * x = c.coordinates;
7517
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7518
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7521
/// Return the number of sub dof maps (for a mixed element)
7522
unsigned int cahnhilliard2d_0_dof_map_4::num_sub_dof_maps() const
7527
/// Create a new dof_map for sub dof map i (for a mixed element)
7528
ufc::dof_map* cahnhilliard2d_0_dof_map_4::create_sub_dof_map(unsigned int i) const
7530
return new cahnhilliard2d_0_dof_map_4();
7535
cahnhilliard2d_0_dof_map_5::cahnhilliard2d_0_dof_map_5() : ufc::dof_map()
7537
__global_dimension = 0;
7541
cahnhilliard2d_0_dof_map_5::~cahnhilliard2d_0_dof_map_5()
7546
/// Return a string identifying the dof map
7547
const char* cahnhilliard2d_0_dof_map_5::signature() const
7549
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7552
/// Return true iff mesh entities of topological dimension d are needed
7553
bool cahnhilliard2d_0_dof_map_5::needs_mesh_entities(unsigned int d) const
7570
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7571
bool cahnhilliard2d_0_dof_map_5::init_mesh(const ufc::mesh& m)
7573
__global_dimension = m.num_entities[2];
7577
/// Initialize dof map for given cell
7578
void cahnhilliard2d_0_dof_map_5::init_cell(const ufc::mesh& m,
7584
/// Finish initialization of dof map for cells
7585
void cahnhilliard2d_0_dof_map_5::init_cell_finalize()
7590
/// Return the dimension of the global finite element function space
7591
unsigned int cahnhilliard2d_0_dof_map_5::global_dimension() const
7593
return __global_dimension;
7596
/// Return the dimension of the local finite element function space for a cell
7597
unsigned int cahnhilliard2d_0_dof_map_5::local_dimension(const ufc::cell& c) const
7602
/// Return the maximum dimension of the local finite element function space
7603
unsigned int cahnhilliard2d_0_dof_map_5::max_local_dimension() const
7608
// Return the geometric dimension of the coordinates this dof map provides
7609
unsigned int cahnhilliard2d_0_dof_map_5::geometric_dimension() const
7614
/// Return the number of dofs on each cell facet
7615
unsigned int cahnhilliard2d_0_dof_map_5::num_facet_dofs() const
7620
/// Return the number of dofs associated with each cell entity of dimension d
7621
unsigned int cahnhilliard2d_0_dof_map_5::num_entity_dofs(unsigned int d) const
7623
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7626
/// Tabulate the local-to-global mapping of dofs on a cell
7627
void cahnhilliard2d_0_dof_map_5::tabulate_dofs(unsigned int* dofs,
7629
const ufc::cell& c) const
7631
dofs[0] = c.entity_indices[2][0];
7634
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7635
void cahnhilliard2d_0_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
7636
unsigned int facet) const
7652
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7653
void cahnhilliard2d_0_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
7654
unsigned int d, unsigned int i) const
7656
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7659
/// Tabulate the coordinates of all dofs on a cell
7660
void cahnhilliard2d_0_dof_map_5::tabulate_coordinates(double** coordinates,
7661
const ufc::cell& c) const
7663
const double * const * x = c.coordinates;
7664
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7665
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7668
/// Return the number of sub dof maps (for a mixed element)
7669
unsigned int cahnhilliard2d_0_dof_map_5::num_sub_dof_maps() const
7674
/// Create a new dof_map for sub dof map i (for a mixed element)
7675
ufc::dof_map* cahnhilliard2d_0_dof_map_5::create_sub_dof_map(unsigned int i) const
7677
return new cahnhilliard2d_0_dof_map_5();
7682
cahnhilliard2d_0_dof_map_6::cahnhilliard2d_0_dof_map_6() : ufc::dof_map()
7684
__global_dimension = 0;
7688
cahnhilliard2d_0_dof_map_6::~cahnhilliard2d_0_dof_map_6()
7693
/// Return a string identifying the dof map
7694
const char* cahnhilliard2d_0_dof_map_6::signature() const
7696
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7699
/// Return true iff mesh entities of topological dimension d are needed
7700
bool cahnhilliard2d_0_dof_map_6::needs_mesh_entities(unsigned int d) const
7717
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7718
bool cahnhilliard2d_0_dof_map_6::init_mesh(const ufc::mesh& m)
7720
__global_dimension = m.num_entities[2];
7724
/// Initialize dof map for given cell
7725
void cahnhilliard2d_0_dof_map_6::init_cell(const ufc::mesh& m,
7731
/// Finish initialization of dof map for cells
7732
void cahnhilliard2d_0_dof_map_6::init_cell_finalize()
7737
/// Return the dimension of the global finite element function space
7738
unsigned int cahnhilliard2d_0_dof_map_6::global_dimension() const
7740
return __global_dimension;
7743
/// Return the dimension of the local finite element function space for a cell
7744
unsigned int cahnhilliard2d_0_dof_map_6::local_dimension(const ufc::cell& c) const
7749
/// Return the maximum dimension of the local finite element function space
7750
unsigned int cahnhilliard2d_0_dof_map_6::max_local_dimension() const
7755
// Return the geometric dimension of the coordinates this dof map provides
7756
unsigned int cahnhilliard2d_0_dof_map_6::geometric_dimension() const
7761
/// Return the number of dofs on each cell facet
7762
unsigned int cahnhilliard2d_0_dof_map_6::num_facet_dofs() const
7767
/// Return the number of dofs associated with each cell entity of dimension d
7768
unsigned int cahnhilliard2d_0_dof_map_6::num_entity_dofs(unsigned int d) const
7770
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7773
/// Tabulate the local-to-global mapping of dofs on a cell
7774
void cahnhilliard2d_0_dof_map_6::tabulate_dofs(unsigned int* dofs,
7776
const ufc::cell& c) const
7778
dofs[0] = c.entity_indices[2][0];
7781
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7782
void cahnhilliard2d_0_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
7783
unsigned int facet) const
7799
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7800
void cahnhilliard2d_0_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
7801
unsigned int d, unsigned int i) const
7803
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7806
/// Tabulate the coordinates of all dofs on a cell
7807
void cahnhilliard2d_0_dof_map_6::tabulate_coordinates(double** coordinates,
7808
const ufc::cell& c) const
7810
const double * const * x = c.coordinates;
7811
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7812
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7815
/// Return the number of sub dof maps (for a mixed element)
7816
unsigned int cahnhilliard2d_0_dof_map_6::num_sub_dof_maps() const
7821
/// Create a new dof_map for sub dof map i (for a mixed element)
7822
ufc::dof_map* cahnhilliard2d_0_dof_map_6::create_sub_dof_map(unsigned int i) const
7824
return new cahnhilliard2d_0_dof_map_6();
7829
cahnhilliard2d_0_cell_integral_0_quadrature::cahnhilliard2d_0_cell_integral_0_quadrature() : ufc::cell_integral()
7835
cahnhilliard2d_0_cell_integral_0_quadrature::~cahnhilliard2d_0_cell_integral_0_quadrature()
7761
7840
/// Tabulate the tensor for the contribution from a local cell
7762
void UFC_CahnHilliard2DBilinearForm_cell_integral_0::tabulate_tensor(double* A,
7841
void cahnhilliard2d_0_cell_integral_0_quadrature::tabulate_tensor(double* A,
7763
7842
const double * const * w,
7764
7843
const ufc::cell& c) const
7784
7863
// Set scale factor
7785
7864
const double det = std::abs(detJ);
7787
// Number of operations to compute element tensor = 377
7788
// Compute coefficients
7789
const double c3_2_0_0 = w[3][0];
7790
const double c4_2_1_0 = w[4][0];
7791
const double c2_3_0_0 = w[2][0];
7792
const double c0_3_1_3 = w[0][3];
7793
const double c0_3_1_4 = w[0][4];
7794
const double c0_3_1_5 = w[0][5];
7795
const double c0_3_2_3 = w[0][3];
7796
const double c0_3_2_4 = w[0][4];
7797
const double c0_3_2_5 = w[0][5];
7798
const double c2_4_0_0 = w[2][0];
7799
const double c0_4_1_3 = w[0][3];
7800
const double c0_4_1_4 = w[0][4];
7801
const double c0_4_1_5 = w[0][5];
7802
const double c2_5_0_0 = w[2][0];
7803
const double c1_6_0_0 = w[1][0];
7805
// Compute geometry tensors
7806
// Number of operations to compute decalrations = 79
7807
const double G0_ = det;
7808
const double G2_0_0_0_0 = det*c3_2_0_0*c4_2_1_0*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
7809
const double G2_0_0_0_1 = det*c3_2_0_0*c4_2_1_0*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
7810
const double G2_0_0_1_0 = det*c3_2_0_0*c4_2_1_0*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
7811
const double G2_0_0_1_1 = det*c3_2_0_0*c4_2_1_0*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
7812
const double G3_0_3_3 = det*c2_3_0_0*c0_3_1_3*c0_3_2_3;
7813
const double G3_0_3_4 = det*c2_3_0_0*c0_3_1_3*c0_3_2_4;
7814
const double G3_0_3_5 = det*c2_3_0_0*c0_3_1_3*c0_3_2_5;
7815
const double G3_0_4_3 = det*c2_3_0_0*c0_3_1_4*c0_3_2_3;
7816
const double G3_0_4_4 = det*c2_3_0_0*c0_3_1_4*c0_3_2_4;
7817
const double G3_0_4_5 = det*c2_3_0_0*c0_3_1_4*c0_3_2_5;
7818
const double G3_0_5_3 = det*c2_3_0_0*c0_3_1_5*c0_3_2_3;
7819
const double G3_0_5_4 = det*c2_3_0_0*c0_3_1_5*c0_3_2_4;
7820
const double G3_0_5_5 = det*c2_3_0_0*c0_3_1_5*c0_3_2_5;
7821
const double G4_0_3 = det*c2_4_0_0*c0_4_1_3;
7822
const double G4_0_4 = det*c2_4_0_0*c0_4_1_4;
7823
const double G4_0_5 = det*c2_4_0_0*c0_4_1_5;
7824
const double G5_0 = det*c2_5_0_0;
7825
const double G6_0_0_0 = det*c1_6_0_0*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
7826
const double G6_0_0_1 = det*c1_6_0_0*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
7827
const double G6_0_1_0 = det*c1_6_0_0*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
7828
const double G6_0_1_1 = det*c1_6_0_0*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
7830
// Compute element tensor
7831
// Number of operations to compute tensor = 298
7832
A[0] = 0.0833333333333332*G0_;
7833
A[1] = 0.0416666666666666*G0_;
7834
A[2] = 0.0416666666666666*G0_;
7835
A[3] = -0.4*G3_0_3_3 - 0.0999999999999999*G3_0_3_4 - 0.0999999999999999*G3_0_3_5 - 0.0999999999999999*G3_0_4_3 - 0.0666666666666666*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0999999999999999*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0666666666666666*G3_0_5_5 + 0.599999999999999*G4_0_3 + 0.2*G4_0_4 + 0.2*G4_0_5 - 0.166666666666666*G5_0 - 0.5*G6_0_0_0 - 0.5*G6_0_0_1 - 0.5*G6_0_1_0 - 0.5*G6_0_1_1;
7836
A[4] = -0.0999999999999999*G3_0_3_3 - 0.0666666666666666*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0666666666666666*G3_0_4_3 - 0.0999999999999999*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0333333333333333*G3_0_5_5 + 0.2*G4_0_3 + 0.2*G4_0_4 + 0.0999999999999998*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_0_0 + 0.5*G6_0_1_0;
7837
A[5] = -0.1*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0666666666666666*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0333333333333333*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0666666666666666*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0999999999999999*G3_0_5_5 + 0.2*G4_0_3 + 0.0999999999999998*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_0_1 + 0.5*G6_0_1_1;
7838
A[6] = 0.0416666666666666*G0_;
7839
A[7] = 0.0833333333333332*G0_;
7840
A[8] = 0.0416666666666666*G0_;
7841
A[9] = -0.0999999999999999*G3_0_3_3 - 0.0666666666666666*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0666666666666666*G3_0_4_3 - 0.0999999999999999*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0333333333333333*G3_0_5_5 + 0.2*G4_0_3 + 0.2*G4_0_4 + 0.0999999999999998*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_0_0 + 0.5*G6_0_0_1;
7842
A[10] = -0.0666666666666666*G3_0_3_3 - 0.0999999999999999*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0999999999999999*G3_0_4_3 - 0.4*G3_0_4_4 - 0.0999999999999999*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0999999999999999*G3_0_5_4 - 0.0666666666666666*G3_0_5_5 + 0.2*G4_0_3 + 0.599999999999999*G4_0_4 + 0.2*G4_0_5 - 0.166666666666666*G5_0 - 0.5*G6_0_0_0;
7843
A[11] = -0.0333333333333333*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.1*G3_0_4_4 - 0.0666666666666666*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0666666666666666*G3_0_5_4 - 0.1*G3_0_5_5 + 0.0999999999999998*G4_0_3 + 0.2*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 - 0.5*G6_0_0_1;
7844
A[12] = 0.0416666666666666*G0_;
7845
A[13] = 0.0416666666666666*G0_;
7846
A[14] = 0.0833333333333332*G0_;
7847
A[15] = -0.0999999999999999*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0666666666666666*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0333333333333333*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0666666666666666*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0999999999999999*G3_0_5_5 + 0.2*G4_0_3 + 0.0999999999999998*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_1_0 + 0.5*G6_0_1_1;
7848
A[16] = -0.0333333333333333*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0999999999999999*G3_0_4_4 - 0.0666666666666666*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0666666666666666*G3_0_5_4 - 0.1*G3_0_5_5 + 0.0999999999999998*G4_0_3 + 0.2*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 - 0.5*G6_0_1_0;
7849
A[17] = -0.0666666666666666*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0999999999999999*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0666666666666666*G3_0_4_4 - 0.1*G3_0_4_5 - 0.0999999999999999*G3_0_5_3 - 0.0999999999999999*G3_0_5_4 - 0.4*G3_0_5_5 + 0.2*G4_0_3 + 0.2*G4_0_4 + 0.599999999999999*G4_0_5 - 0.166666666666666*G5_0 - 0.5*G6_0_1_1;
7850
A[18] = 0.5*G2_0_0_0_0 + 0.5*G2_0_0_0_1 + 0.5*G2_0_0_1_0 + 0.5*G2_0_0_1_1;
7851
A[19] = -0.5*G2_0_0_0_0 - 0.5*G2_0_0_1_0;
7852
A[20] = -0.5*G2_0_0_0_1 - 0.5*G2_0_0_1_1;
7853
A[21] = 0.0833333333333332*G0_;
7854
A[22] = 0.0416666666666666*G0_;
7855
A[23] = 0.0416666666666666*G0_;
7856
A[24] = -0.5*G2_0_0_0_0 - 0.5*G2_0_0_0_1;
7857
A[25] = 0.5*G2_0_0_0_0;
7858
A[26] = 0.5*G2_0_0_0_1;
7859
A[27] = 0.0416666666666666*G0_;
7860
A[28] = 0.0833333333333332*G0_;
7861
A[29] = 0.0416666666666666*G0_;
7862
A[30] = -0.5*G2_0_0_1_0 - 0.5*G2_0_0_1_1;
7863
A[31] = 0.5*G2_0_0_1_0;
7864
A[32] = 0.5*G2_0_0_1_1;
7865
A[33] = 0.0416666666666666*G0_;
7866
A[34] = 0.0416666666666666*G0_;
7867
A[35] = 0.0833333333333332*G0_;
7871
UFC_CahnHilliard2DBilinearForm::UFC_CahnHilliard2DBilinearForm() : ufc::form()
7877
UFC_CahnHilliard2DBilinearForm::~UFC_CahnHilliard2DBilinearForm()
7867
// Array of quadrature weights
7868
static const double W9[9] = {0.0558144204830443, 0.063678085099885, 0.0193963833059595, 0.0893030727728709, 0.101884936159816, 0.0310342132895351, 0.0558144204830443, 0.063678085099885, 0.0193963833059595};
7869
// Quadrature points on the UFC reference element: (0.102717654809626, 0.088587959512704), (0.0665540678391645, 0.409466864440735), (0.0239311322870806, 0.787659461760847), (0.455706020243648, 0.088587959512704), (0.295266567779633, 0.409466864440735), (0.106170269119576, 0.787659461760847), (0.80869438567767, 0.088587959512704), (0.523979067720101, 0.409466864440735), (0.188409405952072, 0.787659461760847)
7871
// Value of basis functions at quadrature points.
7872
static const double FE0_C1_D01[9][2] = \
7883
// Array of non-zero columns
7884
static const unsigned int nzc0[2] = {3, 5};
7885
// Array of non-zero columns
7886
static const unsigned int nzc1[2] = {3, 4};
7887
// Array of non-zero columns
7888
static const unsigned int nzc2[2] = {0, 1};
7889
// Array of non-zero columns
7890
static const unsigned int nzc3[2] = {0, 2};
7891
static const double FE0_C1[9][3] = \
7892
{{0.80869438567767, 0.102717654809626, 0.088587959512704},
7893
{0.523979067720101, 0.0665540678391645, 0.409466864440735},
7894
{0.188409405952072, 0.0239311322870807, 0.787659461760847},
7895
{0.455706020243648, 0.455706020243648, 0.088587959512704},
7896
{0.295266567779633, 0.295266567779633, 0.409466864440735},
7897
{0.106170269119576, 0.106170269119577, 0.787659461760847},
7898
{0.102717654809626, 0.80869438567767, 0.088587959512704},
7899
{0.0665540678391645, 0.523979067720101, 0.409466864440735},
7900
{0.0239311322870807, 0.188409405952072, 0.787659461760847}};
7902
// Array of non-zero columns
7903
static const unsigned int nzc4[3] = {3, 4, 5};
7904
// Array of non-zero columns
7905
static const unsigned int nzc5[3] = {0, 1, 2};
7907
// Number of operations to compute geometry constants: 39
7908
const double G0 = -det*w[1][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
7909
const double G1 = det*w[3][0]*w[4][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
7910
const double G2 = -det*w[1][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
7911
const double G3 = -12*det*w[2][0];
7912
const double G4 = 12*det*w[2][0];
7913
const double G5 = -2*det*w[2][0];
7914
const double G6 = det*w[3][0]*w[4][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
7915
const double G7 = -det*w[1][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
7916
const double G8 = det*w[3][0]*w[4][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
7918
// Compute element tensor using UFL quadrature representation
7919
// Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
7920
// Total number of operations to compute element tensor: 1794
7922
// Loop quadrature points for integral
7923
// Number of operations to compute element tensor for following IP loop = 1755
7924
for (unsigned int ip = 0; ip < 9; ip++)
7927
// Function declarations
7930
// Total number of operations to compute function values = 6
7931
for (unsigned int r = 0; r < 3; r++)
7933
F0 += FE0_C1[ip][r]*w[0][nzc4[r]];
7934
}// end loop over 'r'
7936
// Number of operations to compute ip constants: 12
7937
// Number of operations: 1
7938
const double Gip0 = W9[ip]*det;
7940
// Number of operations: 1
7941
const double Gip1 = G0*W9[ip];
7943
// Number of operations: 1
7944
const double Gip2 = G1*W9[ip];
7946
// Number of operations: 1
7947
const double Gip3 = G2*W9[ip];
7949
// Number of operations: 5
7950
const double Gip4 = W9[ip]*(G5 + F0*(G4 + F0*G3));
7952
// Number of operations: 1
7953
const double Gip5 = G6*W9[ip];
7955
// Number of operations: 1
7956
const double Gip6 = G7*W9[ip];
7958
// Number of operations: 1
7959
const double Gip7 = G8*W9[ip];
7962
// Number of operations for primary indices = 81
7963
for (unsigned int j = 0; j < 3; j++)
7965
for (unsigned int k = 0; k < 3; k++)
7967
// Number of operations to compute entry = 3
7968
A[nzc4[j]*6 + nzc5[k]] += FE0_C1[ip][j]*FE0_C1[ip][k]*Gip0;
7969
// Number of operations to compute entry = 3
7970
A[nzc4[j]*6 + nzc4[k]] += FE0_C1[ip][j]*FE0_C1[ip][k]*Gip4;
7971
// Number of operations to compute entry = 3
7972
A[nzc5[j]*6 + nzc4[k]] += FE0_C1[ip][j]*FE0_C1[ip][k]*Gip0;
7973
}// end loop over 'k'
7974
}// end loop over 'j'
7976
// Number of operations for primary indices = 96
7977
for (unsigned int j = 0; j < 2; j++)
7979
for (unsigned int k = 0; k < 2; k++)
7981
// Number of operations to compute entry = 3
7982
A[nzc0[j]*6 + nzc1[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip1;
7983
// Number of operations to compute entry = 3
7984
A[nzc2[j]*6 + nzc3[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip2;
7985
// Number of operations to compute entry = 3
7986
A[nzc1[j]*6 + nzc1[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip3;
7987
// Number of operations to compute entry = 3
7988
A[nzc3[j]*6 + nzc2[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip2;
7989
// Number of operations to compute entry = 3
7990
A[nzc1[j]*6 + nzc0[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip1;
7991
// Number of operations to compute entry = 3
7992
A[nzc3[j]*6 + nzc3[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip5;
7993
// Number of operations to compute entry = 3
7994
A[nzc0[j]*6 + nzc0[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip6;
7995
// Number of operations to compute entry = 3
7996
A[nzc2[j]*6 + nzc2[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip7;
7997
}// end loop over 'k'
7998
}// end loop over 'j'
7999
}// end loop over 'ip'
8003
cahnhilliard2d_0_cell_integral_0::cahnhilliard2d_0_cell_integral_0() : ufc::cell_integral()
8009
cahnhilliard2d_0_cell_integral_0::~cahnhilliard2d_0_cell_integral_0()
8014
/// Tabulate the tensor for the contribution from a local cell
8015
void cahnhilliard2d_0_cell_integral_0::tabulate_tensor(double* A,
8016
const double * const * w,
8017
const ufc::cell& c) const
8019
// Reset values of the element tensor block
8020
for (unsigned int j = 0; j < 36; j++)
8023
// Add all contributions to element tensor
8024
integral_0_quadrature.tabulate_tensor(A, w, c);
8028
cahnhilliard2d_form_0::cahnhilliard2d_form_0() : ufc::form()
8034
cahnhilliard2d_form_0::~cahnhilliard2d_form_0()
7882
8039
/// Return a string identifying the form
7883
const char* UFC_CahnHilliard2DBilinearForm::signature() const
8040
const char* cahnhilliard2d_form_0::signature() const
7885
return " | vi0[0, 1, 2, 3, 4, 5][b0[0, 1]]*vi1[0, 1, 2, 3, 4, 5][b0[0, 1]]*dX(0) + w3_a0[0]w4_a1[0](dXa2[0, 1]/dxb0[0, 1])(dXa3[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa2[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*((d/dXa3[0, 1])va1[0])*vi1[0, 1, 2, 3, 4, 5][0]*dX(0) + w3_a0[0]w4_a1[0](dXa2[0, 1]/dxb0[0, 1])(dXa3[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa2[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*va1[0]*((d/dXa3[0, 1])vi1[0, 1, 2, 3, 4, 5][0])*dX(0) + -12.0w2_a0[0]w0_a1[0, 1, 2, 3, 4, 5]w0_a2[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*va1[0, 1, 2, 3, 4, 5][1]*va2[0, 1, 2, 3, 4, 5][1]*vi1[0, 1, 2, 3, 4, 5][1]*dX(0) + 12.0w2_a0[0]w0_a1[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*va1[0, 1, 2, 3, 4, 5][1]*vi1[0, 1, 2, 3, 4, 5][1]*dX(0) + -2.0w2_a0[0] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*vi1[0, 1, 2, 3, 4, 5][1]*dX(0) + -w1_a0[0](dXa1[0, 1]/dxb0[0, 1])(dXa2[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa1[0, 1])vi0[0, 1, 2, 3, 4, 5][0])*((d/dXa2[0, 1])vi1[0, 1, 2, 3, 4, 5][1])*dX(0)";
8042
return "Form([Integral(Sum(Sum(Product(Constant(Cell('triangle', 1, Space(2)), 3), IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(Product(Constant(Cell('triangle', 1, Space(2)), 4), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2}))), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Sum(Product(IntValue(-1, (), (), {}), Product(Constant(Cell('triangle', 1, Space(2)), 1), IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((FixedIndex(1),), {})), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((Index(4),), {Index(4): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(1),), {})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(4),), {Index(4): 2}))), MultiIndex((Index(4),), {Index(4): 2})))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2}))), Product(IntValue(-1, (), (), {}), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Constant(Cell('triangle', 1, Space(2)), 2), Sum(Product(IntValue(-1, (), (), {}), Sum(Product(Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(IntValue(-1, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))), Sum(Product(Product(IntValue(-1, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Product(Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))), Product(Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Sum(Product(Product(IntValue(-1, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))))))))))))), Measure('cell', 0, None))])";
7888
8045
/// Return the rank of the global tensor (r)
7889
unsigned int UFC_CahnHilliard2DBilinearForm::rank() const
8046
unsigned int cahnhilliard2d_form_0::rank() const
7894
8051
/// Return the number of coefficients (n)
7895
unsigned int UFC_CahnHilliard2DBilinearForm::num_coefficients() const
8052
unsigned int cahnhilliard2d_form_0::num_coefficients() const
7900
8057
/// Return the number of cell integrals
7901
unsigned int UFC_CahnHilliard2DBilinearForm::num_cell_integrals() const
8058
unsigned int cahnhilliard2d_form_0::num_cell_integrals() const
7906
8063
/// Return the number of exterior facet integrals
7907
unsigned int UFC_CahnHilliard2DBilinearForm::num_exterior_facet_integrals() const
8064
unsigned int cahnhilliard2d_form_0::num_exterior_facet_integrals() const
7912
8069
/// Return the number of interior facet integrals
7913
unsigned int UFC_CahnHilliard2DBilinearForm::num_interior_facet_integrals() const
8070
unsigned int cahnhilliard2d_form_0::num_interior_facet_integrals() const
7918
8075
/// Create a new finite element for argument function i
7919
ufc::finite_element* UFC_CahnHilliard2DBilinearForm::create_finite_element(unsigned int i) const
8076
ufc::finite_element* cahnhilliard2d_form_0::create_finite_element(unsigned int i) const
7924
return new UFC_CahnHilliard2DBilinearForm_finite_element_0();
8081
return new cahnhilliard2d_0_finite_element_0();
7927
return new UFC_CahnHilliard2DBilinearForm_finite_element_1();
8084
return new cahnhilliard2d_0_finite_element_1();
7930
return new UFC_CahnHilliard2DBilinearForm_finite_element_2();
8087
return new cahnhilliard2d_0_finite_element_2();
7933
return new UFC_CahnHilliard2DBilinearForm_finite_element_3();
8090
return new cahnhilliard2d_0_finite_element_3();
7936
return new UFC_CahnHilliard2DBilinearForm_finite_element_4();
8093
return new cahnhilliard2d_0_finite_element_4();
7939
return new UFC_CahnHilliard2DBilinearForm_finite_element_5();
8096
return new cahnhilliard2d_0_finite_element_5();
7942
return new UFC_CahnHilliard2DBilinearForm_finite_element_6();
8099
return new cahnhilliard2d_0_finite_element_6();
7948
8105
/// Create a new dof map for argument function i
7949
ufc::dof_map* UFC_CahnHilliard2DBilinearForm::create_dof_map(unsigned int i) const
8106
ufc::dof_map* cahnhilliard2d_form_0::create_dof_map(unsigned int i) const
7954
return new UFC_CahnHilliard2DBilinearForm_dof_map_0();
8111
return new cahnhilliard2d_0_dof_map_0();
7957
return new UFC_CahnHilliard2DBilinearForm_dof_map_1();
8114
return new cahnhilliard2d_0_dof_map_1();
7960
return new UFC_CahnHilliard2DBilinearForm_dof_map_2();
8117
return new cahnhilliard2d_0_dof_map_2();
7963
return new UFC_CahnHilliard2DBilinearForm_dof_map_3();
8120
return new cahnhilliard2d_0_dof_map_3();
7966
return new UFC_CahnHilliard2DBilinearForm_dof_map_4();
8123
return new cahnhilliard2d_0_dof_map_4();
7969
return new UFC_CahnHilliard2DBilinearForm_dof_map_5();
8126
return new cahnhilliard2d_0_dof_map_5();
7972
return new UFC_CahnHilliard2DBilinearForm_dof_map_6();
8129
return new cahnhilliard2d_0_dof_map_6();
7978
8135
/// Create a new cell integral on sub domain i
7979
ufc::cell_integral* UFC_CahnHilliard2DBilinearForm::create_cell_integral(unsigned int i) const
8136
ufc::cell_integral* cahnhilliard2d_form_0::create_cell_integral(unsigned int i) const
7981
return new UFC_CahnHilliard2DBilinearForm_cell_integral_0();
8138
return new cahnhilliard2d_0_cell_integral_0();
7984
8141
/// Create a new exterior facet integral on sub domain i
7985
ufc::exterior_facet_integral* UFC_CahnHilliard2DBilinearForm::create_exterior_facet_integral(unsigned int i) const
8142
ufc::exterior_facet_integral* cahnhilliard2d_form_0::create_exterior_facet_integral(unsigned int i) const
7990
8147
/// Create a new interior facet integral on sub domain i
7991
ufc::interior_facet_integral* UFC_CahnHilliard2DBilinearForm::create_interior_facet_integral(unsigned int i) const
7998
UFC_CahnHilliard2DLinearForm_finite_element_0_0::UFC_CahnHilliard2DLinearForm_finite_element_0_0() : ufc::finite_element()
8004
UFC_CahnHilliard2DLinearForm_finite_element_0_0::~UFC_CahnHilliard2DLinearForm_finite_element_0_0()
8009
/// Return a string identifying the finite element
8010
const char* UFC_CahnHilliard2DLinearForm_finite_element_0_0::signature() const
8012
return "FiniteElement('Lagrange', 'triangle', 1)";
8015
/// Return the cell shape
8016
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_0_0::cell_shape() const
8018
return ufc::triangle;
8021
/// Return the dimension of the finite element function space
8022
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::space_dimension() const
8027
/// Return the rank of the value space
8028
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::value_rank() const
8033
/// Return the dimension of the value space for axis i
8034
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::value_dimension(unsigned int i) const
8039
/// Evaluate basis function i at given point in cell
8040
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis(unsigned int i,
8042
const double* coordinates,
8043
const ufc::cell& c) const
8045
// Extract vertex coordinates
8046
const double * const * element_coordinates = c.coordinates;
8048
// Compute Jacobian of affine map from reference cell
8049
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8050
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8051
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8052
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8054
// Compute determinant of Jacobian
8055
const double detJ = J_00*J_11 - J_01*J_10;
8057
// Compute inverse of Jacobian
8059
// Get coordinates and map to the reference (UFC) element
8060
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8061
element_coordinates[0][0]*element_coordinates[2][1] +\
8062
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8063
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8064
element_coordinates[1][0]*element_coordinates[0][1] -\
8065
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8067
// Map coordinates to the reference square
8068
if (std::abs(y - 1.0) < 1e-14)
8071
x = 2.0 *x/(1.0 - y) - 1.0;
8077
// Map degree of freedom to element degree of freedom
8078
const unsigned int dof = i;
8080
// Generate scalings
8081
const double scalings_y_0 = 1;
8082
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8084
// Compute psitilde_a
8085
const double psitilde_a_0 = 1;
8086
const double psitilde_a_1 = x;
8088
// Compute psitilde_bs
8089
const double psitilde_bs_0_0 = 1;
8090
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8091
const double psitilde_bs_1_0 = 1;
8093
// Compute basisvalues
8094
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8095
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8096
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8098
// Table(s) of coefficients
8099
const static double coefficients0[3][3] = \
8100
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8101
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8102
{0.471404520791032, 0, 0.333333333333333}};
8104
// Extract relevant coefficients
8105
const double coeff0_0 = coefficients0[dof][0];
8106
const double coeff0_1 = coefficients0[dof][1];
8107
const double coeff0_2 = coefficients0[dof][2];
8110
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8113
/// Evaluate all basis functions at given point in cell
8114
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis_all(double* values,
8115
const double* coordinates,
8116
const ufc::cell& c) const
8118
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8121
/// Evaluate order n derivatives of basis function i at given point in cell
8122
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis_derivatives(unsigned int i,
8125
const double* coordinates,
8126
const ufc::cell& c) const
8128
// Extract vertex coordinates
8129
const double * const * element_coordinates = c.coordinates;
8131
// Compute Jacobian of affine map from reference cell
8132
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8133
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8134
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8135
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8137
// Compute determinant of Jacobian
8138
const double detJ = J_00*J_11 - J_01*J_10;
8140
// Compute inverse of Jacobian
8142
// Get coordinates and map to the reference (UFC) element
8143
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8144
element_coordinates[0][0]*element_coordinates[2][1] +\
8145
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8146
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8147
element_coordinates[1][0]*element_coordinates[0][1] -\
8148
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8150
// Map coordinates to the reference square
8151
if (std::abs(y - 1.0) < 1e-14)
8154
x = 2.0 *x/(1.0 - y) - 1.0;
8157
// Compute number of derivatives
8158
unsigned int num_derivatives = 1;
8160
for (unsigned int j = 0; j < n; j++)
8161
num_derivatives *= 2;
8164
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8165
unsigned int **combinations = new unsigned int *[num_derivatives];
8167
for (unsigned int j = 0; j < num_derivatives; j++)
8169
combinations[j] = new unsigned int [n];
8170
for (unsigned int k = 0; k < n; k++)
8171
combinations[j][k] = 0;
8174
// Generate combinations of derivatives
8175
for (unsigned int row = 1; row < num_derivatives; row++)
8177
for (unsigned int num = 0; num < row; num++)
8179
for (unsigned int col = n-1; col+1 > 0; col--)
8181
if (combinations[row][col] + 1 > 1)
8182
combinations[row][col] = 0;
8185
combinations[row][col] += 1;
8192
// Compute inverse of Jacobian
8193
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8195
// Declare transformation matrix
8196
// Declare pointer to two dimensional array and initialise
8197
double **transform = new double *[num_derivatives];
8199
for (unsigned int j = 0; j < num_derivatives; j++)
8201
transform[j] = new double [num_derivatives];
8202
for (unsigned int k = 0; k < num_derivatives; k++)
8203
transform[j][k] = 1;
8206
// Construct transformation matrix
8207
for (unsigned int row = 0; row < num_derivatives; row++)
8209
for (unsigned int col = 0; col < num_derivatives; col++)
8211
for (unsigned int k = 0; k < n; k++)
8212
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8217
for (unsigned int j = 0; j < 1*num_derivatives; j++)
8220
// Map degree of freedom to element degree of freedom
8221
const unsigned int dof = i;
8223
// Generate scalings
8224
const double scalings_y_0 = 1;
8225
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8227
// Compute psitilde_a
8228
const double psitilde_a_0 = 1;
8229
const double psitilde_a_1 = x;
8231
// Compute psitilde_bs
8232
const double psitilde_bs_0_0 = 1;
8233
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8234
const double psitilde_bs_1_0 = 1;
8236
// Compute basisvalues
8237
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8238
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8239
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8241
// Table(s) of coefficients
8242
const static double coefficients0[3][3] = \
8243
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8244
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8245
{0.471404520791032, 0, 0.333333333333333}};
8247
// Interesting (new) part
8248
// Tables of derivatives of the polynomial base (transpose)
8249
const static double dmats0[3][3] = \
8251
{4.89897948556636, 0, 0},
8254
const static double dmats1[3][3] = \
8256
{2.44948974278318, 0, 0},
8257
{4.24264068711928, 0, 0}};
8259
// Compute reference derivatives
8260
// Declare pointer to array of derivatives on FIAT element
8261
double *derivatives = new double [num_derivatives];
8263
// Declare coefficients
8264
double coeff0_0 = 0;
8265
double coeff0_1 = 0;
8266
double coeff0_2 = 0;
8268
// Declare new coefficients
8269
double new_coeff0_0 = 0;
8270
double new_coeff0_1 = 0;
8271
double new_coeff0_2 = 0;
8273
// Loop possible derivatives
8274
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8276
// Get values from coefficients array
8277
new_coeff0_0 = coefficients0[dof][0];
8278
new_coeff0_1 = coefficients0[dof][1];
8279
new_coeff0_2 = coefficients0[dof][2];
8281
// Loop derivative order
8282
for (unsigned int j = 0; j < n; j++)
8284
// Update old coefficients
8285
coeff0_0 = new_coeff0_0;
8286
coeff0_1 = new_coeff0_1;
8287
coeff0_2 = new_coeff0_2;
8289
if(combinations[deriv_num][j] == 0)
8291
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
8292
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
8293
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
8295
if(combinations[deriv_num][j] == 1)
8297
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
8298
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
8299
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
8303
// Compute derivatives on reference element as dot product of coefficients and basisvalues
8304
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
8307
// Transform derivatives back to physical element
8308
for (unsigned int row = 0; row < num_derivatives; row++)
8310
for (unsigned int col = 0; col < num_derivatives; col++)
8312
values[row] += transform[row][col]*derivatives[col];
8315
// Delete pointer to array of derivatives on FIAT element
8316
delete [] derivatives;
8318
// Delete pointer to array of combinations of derivatives and transform
8319
for (unsigned int row = 0; row < num_derivatives; row++)
8321
delete [] combinations[row];
8322
delete [] transform[row];
8325
delete [] combinations;
8326
delete [] transform;
8329
/// Evaluate order n derivatives of all basis functions at given point in cell
8330
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
8332
const double* coordinates,
8333
const ufc::cell& c) const
8335
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8338
/// Evaluate linear functional for dof i on the function f
8339
double UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_dof(unsigned int i,
8340
const ufc::function& f,
8341
const ufc::cell& c) const
8343
// The reference points, direction and weights:
8344
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
8345
const static double W[3][1] = {{1}, {1}, {1}};
8346
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
8348
const double * const * x = c.coordinates;
8349
double result = 0.0;
8350
// Iterate over the points:
8351
// Evaluate basis functions for affine mapping
8352
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
8353
const double w1 = X[i][0][0];
8354
const double w2 = X[i][0][1];
8356
// Compute affine mapping y = F(X)
8358
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
8359
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
8361
// Evaluate function at physical points
8363
f.evaluate(values, y, c);
8365
// Map function values using appropriate mapping
8366
// Affine map: Do nothing
8368
// Note that we do not map the weights (yet).
8370
// Take directional components
8371
for(int k = 0; k < 1; k++)
8372
result += values[k]*D[i][0][k];
8373
// Multiply by weights
8379
/// Evaluate linear functionals for all dofs on the function f
8380
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_dofs(double* values,
8381
const ufc::function& f,
8382
const ufc::cell& c) const
8384
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8387
/// Interpolate vertex values from dof values
8388
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
8389
const double* dof_values,
8390
const ufc::cell& c) const
8392
// Evaluate at vertices and use affine mapping
8393
vertex_values[0] = dof_values[0];
8394
vertex_values[1] = dof_values[1];
8395
vertex_values[2] = dof_values[2];
8398
/// Return the number of sub elements (for a mixed element)
8399
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::num_sub_elements() const
8404
/// Create a new finite element for sub element i (for a mixed element)
8405
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_0_0::create_sub_element(unsigned int i) const
8407
return new UFC_CahnHilliard2DLinearForm_finite_element_0_0();
8412
UFC_CahnHilliard2DLinearForm_finite_element_0_1::UFC_CahnHilliard2DLinearForm_finite_element_0_1() : ufc::finite_element()
8418
UFC_CahnHilliard2DLinearForm_finite_element_0_1::~UFC_CahnHilliard2DLinearForm_finite_element_0_1()
8423
/// Return a string identifying the finite element
8424
const char* UFC_CahnHilliard2DLinearForm_finite_element_0_1::signature() const
8426
return "FiniteElement('Lagrange', 'triangle', 1)";
8429
/// Return the cell shape
8430
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_0_1::cell_shape() const
8432
return ufc::triangle;
8435
/// Return the dimension of the finite element function space
8436
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::space_dimension() const
8441
/// Return the rank of the value space
8442
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::value_rank() const
8447
/// Return the dimension of the value space for axis i
8448
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::value_dimension(unsigned int i) const
8453
/// Evaluate basis function i at given point in cell
8454
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis(unsigned int i,
8456
const double* coordinates,
8457
const ufc::cell& c) const
8459
// Extract vertex coordinates
8460
const double * const * element_coordinates = c.coordinates;
8462
// Compute Jacobian of affine map from reference cell
8463
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8464
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8465
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8466
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8468
// Compute determinant of Jacobian
8469
const double detJ = J_00*J_11 - J_01*J_10;
8471
// Compute inverse of Jacobian
8473
// Get coordinates and map to the reference (UFC) element
8474
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8475
element_coordinates[0][0]*element_coordinates[2][1] +\
8476
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8477
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8478
element_coordinates[1][0]*element_coordinates[0][1] -\
8479
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8481
// Map coordinates to the reference square
8482
if (std::abs(y - 1.0) < 1e-14)
8485
x = 2.0 *x/(1.0 - y) - 1.0;
8491
// Map degree of freedom to element degree of freedom
8492
const unsigned int dof = i;
8494
// Generate scalings
8495
const double scalings_y_0 = 1;
8496
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8498
// Compute psitilde_a
8499
const double psitilde_a_0 = 1;
8500
const double psitilde_a_1 = x;
8502
// Compute psitilde_bs
8503
const double psitilde_bs_0_0 = 1;
8504
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8505
const double psitilde_bs_1_0 = 1;
8507
// Compute basisvalues
8508
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8509
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8510
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8512
// Table(s) of coefficients
8513
const static double coefficients0[3][3] = \
8514
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8515
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8516
{0.471404520791032, 0, 0.333333333333333}};
8518
// Extract relevant coefficients
8519
const double coeff0_0 = coefficients0[dof][0];
8520
const double coeff0_1 = coefficients0[dof][1];
8521
const double coeff0_2 = coefficients0[dof][2];
8524
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8527
/// Evaluate all basis functions at given point in cell
8528
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis_all(double* values,
8529
const double* coordinates,
8530
const ufc::cell& c) const
8532
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8535
/// Evaluate order n derivatives of basis function i at given point in cell
8536
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
8539
const double* coordinates,
8540
const ufc::cell& c) const
8542
// Extract vertex coordinates
8543
const double * const * element_coordinates = c.coordinates;
8545
// Compute Jacobian of affine map from reference cell
8546
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8547
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8548
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8549
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8551
// Compute determinant of Jacobian
8552
const double detJ = J_00*J_11 - J_01*J_10;
8554
// Compute inverse of Jacobian
8556
// Get coordinates and map to the reference (UFC) element
8557
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8558
element_coordinates[0][0]*element_coordinates[2][1] +\
8559
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8560
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8561
element_coordinates[1][0]*element_coordinates[0][1] -\
8562
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8564
// Map coordinates to the reference square
8565
if (std::abs(y - 1.0) < 1e-14)
8568
x = 2.0 *x/(1.0 - y) - 1.0;
8571
// Compute number of derivatives
8572
unsigned int num_derivatives = 1;
8574
for (unsigned int j = 0; j < n; j++)
8575
num_derivatives *= 2;
8578
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8579
unsigned int **combinations = new unsigned int *[num_derivatives];
8581
for (unsigned int j = 0; j < num_derivatives; j++)
8583
combinations[j] = new unsigned int [n];
8584
for (unsigned int k = 0; k < n; k++)
8585
combinations[j][k] = 0;
8588
// Generate combinations of derivatives
8589
for (unsigned int row = 1; row < num_derivatives; row++)
8591
for (unsigned int num = 0; num < row; num++)
8593
for (unsigned int col = n-1; col+1 > 0; col--)
8595
if (combinations[row][col] + 1 > 1)
8596
combinations[row][col] = 0;
8599
combinations[row][col] += 1;
8606
// Compute inverse of Jacobian
8607
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8609
// Declare transformation matrix
8610
// Declare pointer to two dimensional array and initialise
8611
double **transform = new double *[num_derivatives];
8613
for (unsigned int j = 0; j < num_derivatives; j++)
8615
transform[j] = new double [num_derivatives];
8616
for (unsigned int k = 0; k < num_derivatives; k++)
8617
transform[j][k] = 1;
8620
// Construct transformation matrix
8621
for (unsigned int row = 0; row < num_derivatives; row++)
8623
for (unsigned int col = 0; col < num_derivatives; col++)
8625
for (unsigned int k = 0; k < n; k++)
8626
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8631
for (unsigned int j = 0; j < 1*num_derivatives; j++)
8634
// Map degree of freedom to element degree of freedom
8635
const unsigned int dof = i;
8637
// Generate scalings
8638
const double scalings_y_0 = 1;
8639
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8641
// Compute psitilde_a
8642
const double psitilde_a_0 = 1;
8643
const double psitilde_a_1 = x;
8645
// Compute psitilde_bs
8646
const double psitilde_bs_0_0 = 1;
8647
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8648
const double psitilde_bs_1_0 = 1;
8650
// Compute basisvalues
8651
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8652
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8653
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8655
// Table(s) of coefficients
8656
const static double coefficients0[3][3] = \
8657
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8658
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8659
{0.471404520791032, 0, 0.333333333333333}};
8661
// Interesting (new) part
8662
// Tables of derivatives of the polynomial base (transpose)
8663
const static double dmats0[3][3] = \
8665
{4.89897948556636, 0, 0},
8668
const static double dmats1[3][3] = \
8670
{2.44948974278318, 0, 0},
8671
{4.24264068711928, 0, 0}};
8673
// Compute reference derivatives
8674
// Declare pointer to array of derivatives on FIAT element
8675
double *derivatives = new double [num_derivatives];
8677
// Declare coefficients
8678
double coeff0_0 = 0;
8679
double coeff0_1 = 0;
8680
double coeff0_2 = 0;
8682
// Declare new coefficients
8683
double new_coeff0_0 = 0;
8684
double new_coeff0_1 = 0;
8685
double new_coeff0_2 = 0;
8687
// Loop possible derivatives
8688
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8690
// Get values from coefficients array
8691
new_coeff0_0 = coefficients0[dof][0];
8692
new_coeff0_1 = coefficients0[dof][1];
8693
new_coeff0_2 = coefficients0[dof][2];
8695
// Loop derivative order
8696
for (unsigned int j = 0; j < n; j++)
8698
// Update old coefficients
8699
coeff0_0 = new_coeff0_0;
8700
coeff0_1 = new_coeff0_1;
8701
coeff0_2 = new_coeff0_2;
8703
if(combinations[deriv_num][j] == 0)
8705
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
8706
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
8707
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
8709
if(combinations[deriv_num][j] == 1)
8711
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
8712
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
8713
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
8717
// Compute derivatives on reference element as dot product of coefficients and basisvalues
8718
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
8721
// Transform derivatives back to physical element
8722
for (unsigned int row = 0; row < num_derivatives; row++)
8724
for (unsigned int col = 0; col < num_derivatives; col++)
8726
values[row] += transform[row][col]*derivatives[col];
8729
// Delete pointer to array of derivatives on FIAT element
8730
delete [] derivatives;
8732
// Delete pointer to array of combinations of derivatives and transform
8733
for (unsigned int row = 0; row < num_derivatives; row++)
8735
delete [] combinations[row];
8736
delete [] transform[row];
8739
delete [] combinations;
8740
delete [] transform;
8743
/// Evaluate order n derivatives of all basis functions at given point in cell
8744
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
8746
const double* coordinates,
8747
const ufc::cell& c) const
8749
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8752
/// Evaluate linear functional for dof i on the function f
8753
double UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_dof(unsigned int i,
8754
const ufc::function& f,
8755
const ufc::cell& c) const
8757
// The reference points, direction and weights:
8758
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
8759
const static double W[3][1] = {{1}, {1}, {1}};
8760
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
8762
const double * const * x = c.coordinates;
8763
double result = 0.0;
8764
// Iterate over the points:
8765
// Evaluate basis functions for affine mapping
8766
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
8767
const double w1 = X[i][0][0];
8768
const double w2 = X[i][0][1];
8770
// Compute affine mapping y = F(X)
8772
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
8773
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
8775
// Evaluate function at physical points
8777
f.evaluate(values, y, c);
8779
// Map function values using appropriate mapping
8780
// Affine map: Do nothing
8782
// Note that we do not map the weights (yet).
8784
// Take directional components
8785
for(int k = 0; k < 1; k++)
8786
result += values[k]*D[i][0][k];
8787
// Multiply by weights
8793
/// Evaluate linear functionals for all dofs on the function f
8794
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_dofs(double* values,
8795
const ufc::function& f,
8796
const ufc::cell& c) const
8798
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8801
/// Interpolate vertex values from dof values
8802
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
8803
const double* dof_values,
8804
const ufc::cell& c) const
8806
// Evaluate at vertices and use affine mapping
8807
vertex_values[0] = dof_values[0];
8808
vertex_values[1] = dof_values[1];
8809
vertex_values[2] = dof_values[2];
8812
/// Return the number of sub elements (for a mixed element)
8813
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::num_sub_elements() const
8818
/// Create a new finite element for sub element i (for a mixed element)
8819
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_0_1::create_sub_element(unsigned int i) const
8821
return new UFC_CahnHilliard2DLinearForm_finite_element_0_1();
8826
UFC_CahnHilliard2DLinearForm_finite_element_0::UFC_CahnHilliard2DLinearForm_finite_element_0() : ufc::finite_element()
8832
UFC_CahnHilliard2DLinearForm_finite_element_0::~UFC_CahnHilliard2DLinearForm_finite_element_0()
8837
/// Return a string identifying the finite element
8838
const char* UFC_CahnHilliard2DLinearForm_finite_element_0::signature() const
8840
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
8843
/// Return the cell shape
8844
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_0::cell_shape() const
8846
return ufc::triangle;
8849
/// Return the dimension of the finite element function space
8850
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::space_dimension() const
8855
/// Return the rank of the value space
8856
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::value_rank() const
8861
/// Return the dimension of the value space for axis i
8862
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::value_dimension(unsigned int i) const
8867
/// Evaluate basis function i at given point in cell
8868
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis(unsigned int i,
8870
const double* coordinates,
8871
const ufc::cell& c) const
8873
// Extract vertex coordinates
8874
const double * const * element_coordinates = c.coordinates;
8876
// Compute Jacobian of affine map from reference cell
8877
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8878
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8879
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8880
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8882
// Compute determinant of Jacobian
8883
const double detJ = J_00*J_11 - J_01*J_10;
8885
// Compute inverse of Jacobian
8887
// Get coordinates and map to the reference (UFC) element
8888
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8889
element_coordinates[0][0]*element_coordinates[2][1] +\
8890
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8891
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8892
element_coordinates[1][0]*element_coordinates[0][1] -\
8893
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8895
// Map coordinates to the reference square
8896
if (std::abs(y - 1.0) < 1e-14)
8899
x = 2.0 *x/(1.0 - y) - 1.0;
8906
if (0 <= i && i <= 2)
8908
// Map degree of freedom to element degree of freedom
8909
const unsigned int dof = i;
8911
// Generate scalings
8912
const double scalings_y_0 = 1;
8913
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8915
// Compute psitilde_a
8916
const double psitilde_a_0 = 1;
8917
const double psitilde_a_1 = x;
8919
// Compute psitilde_bs
8920
const double psitilde_bs_0_0 = 1;
8921
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8922
const double psitilde_bs_1_0 = 1;
8924
// Compute basisvalues
8925
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8926
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8927
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8929
// Table(s) of coefficients
8930
const static double coefficients0[3][3] = \
8931
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8932
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8933
{0.471404520791032, 0, 0.333333333333333}};
8935
// Extract relevant coefficients
8936
const double coeff0_0 = coefficients0[dof][0];
8937
const double coeff0_1 = coefficients0[dof][1];
8938
const double coeff0_2 = coefficients0[dof][2];
8941
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8944
if (3 <= i && i <= 5)
8946
// Map degree of freedom to element degree of freedom
8947
const unsigned int dof = i - 3;
8949
// Generate scalings
8950
const double scalings_y_0 = 1;
8951
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8953
// Compute psitilde_a
8954
const double psitilde_a_0 = 1;
8955
const double psitilde_a_1 = x;
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_1_0 = 1;
8962
// Compute basisvalues
8963
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8964
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8965
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8967
// Table(s) of coefficients
8968
const static double coefficients0[3][3] = \
8969
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8970
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8971
{0.471404520791032, 0, 0.333333333333333}};
8973
// Extract relevant coefficients
8974
const double coeff0_0 = coefficients0[dof][0];
8975
const double coeff0_1 = coefficients0[dof][1];
8976
const double coeff0_2 = coefficients0[dof][2];
8979
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8984
/// Evaluate all basis functions at given point in cell
8985
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis_all(double* values,
8986
const double* coordinates,
8987
const ufc::cell& c) const
8989
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8992
/// Evaluate order n derivatives of basis function i at given point in cell
8993
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis_derivatives(unsigned int i,
8996
const double* coordinates,
8997
const ufc::cell& c) const
8999
// Extract vertex coordinates
9000
const double * const * element_coordinates = c.coordinates;
9002
// Compute Jacobian of affine map from reference cell
9003
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9004
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9005
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9006
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9008
// Compute determinant of Jacobian
9009
const double detJ = J_00*J_11 - J_01*J_10;
9011
// Compute inverse of Jacobian
9013
// Get coordinates and map to the reference (UFC) element
9014
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9015
element_coordinates[0][0]*element_coordinates[2][1] +\
9016
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9017
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9018
element_coordinates[1][0]*element_coordinates[0][1] -\
9019
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9021
// Map coordinates to the reference square
9022
if (std::abs(y - 1.0) < 1e-14)
9025
x = 2.0 *x/(1.0 - y) - 1.0;
9028
// Compute number of derivatives
9029
unsigned int num_derivatives = 1;
9031
for (unsigned int j = 0; j < n; j++)
9032
num_derivatives *= 2;
9035
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9036
unsigned int **combinations = new unsigned int *[num_derivatives];
9038
for (unsigned int j = 0; j < num_derivatives; j++)
9040
combinations[j] = new unsigned int [n];
9041
for (unsigned int k = 0; k < n; k++)
9042
combinations[j][k] = 0;
9045
// Generate combinations of derivatives
9046
for (unsigned int row = 1; row < num_derivatives; row++)
9048
for (unsigned int num = 0; num < row; num++)
9050
for (unsigned int col = n-1; col+1 > 0; col--)
9052
if (combinations[row][col] + 1 > 1)
9053
combinations[row][col] = 0;
9056
combinations[row][col] += 1;
9063
// Compute inverse of Jacobian
9064
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
9066
// Declare transformation matrix
9067
// Declare pointer to two dimensional array and initialise
9068
double **transform = new double *[num_derivatives];
9070
for (unsigned int j = 0; j < num_derivatives; j++)
9072
transform[j] = new double [num_derivatives];
9073
for (unsigned int k = 0; k < num_derivatives; k++)
9074
transform[j][k] = 1;
9077
// Construct transformation matrix
9078
for (unsigned int row = 0; row < num_derivatives; row++)
9080
for (unsigned int col = 0; col < num_derivatives; col++)
9082
for (unsigned int k = 0; k < n; k++)
9083
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
9088
for (unsigned int j = 0; j < 2*num_derivatives; j++)
9091
if (0 <= i && i <= 2)
9093
// Map degree of freedom to element degree of freedom
9094
const unsigned int dof = i;
9096
// Generate scalings
9097
const double scalings_y_0 = 1;
9098
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9100
// Compute psitilde_a
9101
const double psitilde_a_0 = 1;
9102
const double psitilde_a_1 = x;
9104
// Compute psitilde_bs
9105
const double psitilde_bs_0_0 = 1;
9106
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9107
const double psitilde_bs_1_0 = 1;
9109
// Compute basisvalues
9110
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9111
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9112
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9114
// Table(s) of coefficients
9115
const static double coefficients0[3][3] = \
9116
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9117
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9118
{0.471404520791032, 0, 0.333333333333333}};
9120
// Interesting (new) part
9121
// Tables of derivatives of the polynomial base (transpose)
9122
const static double dmats0[3][3] = \
9124
{4.89897948556636, 0, 0},
9127
const static double dmats1[3][3] = \
9129
{2.44948974278318, 0, 0},
9130
{4.24264068711928, 0, 0}};
9132
// Compute reference derivatives
9133
// Declare pointer to array of derivatives on FIAT element
9134
double *derivatives = new double [num_derivatives];
9136
// Declare coefficients
9137
double coeff0_0 = 0;
9138
double coeff0_1 = 0;
9139
double coeff0_2 = 0;
9141
// Declare new coefficients
9142
double new_coeff0_0 = 0;
9143
double new_coeff0_1 = 0;
9144
double new_coeff0_2 = 0;
9146
// Loop possible derivatives
9147
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9149
// Get values from coefficients array
9150
new_coeff0_0 = coefficients0[dof][0];
9151
new_coeff0_1 = coefficients0[dof][1];
9152
new_coeff0_2 = coefficients0[dof][2];
9154
// Loop derivative order
9155
for (unsigned int j = 0; j < n; j++)
9157
// Update old coefficients
9158
coeff0_0 = new_coeff0_0;
9159
coeff0_1 = new_coeff0_1;
9160
coeff0_2 = new_coeff0_2;
9162
if(combinations[deriv_num][j] == 0)
9164
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9165
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9166
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9168
if(combinations[deriv_num][j] == 1)
9170
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9171
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9172
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9176
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9177
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9180
// Transform derivatives back to physical element
9181
for (unsigned int row = 0; row < num_derivatives; row++)
9183
for (unsigned int col = 0; col < num_derivatives; col++)
9185
values[row] += transform[row][col]*derivatives[col];
9188
// Delete pointer to array of derivatives on FIAT element
9189
delete [] derivatives;
9191
// Delete pointer to array of combinations of derivatives and transform
9192
for (unsigned int row = 0; row < num_derivatives; row++)
9194
delete [] combinations[row];
9195
delete [] transform[row];
9198
delete [] combinations;
9199
delete [] transform;
9202
if (3 <= i && i <= 5)
9204
// Map degree of freedom to element degree of freedom
9205
const unsigned int dof = i - 3;
9207
// Generate scalings
9208
const double scalings_y_0 = 1;
9209
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9211
// Compute psitilde_a
9212
const double psitilde_a_0 = 1;
9213
const double psitilde_a_1 = x;
9215
// Compute psitilde_bs
9216
const double psitilde_bs_0_0 = 1;
9217
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9218
const double psitilde_bs_1_0 = 1;
9220
// Compute basisvalues
9221
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9222
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9223
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9225
// Table(s) of coefficients
9226
const static double coefficients0[3][3] = \
9227
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9228
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9229
{0.471404520791032, 0, 0.333333333333333}};
9231
// Interesting (new) part
9232
// Tables of derivatives of the polynomial base (transpose)
9233
const static double dmats0[3][3] = \
9235
{4.89897948556636, 0, 0},
9238
const static double dmats1[3][3] = \
9240
{2.44948974278318, 0, 0},
9241
{4.24264068711928, 0, 0}};
9243
// Compute reference derivatives
9244
// Declare pointer to array of derivatives on FIAT element
9245
double *derivatives = new double [num_derivatives];
9247
// Declare coefficients
9248
double coeff0_0 = 0;
9249
double coeff0_1 = 0;
9250
double coeff0_2 = 0;
9252
// Declare new coefficients
9253
double new_coeff0_0 = 0;
9254
double new_coeff0_1 = 0;
9255
double new_coeff0_2 = 0;
9257
// Loop possible derivatives
9258
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9260
// Get values from coefficients array
9261
new_coeff0_0 = coefficients0[dof][0];
9262
new_coeff0_1 = coefficients0[dof][1];
9263
new_coeff0_2 = coefficients0[dof][2];
9265
// Loop derivative order
9266
for (unsigned int j = 0; j < n; j++)
9268
// Update old coefficients
9269
coeff0_0 = new_coeff0_0;
9270
coeff0_1 = new_coeff0_1;
9271
coeff0_2 = new_coeff0_2;
9273
if(combinations[deriv_num][j] == 0)
9275
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9276
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9277
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9279
if(combinations[deriv_num][j] == 1)
9281
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9282
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9283
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9287
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9288
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9291
// Transform derivatives back to physical element
9292
for (unsigned int row = 0; row < num_derivatives; row++)
9294
for (unsigned int col = 0; col < num_derivatives; col++)
9296
values[num_derivatives + row] += transform[row][col]*derivatives[col];
9299
// Delete pointer to array of derivatives on FIAT element
9300
delete [] derivatives;
9302
// Delete pointer to array of combinations of derivatives and transform
9303
for (unsigned int row = 0; row < num_derivatives; row++)
9305
delete [] combinations[row];
9306
delete [] transform[row];
9309
delete [] combinations;
9310
delete [] transform;
9315
/// Evaluate order n derivatives of all basis functions at given point in cell
9316
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
9318
const double* coordinates,
9319
const ufc::cell& c) const
9321
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9324
/// Evaluate linear functional for dof i on the function f
9325
double UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_dof(unsigned int i,
9326
const ufc::function& f,
9327
const ufc::cell& c) const
9329
// The reference points, direction and weights:
9330
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
9331
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
9332
const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
9334
const double * const * x = c.coordinates;
9335
double result = 0.0;
9336
// Iterate over the points:
9337
// Evaluate basis functions for affine mapping
9338
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9339
const double w1 = X[i][0][0];
9340
const double w2 = X[i][0][1];
9342
// Compute affine mapping y = F(X)
9344
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9345
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9347
// Evaluate function at physical points
9349
f.evaluate(values, y, c);
9351
// Map function values using appropriate mapping
9352
// Affine map: Do nothing
9354
// Note that we do not map the weights (yet).
9356
// Take directional components
9357
for(int k = 0; k < 2; k++)
9358
result += values[k]*D[i][0][k];
9359
// Multiply by weights
9365
/// Evaluate linear functionals for all dofs on the function f
9366
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_dofs(double* values,
9367
const ufc::function& f,
9368
const ufc::cell& c) const
9370
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9373
/// Interpolate vertex values from dof values
9374
void UFC_CahnHilliard2DLinearForm_finite_element_0::interpolate_vertex_values(double* vertex_values,
9375
const double* dof_values,
9376
const ufc::cell& c) const
9378
// Evaluate at vertices and use affine mapping
9379
vertex_values[0] = dof_values[0];
9380
vertex_values[2] = dof_values[1];
9381
vertex_values[4] = dof_values[2];
9382
// Evaluate at vertices and use affine mapping
9383
vertex_values[1] = dof_values[3];
9384
vertex_values[3] = dof_values[4];
9385
vertex_values[5] = dof_values[5];
9388
/// Return the number of sub elements (for a mixed element)
9389
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::num_sub_elements() const
9394
/// Create a new finite element for sub element i (for a mixed element)
9395
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_0::create_sub_element(unsigned int i) const
9400
return new UFC_CahnHilliard2DLinearForm_finite_element_0_0();
9403
return new UFC_CahnHilliard2DLinearForm_finite_element_0_1();
9411
UFC_CahnHilliard2DLinearForm_finite_element_1_0::UFC_CahnHilliard2DLinearForm_finite_element_1_0() : ufc::finite_element()
9417
UFC_CahnHilliard2DLinearForm_finite_element_1_0::~UFC_CahnHilliard2DLinearForm_finite_element_1_0()
9422
/// Return a string identifying the finite element
9423
const char* UFC_CahnHilliard2DLinearForm_finite_element_1_0::signature() const
9425
return "FiniteElement('Lagrange', 'triangle', 1)";
9428
/// Return the cell shape
9429
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_1_0::cell_shape() const
9431
return ufc::triangle;
9434
/// Return the dimension of the finite element function space
9435
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::space_dimension() const
9440
/// Return the rank of the value space
9441
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::value_rank() const
9446
/// Return the dimension of the value space for axis i
9447
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::value_dimension(unsigned int i) const
9452
/// Evaluate basis function i at given point in cell
9453
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis(unsigned int i,
9455
const double* coordinates,
9456
const ufc::cell& c) const
9458
// Extract vertex coordinates
9459
const double * const * element_coordinates = c.coordinates;
9461
// Compute Jacobian of affine map from reference cell
9462
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9463
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9464
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9465
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9467
// Compute determinant of Jacobian
9468
const double detJ = J_00*J_11 - J_01*J_10;
9470
// Compute inverse of Jacobian
9472
// Get coordinates and map to the reference (UFC) element
9473
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9474
element_coordinates[0][0]*element_coordinates[2][1] +\
9475
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9476
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9477
element_coordinates[1][0]*element_coordinates[0][1] -\
9478
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9480
// Map coordinates to the reference square
9481
if (std::abs(y - 1.0) < 1e-14)
9484
x = 2.0 *x/(1.0 - y) - 1.0;
9490
// Map degree of freedom to element degree of freedom
9491
const unsigned int dof = i;
9493
// Generate scalings
9494
const double scalings_y_0 = 1;
9495
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9497
// Compute psitilde_a
9498
const double psitilde_a_0 = 1;
9499
const double psitilde_a_1 = x;
9501
// Compute psitilde_bs
9502
const double psitilde_bs_0_0 = 1;
9503
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9504
const double psitilde_bs_1_0 = 1;
9506
// Compute basisvalues
9507
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9508
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9509
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9511
// Table(s) of coefficients
9512
const static double coefficients0[3][3] = \
9513
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9514
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9515
{0.471404520791032, 0, 0.333333333333333}};
9517
// Extract relevant coefficients
9518
const double coeff0_0 = coefficients0[dof][0];
9519
const double coeff0_1 = coefficients0[dof][1];
9520
const double coeff0_2 = coefficients0[dof][2];
9523
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9526
/// Evaluate all basis functions at given point in cell
9527
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis_all(double* values,
9528
const double* coordinates,
9529
const ufc::cell& c) const
9531
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9534
/// Evaluate order n derivatives of basis function i at given point in cell
9535
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
9538
const double* coordinates,
9539
const ufc::cell& c) const
9541
// Extract vertex coordinates
9542
const double * const * element_coordinates = c.coordinates;
9544
// Compute Jacobian of affine map from reference cell
9545
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9546
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9547
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9548
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9550
// Compute determinant of Jacobian
9551
const double detJ = J_00*J_11 - J_01*J_10;
9553
// Compute inverse of Jacobian
9555
// Get coordinates and map to the reference (UFC) element
9556
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9557
element_coordinates[0][0]*element_coordinates[2][1] +\
9558
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9559
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9560
element_coordinates[1][0]*element_coordinates[0][1] -\
9561
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9563
// Map coordinates to the reference square
9564
if (std::abs(y - 1.0) < 1e-14)
9567
x = 2.0 *x/(1.0 - y) - 1.0;
9570
// Compute number of derivatives
9571
unsigned int num_derivatives = 1;
9573
for (unsigned int j = 0; j < n; j++)
9574
num_derivatives *= 2;
9577
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9578
unsigned int **combinations = new unsigned int *[num_derivatives];
9580
for (unsigned int j = 0; j < num_derivatives; j++)
9582
combinations[j] = new unsigned int [n];
9583
for (unsigned int k = 0; k < n; k++)
9584
combinations[j][k] = 0;
9587
// Generate combinations of derivatives
9588
for (unsigned int row = 1; row < num_derivatives; row++)
9590
for (unsigned int num = 0; num < row; num++)
9592
for (unsigned int col = n-1; col+1 > 0; col--)
9594
if (combinations[row][col] + 1 > 1)
9595
combinations[row][col] = 0;
9598
combinations[row][col] += 1;
9605
// Compute inverse of Jacobian
9606
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
9608
// Declare transformation matrix
9609
// Declare pointer to two dimensional array and initialise
9610
double **transform = new double *[num_derivatives];
9612
for (unsigned int j = 0; j < num_derivatives; j++)
9614
transform[j] = new double [num_derivatives];
9615
for (unsigned int k = 0; k < num_derivatives; k++)
9616
transform[j][k] = 1;
9619
// Construct transformation matrix
9620
for (unsigned int row = 0; row < num_derivatives; row++)
9622
for (unsigned int col = 0; col < num_derivatives; col++)
9624
for (unsigned int k = 0; k < n; k++)
9625
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
9630
for (unsigned int j = 0; j < 1*num_derivatives; j++)
9633
// Map degree of freedom to element degree of freedom
9634
const unsigned int dof = i;
9636
// Generate scalings
9637
const double scalings_y_0 = 1;
9638
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9640
// Compute psitilde_a
9641
const double psitilde_a_0 = 1;
9642
const double psitilde_a_1 = x;
9644
// Compute psitilde_bs
9645
const double psitilde_bs_0_0 = 1;
9646
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9647
const double psitilde_bs_1_0 = 1;
9649
// Compute basisvalues
9650
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9651
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9652
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9654
// Table(s) of coefficients
9655
const static double coefficients0[3][3] = \
9656
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9657
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9658
{0.471404520791032, 0, 0.333333333333333}};
9660
// Interesting (new) part
9661
// Tables of derivatives of the polynomial base (transpose)
9662
const static double dmats0[3][3] = \
9664
{4.89897948556636, 0, 0},
9667
const static double dmats1[3][3] = \
9669
{2.44948974278318, 0, 0},
9670
{4.24264068711928, 0, 0}};
9672
// Compute reference derivatives
9673
// Declare pointer to array of derivatives on FIAT element
9674
double *derivatives = new double [num_derivatives];
9676
// Declare coefficients
9677
double coeff0_0 = 0;
9678
double coeff0_1 = 0;
9679
double coeff0_2 = 0;
9681
// Declare new coefficients
9682
double new_coeff0_0 = 0;
9683
double new_coeff0_1 = 0;
9684
double new_coeff0_2 = 0;
9686
// Loop possible derivatives
9687
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9689
// Get values from coefficients array
9690
new_coeff0_0 = coefficients0[dof][0];
9691
new_coeff0_1 = coefficients0[dof][1];
9692
new_coeff0_2 = coefficients0[dof][2];
9694
// Loop derivative order
9695
for (unsigned int j = 0; j < n; j++)
9697
// Update old coefficients
9698
coeff0_0 = new_coeff0_0;
9699
coeff0_1 = new_coeff0_1;
9700
coeff0_2 = new_coeff0_2;
9702
if(combinations[deriv_num][j] == 0)
9704
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9705
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9706
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9708
if(combinations[deriv_num][j] == 1)
9710
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9711
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9712
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9716
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9717
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9720
// Transform derivatives back to physical element
9721
for (unsigned int row = 0; row < num_derivatives; row++)
9723
for (unsigned int col = 0; col < num_derivatives; col++)
9725
values[row] += transform[row][col]*derivatives[col];
9728
// Delete pointer to array of derivatives on FIAT element
9729
delete [] derivatives;
9731
// Delete pointer to array of combinations of derivatives and transform
9732
for (unsigned int row = 0; row < num_derivatives; row++)
9734
delete [] combinations[row];
9735
delete [] transform[row];
9738
delete [] combinations;
9739
delete [] transform;
9742
/// Evaluate order n derivatives of all basis functions at given point in cell
9743
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
9745
const double* coordinates,
9746
const ufc::cell& c) const
9748
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9751
/// Evaluate linear functional for dof i on the function f
9752
double UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_dof(unsigned int i,
9753
const ufc::function& f,
9754
const ufc::cell& c) const
9756
// The reference points, direction and weights:
9757
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
9758
const static double W[3][1] = {{1}, {1}, {1}};
9759
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
9761
const double * const * x = c.coordinates;
9762
double result = 0.0;
9763
// Iterate over the points:
9764
// Evaluate basis functions for affine mapping
9765
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9766
const double w1 = X[i][0][0];
9767
const double w2 = X[i][0][1];
9769
// Compute affine mapping y = F(X)
9771
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9772
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9774
// Evaluate function at physical points
9776
f.evaluate(values, y, c);
9778
// Map function values using appropriate mapping
9779
// Affine map: Do nothing
9781
// Note that we do not map the weights (yet).
9783
// Take directional components
9784
for(int k = 0; k < 1; k++)
9785
result += values[k]*D[i][0][k];
9786
// Multiply by weights
9792
/// Evaluate linear functionals for all dofs on the function f
9793
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_dofs(double* values,
9794
const ufc::function& f,
9795
const ufc::cell& c) const
9797
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9800
/// Interpolate vertex values from dof values
9801
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
9802
const double* dof_values,
9803
const ufc::cell& c) const
9805
// Evaluate at vertices and use affine mapping
9806
vertex_values[0] = dof_values[0];
9807
vertex_values[1] = dof_values[1];
9808
vertex_values[2] = dof_values[2];
9811
/// Return the number of sub elements (for a mixed element)
9812
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::num_sub_elements() const
9817
/// Create a new finite element for sub element i (for a mixed element)
9818
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_1_0::create_sub_element(unsigned int i) const
9820
return new UFC_CahnHilliard2DLinearForm_finite_element_1_0();
9825
UFC_CahnHilliard2DLinearForm_finite_element_1_1::UFC_CahnHilliard2DLinearForm_finite_element_1_1() : ufc::finite_element()
9831
UFC_CahnHilliard2DLinearForm_finite_element_1_1::~UFC_CahnHilliard2DLinearForm_finite_element_1_1()
9836
/// Return a string identifying the finite element
9837
const char* UFC_CahnHilliard2DLinearForm_finite_element_1_1::signature() const
9839
return "FiniteElement('Lagrange', 'triangle', 1)";
9842
/// Return the cell shape
9843
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_1_1::cell_shape() const
9845
return ufc::triangle;
9848
/// Return the dimension of the finite element function space
9849
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::space_dimension() const
9854
/// Return the rank of the value space
9855
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::value_rank() const
9860
/// Return the dimension of the value space for axis i
9861
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::value_dimension(unsigned int i) const
9866
/// Evaluate basis function i at given point in cell
9867
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis(unsigned int i,
9869
const double* coordinates,
9870
const ufc::cell& c) const
9872
// Extract vertex coordinates
9873
const double * const * element_coordinates = c.coordinates;
9875
// Compute Jacobian of affine map from reference cell
9876
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9877
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9878
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9879
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9881
// Compute determinant of Jacobian
9882
const double detJ = J_00*J_11 - J_01*J_10;
9884
// Compute inverse of Jacobian
9886
// Get coordinates and map to the reference (UFC) element
9887
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9888
element_coordinates[0][0]*element_coordinates[2][1] +\
9889
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9890
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9891
element_coordinates[1][0]*element_coordinates[0][1] -\
9892
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9894
// Map coordinates to the reference square
9895
if (std::abs(y - 1.0) < 1e-14)
9898
x = 2.0 *x/(1.0 - y) - 1.0;
9904
// Map degree of freedom to element degree of freedom
9905
const unsigned int dof = i;
9907
// Generate scalings
9908
const double scalings_y_0 = 1;
9909
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9911
// Compute psitilde_a
9912
const double psitilde_a_0 = 1;
9913
const double psitilde_a_1 = x;
9915
// Compute psitilde_bs
9916
const double psitilde_bs_0_0 = 1;
9917
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9918
const double psitilde_bs_1_0 = 1;
9920
// Compute basisvalues
9921
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9922
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9923
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9925
// Table(s) of coefficients
9926
const static double coefficients0[3][3] = \
9927
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9928
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9929
{0.471404520791032, 0, 0.333333333333333}};
9931
// Extract relevant coefficients
9932
const double coeff0_0 = coefficients0[dof][0];
9933
const double coeff0_1 = coefficients0[dof][1];
9934
const double coeff0_2 = coefficients0[dof][2];
9937
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9940
/// Evaluate all basis functions at given point in cell
9941
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis_all(double* values,
9942
const double* coordinates,
9943
const ufc::cell& c) const
9945
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9948
/// Evaluate order n derivatives of basis function i at given point in cell
9949
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
9952
const double* coordinates,
9953
const ufc::cell& c) const
9955
// Extract vertex coordinates
9956
const double * const * element_coordinates = c.coordinates;
9958
// Compute Jacobian of affine map from reference cell
9959
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9960
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9961
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9962
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9964
// Compute determinant of Jacobian
9965
const double detJ = J_00*J_11 - J_01*J_10;
9967
// Compute inverse of Jacobian
9969
// Get coordinates and map to the reference (UFC) element
9970
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9971
element_coordinates[0][0]*element_coordinates[2][1] +\
9972
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9973
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9974
element_coordinates[1][0]*element_coordinates[0][1] -\
9975
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9977
// Map coordinates to the reference square
9978
if (std::abs(y - 1.0) < 1e-14)
9981
x = 2.0 *x/(1.0 - y) - 1.0;
9984
// Compute number of derivatives
9985
unsigned int num_derivatives = 1;
9987
for (unsigned int j = 0; j < n; j++)
9988
num_derivatives *= 2;
9991
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9992
unsigned int **combinations = new unsigned int *[num_derivatives];
9994
for (unsigned int j = 0; j < num_derivatives; j++)
9996
combinations[j] = new unsigned int [n];
9997
for (unsigned int k = 0; k < n; k++)
9998
combinations[j][k] = 0;
10001
// Generate combinations of derivatives
10002
for (unsigned int row = 1; row < num_derivatives; row++)
10004
for (unsigned int num = 0; num < row; num++)
10006
for (unsigned int col = n-1; col+1 > 0; col--)
10008
if (combinations[row][col] + 1 > 1)
10009
combinations[row][col] = 0;
10012
combinations[row][col] += 1;
10019
// Compute inverse of Jacobian
10020
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10022
// Declare transformation matrix
10023
// Declare pointer to two dimensional array and initialise
10024
double **transform = new double *[num_derivatives];
10026
for (unsigned int j = 0; j < num_derivatives; j++)
10028
transform[j] = new double [num_derivatives];
10029
for (unsigned int k = 0; k < num_derivatives; k++)
10030
transform[j][k] = 1;
10033
// Construct transformation matrix
10034
for (unsigned int row = 0; row < num_derivatives; row++)
10036
for (unsigned int col = 0; col < num_derivatives; col++)
10038
for (unsigned int k = 0; k < n; k++)
10039
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10044
for (unsigned int j = 0; j < 1*num_derivatives; j++)
10047
// Map degree of freedom to element degree of freedom
10048
const unsigned int dof = i;
10050
// Generate scalings
10051
const double scalings_y_0 = 1;
10052
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10054
// Compute psitilde_a
10055
const double psitilde_a_0 = 1;
10056
const double psitilde_a_1 = x;
10058
// Compute psitilde_bs
10059
const double psitilde_bs_0_0 = 1;
10060
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10061
const double psitilde_bs_1_0 = 1;
10063
// Compute basisvalues
10064
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10065
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10066
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10068
// Table(s) of coefficients
10069
const static double coefficients0[3][3] = \
10070
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10071
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10072
{0.471404520791032, 0, 0.333333333333333}};
10074
// Interesting (new) part
10075
// Tables of derivatives of the polynomial base (transpose)
10076
const static double dmats0[3][3] = \
10078
{4.89897948556636, 0, 0},
10081
const static double dmats1[3][3] = \
10083
{2.44948974278318, 0, 0},
10084
{4.24264068711928, 0, 0}};
10086
// Compute reference derivatives
10087
// Declare pointer to array of derivatives on FIAT element
10088
double *derivatives = new double [num_derivatives];
10090
// Declare coefficients
10091
double coeff0_0 = 0;
10092
double coeff0_1 = 0;
10093
double coeff0_2 = 0;
10095
// Declare new coefficients
10096
double new_coeff0_0 = 0;
10097
double new_coeff0_1 = 0;
10098
double new_coeff0_2 = 0;
10100
// Loop possible derivatives
10101
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10103
// Get values from coefficients array
10104
new_coeff0_0 = coefficients0[dof][0];
10105
new_coeff0_1 = coefficients0[dof][1];
10106
new_coeff0_2 = coefficients0[dof][2];
10108
// Loop derivative order
10109
for (unsigned int j = 0; j < n; j++)
10111
// Update old coefficients
10112
coeff0_0 = new_coeff0_0;
10113
coeff0_1 = new_coeff0_1;
10114
coeff0_2 = new_coeff0_2;
10116
if(combinations[deriv_num][j] == 0)
10118
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10119
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10120
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10122
if(combinations[deriv_num][j] == 1)
10124
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10125
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10126
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10130
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10131
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10134
// Transform derivatives back to physical element
10135
for (unsigned int row = 0; row < num_derivatives; row++)
10137
for (unsigned int col = 0; col < num_derivatives; col++)
10139
values[row] += transform[row][col]*derivatives[col];
10142
// Delete pointer to array of derivatives on FIAT element
10143
delete [] derivatives;
10145
// Delete pointer to array of combinations of derivatives and transform
10146
for (unsigned int row = 0; row < num_derivatives; row++)
10148
delete [] combinations[row];
10149
delete [] transform[row];
10152
delete [] combinations;
10153
delete [] transform;
10156
/// Evaluate order n derivatives of all basis functions at given point in cell
10157
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
10159
const double* coordinates,
10160
const ufc::cell& c) const
10162
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
10165
/// Evaluate linear functional for dof i on the function f
10166
double UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_dof(unsigned int i,
10167
const ufc::function& f,
10168
const ufc::cell& c) const
10170
// The reference points, direction and weights:
10171
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
10172
const static double W[3][1] = {{1}, {1}, {1}};
10173
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
10175
const double * const * x = c.coordinates;
10176
double result = 0.0;
10177
// Iterate over the points:
10178
// Evaluate basis functions for affine mapping
10179
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
10180
const double w1 = X[i][0][0];
10181
const double w2 = X[i][0][1];
10183
// Compute affine mapping y = F(X)
10185
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
10186
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
10188
// Evaluate function at physical points
10190
f.evaluate(values, y, c);
10192
// Map function values using appropriate mapping
10193
// Affine map: Do nothing
10195
// Note that we do not map the weights (yet).
10197
// Take directional components
10198
for(int k = 0; k < 1; k++)
10199
result += values[k]*D[i][0][k];
10200
// Multiply by weights
10206
/// Evaluate linear functionals for all dofs on the function f
10207
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_dofs(double* values,
10208
const ufc::function& f,
10209
const ufc::cell& c) const
10211
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10214
/// Interpolate vertex values from dof values
10215
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
10216
const double* dof_values,
10217
const ufc::cell& c) const
10219
// Evaluate at vertices and use affine mapping
10220
vertex_values[0] = dof_values[0];
10221
vertex_values[1] = dof_values[1];
10222
vertex_values[2] = dof_values[2];
10225
/// Return the number of sub elements (for a mixed element)
10226
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::num_sub_elements() const
10231
/// Create a new finite element for sub element i (for a mixed element)
10232
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_1_1::create_sub_element(unsigned int i) const
10234
return new UFC_CahnHilliard2DLinearForm_finite_element_1_1();
10239
UFC_CahnHilliard2DLinearForm_finite_element_1::UFC_CahnHilliard2DLinearForm_finite_element_1() : ufc::finite_element()
10245
UFC_CahnHilliard2DLinearForm_finite_element_1::~UFC_CahnHilliard2DLinearForm_finite_element_1()
10250
/// Return a string identifying the finite element
10251
const char* UFC_CahnHilliard2DLinearForm_finite_element_1::signature() const
10253
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
10256
/// Return the cell shape
10257
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_1::cell_shape() const
10259
return ufc::triangle;
10262
/// Return the dimension of the finite element function space
10263
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::space_dimension() const
10268
/// Return the rank of the value space
10269
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::value_rank() const
10274
/// Return the dimension of the value space for axis i
10275
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::value_dimension(unsigned int i) const
10280
/// Evaluate basis function i at given point in cell
10281
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis(unsigned int i,
10283
const double* coordinates,
10284
const ufc::cell& c) const
10286
// Extract vertex coordinates
10287
const double * const * element_coordinates = c.coordinates;
10289
// Compute Jacobian of affine map from reference cell
10290
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10291
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10292
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10293
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10295
// Compute determinant of Jacobian
10296
const double detJ = J_00*J_11 - J_01*J_10;
10298
// Compute inverse of Jacobian
10300
// Get coordinates and map to the reference (UFC) element
10301
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10302
element_coordinates[0][0]*element_coordinates[2][1] +\
10303
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10304
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10305
element_coordinates[1][0]*element_coordinates[0][1] -\
10306
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10308
// Map coordinates to the reference square
10309
if (std::abs(y - 1.0) < 1e-14)
10312
x = 2.0 *x/(1.0 - y) - 1.0;
10319
if (0 <= i && i <= 2)
10321
// Map degree of freedom to element degree of freedom
10322
const unsigned int dof = i;
10324
// Generate scalings
10325
const double scalings_y_0 = 1;
10326
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10328
// Compute psitilde_a
10329
const double psitilde_a_0 = 1;
10330
const double psitilde_a_1 = x;
10332
// Compute psitilde_bs
10333
const double psitilde_bs_0_0 = 1;
10334
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10335
const double psitilde_bs_1_0 = 1;
10337
// Compute basisvalues
10338
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10339
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10340
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10342
// Table(s) of coefficients
10343
const static double coefficients0[3][3] = \
10344
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10345
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10346
{0.471404520791032, 0, 0.333333333333333}};
10348
// Extract relevant coefficients
10349
const double coeff0_0 = coefficients0[dof][0];
10350
const double coeff0_1 = coefficients0[dof][1];
10351
const double coeff0_2 = coefficients0[dof][2];
10353
// Compute value(s)
10354
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10357
if (3 <= i && i <= 5)
10359
// Map degree of freedom to element degree of freedom
10360
const unsigned int dof = i - 3;
10362
// Generate scalings
10363
const double scalings_y_0 = 1;
10364
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10366
// Compute psitilde_a
10367
const double psitilde_a_0 = 1;
10368
const double psitilde_a_1 = x;
10370
// Compute psitilde_bs
10371
const double psitilde_bs_0_0 = 1;
10372
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10373
const double psitilde_bs_1_0 = 1;
10375
// Compute basisvalues
10376
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10377
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10378
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10380
// Table(s) of coefficients
10381
const static double coefficients0[3][3] = \
10382
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10383
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10384
{0.471404520791032, 0, 0.333333333333333}};
10386
// Extract relevant coefficients
10387
const double coeff0_0 = coefficients0[dof][0];
10388
const double coeff0_1 = coefficients0[dof][1];
10389
const double coeff0_2 = coefficients0[dof][2];
10391
// Compute value(s)
10392
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10397
/// Evaluate all basis functions at given point in cell
10398
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis_all(double* values,
10399
const double* coordinates,
10400
const ufc::cell& c) const
10402
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
10405
/// Evaluate order n derivatives of basis function i at given point in cell
10406
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis_derivatives(unsigned int i,
10409
const double* coordinates,
10410
const ufc::cell& c) const
10412
// Extract vertex coordinates
10413
const double * const * element_coordinates = c.coordinates;
10415
// Compute Jacobian of affine map from reference cell
10416
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10417
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10418
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10419
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10421
// Compute determinant of Jacobian
10422
const double detJ = J_00*J_11 - J_01*J_10;
10424
// Compute inverse of Jacobian
10426
// Get coordinates and map to the reference (UFC) element
10427
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10428
element_coordinates[0][0]*element_coordinates[2][1] +\
10429
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10430
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10431
element_coordinates[1][0]*element_coordinates[0][1] -\
10432
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10434
// Map coordinates to the reference square
10435
if (std::abs(y - 1.0) < 1e-14)
10438
x = 2.0 *x/(1.0 - y) - 1.0;
10441
// Compute number of derivatives
10442
unsigned int num_derivatives = 1;
10444
for (unsigned int j = 0; j < n; j++)
10445
num_derivatives *= 2;
10448
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10449
unsigned int **combinations = new unsigned int *[num_derivatives];
10451
for (unsigned int j = 0; j < num_derivatives; j++)
10453
combinations[j] = new unsigned int [n];
10454
for (unsigned int k = 0; k < n; k++)
10455
combinations[j][k] = 0;
10458
// Generate combinations of derivatives
10459
for (unsigned int row = 1; row < num_derivatives; row++)
10461
for (unsigned int num = 0; num < row; num++)
10463
for (unsigned int col = n-1; col+1 > 0; col--)
10465
if (combinations[row][col] + 1 > 1)
10466
combinations[row][col] = 0;
10469
combinations[row][col] += 1;
10476
// Compute inverse of Jacobian
10477
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10479
// Declare transformation matrix
10480
// Declare pointer to two dimensional array and initialise
10481
double **transform = new double *[num_derivatives];
10483
for (unsigned int j = 0; j < num_derivatives; j++)
10485
transform[j] = new double [num_derivatives];
10486
for (unsigned int k = 0; k < num_derivatives; k++)
10487
transform[j][k] = 1;
10490
// Construct transformation matrix
10491
for (unsigned int row = 0; row < num_derivatives; row++)
10493
for (unsigned int col = 0; col < num_derivatives; col++)
10495
for (unsigned int k = 0; k < n; k++)
10496
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10501
for (unsigned int j = 0; j < 2*num_derivatives; j++)
10504
if (0 <= i && i <= 2)
10506
// Map degree of freedom to element degree of freedom
10507
const unsigned int dof = i;
10509
// Generate scalings
10510
const double scalings_y_0 = 1;
10511
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10513
// Compute psitilde_a
10514
const double psitilde_a_0 = 1;
10515
const double psitilde_a_1 = x;
10517
// Compute psitilde_bs
10518
const double psitilde_bs_0_0 = 1;
10519
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10520
const double psitilde_bs_1_0 = 1;
10522
// Compute basisvalues
10523
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10524
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10525
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10527
// Table(s) of coefficients
10528
const static double coefficients0[3][3] = \
10529
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10530
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10531
{0.471404520791032, 0, 0.333333333333333}};
10533
// Interesting (new) part
10534
// Tables of derivatives of the polynomial base (transpose)
10535
const static double dmats0[3][3] = \
10537
{4.89897948556636, 0, 0},
10540
const static double dmats1[3][3] = \
10542
{2.44948974278318, 0, 0},
10543
{4.24264068711928, 0, 0}};
10545
// Compute reference derivatives
10546
// Declare pointer to array of derivatives on FIAT element
10547
double *derivatives = new double [num_derivatives];
10549
// Declare coefficients
10550
double coeff0_0 = 0;
10551
double coeff0_1 = 0;
10552
double coeff0_2 = 0;
10554
// Declare new coefficients
10555
double new_coeff0_0 = 0;
10556
double new_coeff0_1 = 0;
10557
double new_coeff0_2 = 0;
10559
// Loop possible derivatives
10560
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10562
// Get values from coefficients array
10563
new_coeff0_0 = coefficients0[dof][0];
10564
new_coeff0_1 = coefficients0[dof][1];
10565
new_coeff0_2 = coefficients0[dof][2];
10567
// Loop derivative order
10568
for (unsigned int j = 0; j < n; j++)
10570
// Update old coefficients
10571
coeff0_0 = new_coeff0_0;
10572
coeff0_1 = new_coeff0_1;
10573
coeff0_2 = new_coeff0_2;
10575
if(combinations[deriv_num][j] == 0)
10577
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10578
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10579
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10581
if(combinations[deriv_num][j] == 1)
10583
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10584
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10585
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10589
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10590
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10593
// Transform derivatives back to physical element
10594
for (unsigned int row = 0; row < num_derivatives; row++)
10596
for (unsigned int col = 0; col < num_derivatives; col++)
10598
values[row] += transform[row][col]*derivatives[col];
10601
// Delete pointer to array of derivatives on FIAT element
10602
delete [] derivatives;
10604
// Delete pointer to array of combinations of derivatives and transform
10605
for (unsigned int row = 0; row < num_derivatives; row++)
10607
delete [] combinations[row];
10608
delete [] transform[row];
10611
delete [] combinations;
10612
delete [] transform;
10615
if (3 <= i && i <= 5)
10617
// Map degree of freedom to element degree of freedom
10618
const unsigned int dof = i - 3;
10620
// Generate scalings
10621
const double scalings_y_0 = 1;
10622
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10624
// Compute psitilde_a
10625
const double psitilde_a_0 = 1;
10626
const double psitilde_a_1 = x;
10628
// Compute psitilde_bs
10629
const double psitilde_bs_0_0 = 1;
10630
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10631
const double psitilde_bs_1_0 = 1;
10633
// Compute basisvalues
10634
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10635
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10636
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10638
// Table(s) of coefficients
10639
const static double coefficients0[3][3] = \
10640
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10641
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10642
{0.471404520791032, 0, 0.333333333333333}};
10644
// Interesting (new) part
10645
// Tables of derivatives of the polynomial base (transpose)
10646
const static double dmats0[3][3] = \
10648
{4.89897948556636, 0, 0},
10651
const static double dmats1[3][3] = \
10653
{2.44948974278318, 0, 0},
10654
{4.24264068711928, 0, 0}};
10656
// Compute reference derivatives
10657
// Declare pointer to array of derivatives on FIAT element
10658
double *derivatives = new double [num_derivatives];
10660
// Declare coefficients
10661
double coeff0_0 = 0;
10662
double coeff0_1 = 0;
10663
double coeff0_2 = 0;
10665
// Declare new coefficients
10666
double new_coeff0_0 = 0;
10667
double new_coeff0_1 = 0;
10668
double new_coeff0_2 = 0;
10670
// Loop possible derivatives
10671
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10673
// Get values from coefficients array
10674
new_coeff0_0 = coefficients0[dof][0];
10675
new_coeff0_1 = coefficients0[dof][1];
10676
new_coeff0_2 = coefficients0[dof][2];
10678
// Loop derivative order
10679
for (unsigned int j = 0; j < n; j++)
10681
// Update old coefficients
10682
coeff0_0 = new_coeff0_0;
10683
coeff0_1 = new_coeff0_1;
10684
coeff0_2 = new_coeff0_2;
10686
if(combinations[deriv_num][j] == 0)
10688
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10689
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10690
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10692
if(combinations[deriv_num][j] == 1)
10694
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10695
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10696
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10700
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10701
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10704
// Transform derivatives back to physical element
10705
for (unsigned int row = 0; row < num_derivatives; row++)
10707
for (unsigned int col = 0; col < num_derivatives; col++)
10709
values[num_derivatives + row] += transform[row][col]*derivatives[col];
10712
// Delete pointer to array of derivatives on FIAT element
10713
delete [] derivatives;
10715
// Delete pointer to array of combinations of derivatives and transform
10716
for (unsigned int row = 0; row < num_derivatives; row++)
10718
delete [] combinations[row];
10719
delete [] transform[row];
10722
delete [] combinations;
10723
delete [] transform;
10728
/// Evaluate order n derivatives of all basis functions at given point in cell
10729
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
10731
const double* coordinates,
10732
const ufc::cell& c) const
10734
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
10737
/// Evaluate linear functional for dof i on the function f
10738
double UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_dof(unsigned int i,
10739
const ufc::function& f,
10740
const ufc::cell& c) const
10742
// The reference points, direction and weights:
10743
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
10744
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
10745
const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
10747
const double * const * x = c.coordinates;
10748
double result = 0.0;
10749
// Iterate over the points:
10750
// Evaluate basis functions for affine mapping
10751
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
10752
const double w1 = X[i][0][0];
10753
const double w2 = X[i][0][1];
10755
// Compute affine mapping y = F(X)
10757
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
10758
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
10760
// Evaluate function at physical points
10762
f.evaluate(values, y, c);
10764
// Map function values using appropriate mapping
10765
// Affine map: Do nothing
10767
// Note that we do not map the weights (yet).
10769
// Take directional components
10770
for(int k = 0; k < 2; k++)
10771
result += values[k]*D[i][0][k];
10772
// Multiply by weights
10778
/// Evaluate linear functionals for all dofs on the function f
10779
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_dofs(double* values,
10780
const ufc::function& f,
10781
const ufc::cell& c) const
10783
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10786
/// Interpolate vertex values from dof values
10787
void UFC_CahnHilliard2DLinearForm_finite_element_1::interpolate_vertex_values(double* vertex_values,
10788
const double* dof_values,
10789
const ufc::cell& c) const
10791
// Evaluate at vertices and use affine mapping
10792
vertex_values[0] = dof_values[0];
10793
vertex_values[2] = dof_values[1];
10794
vertex_values[4] = dof_values[2];
10795
// Evaluate at vertices and use affine mapping
10796
vertex_values[1] = dof_values[3];
10797
vertex_values[3] = dof_values[4];
10798
vertex_values[5] = dof_values[5];
10801
/// Return the number of sub elements (for a mixed element)
10802
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::num_sub_elements() const
10807
/// Create a new finite element for sub element i (for a mixed element)
10808
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_1::create_sub_element(unsigned int i) const
10813
return new UFC_CahnHilliard2DLinearForm_finite_element_1_0();
10816
return new UFC_CahnHilliard2DLinearForm_finite_element_1_1();
10824
UFC_CahnHilliard2DLinearForm_finite_element_2_0::UFC_CahnHilliard2DLinearForm_finite_element_2_0() : ufc::finite_element()
10830
UFC_CahnHilliard2DLinearForm_finite_element_2_0::~UFC_CahnHilliard2DLinearForm_finite_element_2_0()
10835
/// Return a string identifying the finite element
10836
const char* UFC_CahnHilliard2DLinearForm_finite_element_2_0::signature() const
10838
return "FiniteElement('Lagrange', 'triangle', 1)";
10841
/// Return the cell shape
10842
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_2_0::cell_shape() const
10844
return ufc::triangle;
10847
/// Return the dimension of the finite element function space
10848
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::space_dimension() const
10853
/// Return the rank of the value space
10854
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::value_rank() const
10859
/// Return the dimension of the value space for axis i
10860
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::value_dimension(unsigned int i) const
10865
/// Evaluate basis function i at given point in cell
10866
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis(unsigned int i,
10868
const double* coordinates,
10869
const ufc::cell& c) const
10871
// Extract vertex coordinates
10872
const double * const * element_coordinates = c.coordinates;
10874
// Compute Jacobian of affine map from reference cell
10875
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10876
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10877
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10878
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10880
// Compute determinant of Jacobian
10881
const double detJ = J_00*J_11 - J_01*J_10;
10883
// Compute inverse of Jacobian
10885
// Get coordinates and map to the reference (UFC) element
10886
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10887
element_coordinates[0][0]*element_coordinates[2][1] +\
10888
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10889
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10890
element_coordinates[1][0]*element_coordinates[0][1] -\
10891
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10893
// Map coordinates to the reference square
10894
if (std::abs(y - 1.0) < 1e-14)
10897
x = 2.0 *x/(1.0 - y) - 1.0;
10903
// Map degree of freedom to element degree of freedom
10904
const unsigned int dof = i;
10906
// Generate scalings
10907
const double scalings_y_0 = 1;
10908
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10910
// Compute psitilde_a
10911
const double psitilde_a_0 = 1;
10912
const double psitilde_a_1 = x;
10914
// Compute psitilde_bs
10915
const double psitilde_bs_0_0 = 1;
10916
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10917
const double psitilde_bs_1_0 = 1;
10919
// Compute basisvalues
10920
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10921
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10922
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10924
// Table(s) of coefficients
10925
const static double coefficients0[3][3] = \
10926
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10927
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10928
{0.471404520791032, 0, 0.333333333333333}};
10930
// Extract relevant coefficients
10931
const double coeff0_0 = coefficients0[dof][0];
10932
const double coeff0_1 = coefficients0[dof][1];
10933
const double coeff0_2 = coefficients0[dof][2];
10935
// Compute value(s)
10936
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10939
/// Evaluate all basis functions at given point in cell
10940
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis_all(double* values,
10941
const double* coordinates,
10942
const ufc::cell& c) const
10944
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
10947
/// Evaluate order n derivatives of basis function i at given point in cell
10948
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis_derivatives(unsigned int i,
10951
const double* coordinates,
10952
const ufc::cell& c) const
10954
// Extract vertex coordinates
10955
const double * const * element_coordinates = c.coordinates;
10957
// Compute Jacobian of affine map from reference cell
10958
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10959
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10960
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10961
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10963
// Compute determinant of Jacobian
10964
const double detJ = J_00*J_11 - J_01*J_10;
10966
// Compute inverse of Jacobian
10968
// Get coordinates and map to the reference (UFC) element
10969
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10970
element_coordinates[0][0]*element_coordinates[2][1] +\
10971
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10972
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10973
element_coordinates[1][0]*element_coordinates[0][1] -\
10974
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10976
// Map coordinates to the reference square
10977
if (std::abs(y - 1.0) < 1e-14)
10980
x = 2.0 *x/(1.0 - y) - 1.0;
10983
// Compute number of derivatives
10984
unsigned int num_derivatives = 1;
10986
for (unsigned int j = 0; j < n; j++)
10987
num_derivatives *= 2;
10990
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10991
unsigned int **combinations = new unsigned int *[num_derivatives];
10993
for (unsigned int j = 0; j < num_derivatives; j++)
10995
combinations[j] = new unsigned int [n];
10996
for (unsigned int k = 0; k < n; k++)
10997
combinations[j][k] = 0;
11000
// Generate combinations of derivatives
11001
for (unsigned int row = 1; row < num_derivatives; row++)
11003
for (unsigned int num = 0; num < row; num++)
11005
for (unsigned int col = n-1; col+1 > 0; col--)
11007
if (combinations[row][col] + 1 > 1)
11008
combinations[row][col] = 0;
11011
combinations[row][col] += 1;
11018
// Compute inverse of Jacobian
11019
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11021
// Declare transformation matrix
11022
// Declare pointer to two dimensional array and initialise
11023
double **transform = new double *[num_derivatives];
11025
for (unsigned int j = 0; j < num_derivatives; j++)
11027
transform[j] = new double [num_derivatives];
11028
for (unsigned int k = 0; k < num_derivatives; k++)
11029
transform[j][k] = 1;
11032
// Construct transformation matrix
11033
for (unsigned int row = 0; row < num_derivatives; row++)
11035
for (unsigned int col = 0; col < num_derivatives; col++)
11037
for (unsigned int k = 0; k < n; k++)
11038
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11043
for (unsigned int j = 0; j < 1*num_derivatives; j++)
11046
// Map degree of freedom to element degree of freedom
11047
const unsigned int dof = i;
11049
// Generate scalings
11050
const double scalings_y_0 = 1;
11051
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11053
// Compute psitilde_a
11054
const double psitilde_a_0 = 1;
11055
const double psitilde_a_1 = x;
11057
// Compute psitilde_bs
11058
const double psitilde_bs_0_0 = 1;
11059
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11060
const double psitilde_bs_1_0 = 1;
11062
// Compute basisvalues
11063
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11064
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11065
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11067
// Table(s) of coefficients
11068
const static double coefficients0[3][3] = \
11069
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11070
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11071
{0.471404520791032, 0, 0.333333333333333}};
11073
// Interesting (new) part
11074
// Tables of derivatives of the polynomial base (transpose)
11075
const static double dmats0[3][3] = \
11077
{4.89897948556636, 0, 0},
11080
const static double dmats1[3][3] = \
11082
{2.44948974278318, 0, 0},
11083
{4.24264068711928, 0, 0}};
11085
// Compute reference derivatives
11086
// Declare pointer to array of derivatives on FIAT element
11087
double *derivatives = new double [num_derivatives];
11089
// Declare coefficients
11090
double coeff0_0 = 0;
11091
double coeff0_1 = 0;
11092
double coeff0_2 = 0;
11094
// Declare new coefficients
11095
double new_coeff0_0 = 0;
11096
double new_coeff0_1 = 0;
11097
double new_coeff0_2 = 0;
11099
// Loop possible derivatives
11100
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11102
// Get values from coefficients array
11103
new_coeff0_0 = coefficients0[dof][0];
11104
new_coeff0_1 = coefficients0[dof][1];
11105
new_coeff0_2 = coefficients0[dof][2];
11107
// Loop derivative order
11108
for (unsigned int j = 0; j < n; j++)
11110
// Update old coefficients
11111
coeff0_0 = new_coeff0_0;
11112
coeff0_1 = new_coeff0_1;
11113
coeff0_2 = new_coeff0_2;
11115
if(combinations[deriv_num][j] == 0)
11117
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11118
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11119
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11121
if(combinations[deriv_num][j] == 1)
11123
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11124
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11125
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
11129
// Compute derivatives on reference element as dot product of coefficients and basisvalues
11130
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
11133
// Transform derivatives back to physical element
11134
for (unsigned int row = 0; row < num_derivatives; row++)
11136
for (unsigned int col = 0; col < num_derivatives; col++)
11138
values[row] += transform[row][col]*derivatives[col];
11141
// Delete pointer to array of derivatives on FIAT element
11142
delete [] derivatives;
11144
// Delete pointer to array of combinations of derivatives and transform
11145
for (unsigned int row = 0; row < num_derivatives; row++)
11147
delete [] combinations[row];
11148
delete [] transform[row];
11151
delete [] combinations;
11152
delete [] transform;
11155
/// Evaluate order n derivatives of all basis functions at given point in cell
11156
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
11158
const double* coordinates,
11159
const ufc::cell& c) const
11161
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11164
/// Evaluate linear functional for dof i on the function f
11165
double UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_dof(unsigned int i,
11166
const ufc::function& f,
11167
const ufc::cell& c) const
11169
// The reference points, direction and weights:
11170
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
11171
const static double W[3][1] = {{1}, {1}, {1}};
11172
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
11174
const double * const * x = c.coordinates;
11175
double result = 0.0;
11176
// Iterate over the points:
11177
// Evaluate basis functions for affine mapping
11178
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11179
const double w1 = X[i][0][0];
11180
const double w2 = X[i][0][1];
11182
// Compute affine mapping y = F(X)
11184
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11185
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11187
// Evaluate function at physical points
11189
f.evaluate(values, y, c);
11191
// Map function values using appropriate mapping
11192
// Affine map: Do nothing
11194
// Note that we do not map the weights (yet).
11196
// Take directional components
11197
for(int k = 0; k < 1; k++)
11198
result += values[k]*D[i][0][k];
11199
// Multiply by weights
11205
/// Evaluate linear functionals for all dofs on the function f
11206
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_dofs(double* values,
11207
const ufc::function& f,
11208
const ufc::cell& c) const
11210
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11213
/// Interpolate vertex values from dof values
11214
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
11215
const double* dof_values,
11216
const ufc::cell& c) const
11218
// Evaluate at vertices and use affine mapping
11219
vertex_values[0] = dof_values[0];
11220
vertex_values[1] = dof_values[1];
11221
vertex_values[2] = dof_values[2];
11224
/// Return the number of sub elements (for a mixed element)
11225
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::num_sub_elements() const
11230
/// Create a new finite element for sub element i (for a mixed element)
11231
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_2_0::create_sub_element(unsigned int i) const
11233
return new UFC_CahnHilliard2DLinearForm_finite_element_2_0();
11238
UFC_CahnHilliard2DLinearForm_finite_element_2_1::UFC_CahnHilliard2DLinearForm_finite_element_2_1() : ufc::finite_element()
11244
UFC_CahnHilliard2DLinearForm_finite_element_2_1::~UFC_CahnHilliard2DLinearForm_finite_element_2_1()
11249
/// Return a string identifying the finite element
11250
const char* UFC_CahnHilliard2DLinearForm_finite_element_2_1::signature() const
11252
return "FiniteElement('Lagrange', 'triangle', 1)";
11255
/// Return the cell shape
11256
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_2_1::cell_shape() const
11258
return ufc::triangle;
11261
/// Return the dimension of the finite element function space
11262
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::space_dimension() const
11267
/// Return the rank of the value space
11268
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::value_rank() const
11273
/// Return the dimension of the value space for axis i
11274
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::value_dimension(unsigned int i) const
11279
/// Evaluate basis function i at given point in cell
11280
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis(unsigned int i,
11282
const double* coordinates,
11283
const ufc::cell& c) const
11285
// Extract vertex coordinates
11286
const double * const * element_coordinates = c.coordinates;
11288
// Compute Jacobian of affine map from reference cell
11289
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11290
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11291
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11292
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11294
// Compute determinant of Jacobian
11295
const double detJ = J_00*J_11 - J_01*J_10;
11297
// Compute inverse of Jacobian
11299
// Get coordinates and map to the reference (UFC) element
11300
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11301
element_coordinates[0][0]*element_coordinates[2][1] +\
11302
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11303
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11304
element_coordinates[1][0]*element_coordinates[0][1] -\
11305
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11307
// Map coordinates to the reference square
11308
if (std::abs(y - 1.0) < 1e-14)
11311
x = 2.0 *x/(1.0 - y) - 1.0;
11317
// Map degree of freedom to element degree of freedom
11318
const unsigned int dof = i;
11320
// Generate scalings
11321
const double scalings_y_0 = 1;
11322
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11324
// Compute psitilde_a
11325
const double psitilde_a_0 = 1;
11326
const double psitilde_a_1 = x;
11328
// Compute psitilde_bs
11329
const double psitilde_bs_0_0 = 1;
11330
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11331
const double psitilde_bs_1_0 = 1;
11333
// Compute basisvalues
11334
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11335
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11336
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11338
// Table(s) of coefficients
11339
const static double coefficients0[3][3] = \
11340
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11341
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11342
{0.471404520791032, 0, 0.333333333333333}};
11344
// Extract relevant coefficients
11345
const double coeff0_0 = coefficients0[dof][0];
11346
const double coeff0_1 = coefficients0[dof][1];
11347
const double coeff0_2 = coefficients0[dof][2];
11349
// Compute value(s)
11350
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11353
/// Evaluate all basis functions at given point in cell
11354
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis_all(double* values,
11355
const double* coordinates,
11356
const ufc::cell& c) const
11358
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11361
/// Evaluate order n derivatives of basis function i at given point in cell
11362
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
11365
const double* coordinates,
11366
const ufc::cell& c) const
11368
// Extract vertex coordinates
11369
const double * const * element_coordinates = c.coordinates;
11371
// Compute Jacobian of affine map from reference cell
11372
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11373
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11374
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11375
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11377
// Compute determinant of Jacobian
11378
const double detJ = J_00*J_11 - J_01*J_10;
11380
// Compute inverse of Jacobian
11382
// Get coordinates and map to the reference (UFC) element
11383
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11384
element_coordinates[0][0]*element_coordinates[2][1] +\
11385
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11386
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11387
element_coordinates[1][0]*element_coordinates[0][1] -\
11388
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11390
// Map coordinates to the reference square
11391
if (std::abs(y - 1.0) < 1e-14)
11394
x = 2.0 *x/(1.0 - y) - 1.0;
11397
// Compute number of derivatives
11398
unsigned int num_derivatives = 1;
11400
for (unsigned int j = 0; j < n; j++)
11401
num_derivatives *= 2;
11404
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11405
unsigned int **combinations = new unsigned int *[num_derivatives];
11407
for (unsigned int j = 0; j < num_derivatives; j++)
11409
combinations[j] = new unsigned int [n];
11410
for (unsigned int k = 0; k < n; k++)
11411
combinations[j][k] = 0;
11414
// Generate combinations of derivatives
11415
for (unsigned int row = 1; row < num_derivatives; row++)
11417
for (unsigned int num = 0; num < row; num++)
11419
for (unsigned int col = n-1; col+1 > 0; col--)
11421
if (combinations[row][col] + 1 > 1)
11422
combinations[row][col] = 0;
11425
combinations[row][col] += 1;
11432
// Compute inverse of Jacobian
11433
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11435
// Declare transformation matrix
11436
// Declare pointer to two dimensional array and initialise
11437
double **transform = new double *[num_derivatives];
11439
for (unsigned int j = 0; j < num_derivatives; j++)
11441
transform[j] = new double [num_derivatives];
11442
for (unsigned int k = 0; k < num_derivatives; k++)
11443
transform[j][k] = 1;
11446
// Construct transformation matrix
11447
for (unsigned int row = 0; row < num_derivatives; row++)
11449
for (unsigned int col = 0; col < num_derivatives; col++)
11451
for (unsigned int k = 0; k < n; k++)
11452
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11457
for (unsigned int j = 0; j < 1*num_derivatives; j++)
11460
// Map degree of freedom to element degree of freedom
11461
const unsigned int dof = i;
11463
// Generate scalings
11464
const double scalings_y_0 = 1;
11465
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11467
// Compute psitilde_a
11468
const double psitilde_a_0 = 1;
11469
const double psitilde_a_1 = x;
11471
// Compute psitilde_bs
11472
const double psitilde_bs_0_0 = 1;
11473
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11474
const double psitilde_bs_1_0 = 1;
11476
// Compute basisvalues
11477
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11478
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11479
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11481
// Table(s) of coefficients
11482
const static double coefficients0[3][3] = \
11483
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11484
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11485
{0.471404520791032, 0, 0.333333333333333}};
11487
// Interesting (new) part
11488
// Tables of derivatives of the polynomial base (transpose)
11489
const static double dmats0[3][3] = \
11491
{4.89897948556636, 0, 0},
11494
const static double dmats1[3][3] = \
11496
{2.44948974278318, 0, 0},
11497
{4.24264068711928, 0, 0}};
11499
// Compute reference derivatives
11500
// Declare pointer to array of derivatives on FIAT element
11501
double *derivatives = new double [num_derivatives];
11503
// Declare coefficients
11504
double coeff0_0 = 0;
11505
double coeff0_1 = 0;
11506
double coeff0_2 = 0;
11508
// Declare new coefficients
11509
double new_coeff0_0 = 0;
11510
double new_coeff0_1 = 0;
11511
double new_coeff0_2 = 0;
11513
// Loop possible derivatives
11514
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11516
// Get values from coefficients array
11517
new_coeff0_0 = coefficients0[dof][0];
11518
new_coeff0_1 = coefficients0[dof][1];
11519
new_coeff0_2 = coefficients0[dof][2];
11521
// Loop derivative order
11522
for (unsigned int j = 0; j < n; j++)
11524
// Update old coefficients
11525
coeff0_0 = new_coeff0_0;
11526
coeff0_1 = new_coeff0_1;
11527
coeff0_2 = new_coeff0_2;
11529
if(combinations[deriv_num][j] == 0)
11531
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11532
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11533
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11535
if(combinations[deriv_num][j] == 1)
11537
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11538
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11539
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
11543
// Compute derivatives on reference element as dot product of coefficients and basisvalues
11544
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
11547
// Transform derivatives back to physical element
11548
for (unsigned int row = 0; row < num_derivatives; row++)
11550
for (unsigned int col = 0; col < num_derivatives; col++)
11552
values[row] += transform[row][col]*derivatives[col];
11555
// Delete pointer to array of derivatives on FIAT element
11556
delete [] derivatives;
11558
// Delete pointer to array of combinations of derivatives and transform
11559
for (unsigned int row = 0; row < num_derivatives; row++)
11561
delete [] combinations[row];
11562
delete [] transform[row];
11565
delete [] combinations;
11566
delete [] transform;
11569
/// Evaluate order n derivatives of all basis functions at given point in cell
11570
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
11572
const double* coordinates,
11573
const ufc::cell& c) const
11575
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11578
/// Evaluate linear functional for dof i on the function f
11579
double UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_dof(unsigned int i,
11580
const ufc::function& f,
11581
const ufc::cell& c) const
11583
// The reference points, direction and weights:
11584
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
11585
const static double W[3][1] = {{1}, {1}, {1}};
11586
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
11588
const double * const * x = c.coordinates;
11589
double result = 0.0;
11590
// Iterate over the points:
11591
// Evaluate basis functions for affine mapping
11592
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11593
const double w1 = X[i][0][0];
11594
const double w2 = X[i][0][1];
11596
// Compute affine mapping y = F(X)
11598
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11599
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11601
// Evaluate function at physical points
11603
f.evaluate(values, y, c);
11605
// Map function values using appropriate mapping
11606
// Affine map: Do nothing
11608
// Note that we do not map the weights (yet).
11610
// Take directional components
11611
for(int k = 0; k < 1; k++)
11612
result += values[k]*D[i][0][k];
11613
// Multiply by weights
11619
/// Evaluate linear functionals for all dofs on the function f
11620
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_dofs(double* values,
11621
const ufc::function& f,
11622
const ufc::cell& c) const
11624
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11627
/// Interpolate vertex values from dof values
11628
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
11629
const double* dof_values,
11630
const ufc::cell& c) const
11632
// Evaluate at vertices and use affine mapping
11633
vertex_values[0] = dof_values[0];
11634
vertex_values[1] = dof_values[1];
11635
vertex_values[2] = dof_values[2];
11638
/// Return the number of sub elements (for a mixed element)
11639
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::num_sub_elements() const
11644
/// Create a new finite element for sub element i (for a mixed element)
11645
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_2_1::create_sub_element(unsigned int i) const
11647
return new UFC_CahnHilliard2DLinearForm_finite_element_2_1();
11652
UFC_CahnHilliard2DLinearForm_finite_element_2::UFC_CahnHilliard2DLinearForm_finite_element_2() : ufc::finite_element()
11658
UFC_CahnHilliard2DLinearForm_finite_element_2::~UFC_CahnHilliard2DLinearForm_finite_element_2()
11663
/// Return a string identifying the finite element
11664
const char* UFC_CahnHilliard2DLinearForm_finite_element_2::signature() const
11666
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
11669
/// Return the cell shape
11670
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_2::cell_shape() const
11672
return ufc::triangle;
11675
/// Return the dimension of the finite element function space
11676
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::space_dimension() const
11681
/// Return the rank of the value space
11682
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::value_rank() const
11687
/// Return the dimension of the value space for axis i
11688
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::value_dimension(unsigned int i) const
11693
/// Evaluate basis function i at given point in cell
11694
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis(unsigned int i,
11696
const double* coordinates,
11697
const ufc::cell& c) const
11699
// Extract vertex coordinates
11700
const double * const * element_coordinates = c.coordinates;
11702
// Compute Jacobian of affine map from reference cell
11703
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11704
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11705
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11706
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11708
// Compute determinant of Jacobian
11709
const double detJ = J_00*J_11 - J_01*J_10;
11711
// Compute inverse of Jacobian
11713
// Get coordinates and map to the reference (UFC) element
11714
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11715
element_coordinates[0][0]*element_coordinates[2][1] +\
11716
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11717
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11718
element_coordinates[1][0]*element_coordinates[0][1] -\
11719
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11721
// Map coordinates to the reference square
11722
if (std::abs(y - 1.0) < 1e-14)
11725
x = 2.0 *x/(1.0 - y) - 1.0;
11732
if (0 <= i && i <= 2)
11734
// Map degree of freedom to element degree of freedom
11735
const unsigned int dof = i;
11737
// Generate scalings
11738
const double scalings_y_0 = 1;
11739
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11741
// Compute psitilde_a
11742
const double psitilde_a_0 = 1;
11743
const double psitilde_a_1 = x;
11745
// Compute psitilde_bs
11746
const double psitilde_bs_0_0 = 1;
11747
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11748
const double psitilde_bs_1_0 = 1;
11750
// Compute basisvalues
11751
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11752
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11753
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11755
// Table(s) of coefficients
11756
const static double coefficients0[3][3] = \
11757
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11758
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11759
{0.471404520791032, 0, 0.333333333333333}};
11761
// Extract relevant coefficients
11762
const double coeff0_0 = coefficients0[dof][0];
11763
const double coeff0_1 = coefficients0[dof][1];
11764
const double coeff0_2 = coefficients0[dof][2];
11766
// Compute value(s)
11767
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11770
if (3 <= i && i <= 5)
11772
// Map degree of freedom to element degree of freedom
11773
const unsigned int dof = i - 3;
11775
// Generate scalings
11776
const double scalings_y_0 = 1;
11777
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11779
// Compute psitilde_a
11780
const double psitilde_a_0 = 1;
11781
const double psitilde_a_1 = x;
11783
// Compute psitilde_bs
11784
const double psitilde_bs_0_0 = 1;
11785
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11786
const double psitilde_bs_1_0 = 1;
11788
// Compute basisvalues
11789
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11790
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11791
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11793
// Table(s) of coefficients
11794
const static double coefficients0[3][3] = \
11795
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11796
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11797
{0.471404520791032, 0, 0.333333333333333}};
11799
// Extract relevant coefficients
11800
const double coeff0_0 = coefficients0[dof][0];
11801
const double coeff0_1 = coefficients0[dof][1];
11802
const double coeff0_2 = coefficients0[dof][2];
11804
// Compute value(s)
11805
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11810
/// Evaluate all basis functions at given point in cell
11811
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis_all(double* values,
11812
const double* coordinates,
11813
const ufc::cell& c) const
11815
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11818
/// Evaluate order n derivatives of basis function i at given point in cell
11819
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis_derivatives(unsigned int i,
11822
const double* coordinates,
11823
const ufc::cell& c) const
11825
// Extract vertex coordinates
11826
const double * const * element_coordinates = c.coordinates;
11828
// Compute Jacobian of affine map from reference cell
11829
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11830
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11831
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11832
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11834
// Compute determinant of Jacobian
11835
const double detJ = J_00*J_11 - J_01*J_10;
11837
// Compute inverse of Jacobian
11839
// Get coordinates and map to the reference (UFC) element
11840
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11841
element_coordinates[0][0]*element_coordinates[2][1] +\
11842
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11843
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11844
element_coordinates[1][0]*element_coordinates[0][1] -\
11845
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11847
// Map coordinates to the reference square
11848
if (std::abs(y - 1.0) < 1e-14)
11851
x = 2.0 *x/(1.0 - y) - 1.0;
11854
// Compute number of derivatives
11855
unsigned int num_derivatives = 1;
11857
for (unsigned int j = 0; j < n; j++)
11858
num_derivatives *= 2;
11861
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11862
unsigned int **combinations = new unsigned int *[num_derivatives];
11864
for (unsigned int j = 0; j < num_derivatives; j++)
11866
combinations[j] = new unsigned int [n];
11867
for (unsigned int k = 0; k < n; k++)
11868
combinations[j][k] = 0;
11871
// Generate combinations of derivatives
11872
for (unsigned int row = 1; row < num_derivatives; row++)
11874
for (unsigned int num = 0; num < row; num++)
11876
for (unsigned int col = n-1; col+1 > 0; col--)
11878
if (combinations[row][col] + 1 > 1)
11879
combinations[row][col] = 0;
11882
combinations[row][col] += 1;
11889
// Compute inverse of Jacobian
11890
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11892
// Declare transformation matrix
11893
// Declare pointer to two dimensional array and initialise
11894
double **transform = new double *[num_derivatives];
11896
for (unsigned int j = 0; j < num_derivatives; j++)
11898
transform[j] = new double [num_derivatives];
11899
for (unsigned int k = 0; k < num_derivatives; k++)
11900
transform[j][k] = 1;
11903
// Construct transformation matrix
11904
for (unsigned int row = 0; row < num_derivatives; row++)
11906
for (unsigned int col = 0; col < num_derivatives; col++)
11908
for (unsigned int k = 0; k < n; k++)
11909
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11914
for (unsigned int j = 0; j < 2*num_derivatives; j++)
11917
if (0 <= i && i <= 2)
11919
// Map degree of freedom to element degree of freedom
11920
const unsigned int dof = i;
11922
// Generate scalings
11923
const double scalings_y_0 = 1;
11924
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11926
// Compute psitilde_a
11927
const double psitilde_a_0 = 1;
11928
const double psitilde_a_1 = x;
11930
// Compute psitilde_bs
11931
const double psitilde_bs_0_0 = 1;
11932
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11933
const double psitilde_bs_1_0 = 1;
11935
// Compute basisvalues
11936
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11937
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11938
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11940
// Table(s) of coefficients
11941
const static double coefficients0[3][3] = \
11942
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11943
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11944
{0.471404520791032, 0, 0.333333333333333}};
11946
// Interesting (new) part
11947
// Tables of derivatives of the polynomial base (transpose)
11948
const static double dmats0[3][3] = \
11950
{4.89897948556636, 0, 0},
11953
const static double dmats1[3][3] = \
11955
{2.44948974278318, 0, 0},
11956
{4.24264068711928, 0, 0}};
11958
// Compute reference derivatives
11959
// Declare pointer to array of derivatives on FIAT element
11960
double *derivatives = new double [num_derivatives];
11962
// Declare coefficients
11963
double coeff0_0 = 0;
11964
double coeff0_1 = 0;
11965
double coeff0_2 = 0;
11967
// Declare new coefficients
11968
double new_coeff0_0 = 0;
11969
double new_coeff0_1 = 0;
11970
double new_coeff0_2 = 0;
11972
// Loop possible derivatives
11973
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11975
// Get values from coefficients array
11976
new_coeff0_0 = coefficients0[dof][0];
11977
new_coeff0_1 = coefficients0[dof][1];
11978
new_coeff0_2 = coefficients0[dof][2];
11980
// Loop derivative order
11981
for (unsigned int j = 0; j < n; j++)
11983
// Update old coefficients
11984
coeff0_0 = new_coeff0_0;
11985
coeff0_1 = new_coeff0_1;
11986
coeff0_2 = new_coeff0_2;
11988
if(combinations[deriv_num][j] == 0)
11990
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11991
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11992
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11994
if(combinations[deriv_num][j] == 1)
11996
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11997
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11998
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
12002
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12003
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
12006
// Transform derivatives back to physical element
12007
for (unsigned int row = 0; row < num_derivatives; row++)
12009
for (unsigned int col = 0; col < num_derivatives; col++)
12011
values[row] += transform[row][col]*derivatives[col];
12014
// Delete pointer to array of derivatives on FIAT element
12015
delete [] derivatives;
12017
// Delete pointer to array of combinations of derivatives and transform
12018
for (unsigned int row = 0; row < num_derivatives; row++)
12020
delete [] combinations[row];
12021
delete [] transform[row];
12024
delete [] combinations;
12025
delete [] transform;
12028
if (3 <= i && i <= 5)
12030
// Map degree of freedom to element degree of freedom
12031
const unsigned int dof = i - 3;
12033
// Generate scalings
12034
const double scalings_y_0 = 1;
12035
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12037
// Compute psitilde_a
12038
const double psitilde_a_0 = 1;
12039
const double psitilde_a_1 = x;
12041
// Compute psitilde_bs
12042
const double psitilde_bs_0_0 = 1;
12043
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12044
const double psitilde_bs_1_0 = 1;
12046
// Compute basisvalues
12047
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12048
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12049
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12051
// Table(s) of coefficients
12052
const static double coefficients0[3][3] = \
12053
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
12054
{0.471404520791032, 0.288675134594813, -0.166666666666667},
12055
{0.471404520791032, 0, 0.333333333333333}};
12057
// Interesting (new) part
12058
// Tables of derivatives of the polynomial base (transpose)
12059
const static double dmats0[3][3] = \
12061
{4.89897948556636, 0, 0},
12064
const static double dmats1[3][3] = \
12066
{2.44948974278318, 0, 0},
12067
{4.24264068711928, 0, 0}};
12069
// Compute reference derivatives
12070
// Declare pointer to array of derivatives on FIAT element
12071
double *derivatives = new double [num_derivatives];
12073
// Declare coefficients
12074
double coeff0_0 = 0;
12075
double coeff0_1 = 0;
12076
double coeff0_2 = 0;
12078
// Declare new coefficients
12079
double new_coeff0_0 = 0;
12080
double new_coeff0_1 = 0;
12081
double new_coeff0_2 = 0;
12083
// Loop possible derivatives
12084
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12086
// Get values from coefficients array
12087
new_coeff0_0 = coefficients0[dof][0];
12088
new_coeff0_1 = coefficients0[dof][1];
12089
new_coeff0_2 = coefficients0[dof][2];
12091
// Loop derivative order
12092
for (unsigned int j = 0; j < n; j++)
12094
// Update old coefficients
12095
coeff0_0 = new_coeff0_0;
12096
coeff0_1 = new_coeff0_1;
12097
coeff0_2 = new_coeff0_2;
12099
if(combinations[deriv_num][j] == 0)
12101
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
12102
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
12103
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
12105
if(combinations[deriv_num][j] == 1)
12107
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
12108
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
12109
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
12113
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12114
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
12117
// Transform derivatives back to physical element
12118
for (unsigned int row = 0; row < num_derivatives; row++)
12120
for (unsigned int col = 0; col < num_derivatives; col++)
12122
values[num_derivatives + row] += transform[row][col]*derivatives[col];
12125
// Delete pointer to array of derivatives on FIAT element
12126
delete [] derivatives;
12128
// Delete pointer to array of combinations of derivatives and transform
12129
for (unsigned int row = 0; row < num_derivatives; row++)
12131
delete [] combinations[row];
12132
delete [] transform[row];
12135
delete [] combinations;
12136
delete [] transform;
12141
/// Evaluate order n derivatives of all basis functions at given point in cell
12142
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
12144
const double* coordinates,
12145
const ufc::cell& c) const
12147
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12150
/// Evaluate linear functional for dof i on the function f
12151
double UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_dof(unsigned int i,
12152
const ufc::function& f,
12153
const ufc::cell& c) const
12155
// The reference points, direction and weights:
12156
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
12157
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
12158
const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
12160
const double * const * x = c.coordinates;
12161
double result = 0.0;
12162
// Iterate over the points:
12163
// Evaluate basis functions for affine mapping
12164
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12165
const double w1 = X[i][0][0];
12166
const double w2 = X[i][0][1];
12168
// Compute affine mapping y = F(X)
12170
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12171
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12173
// Evaluate function at physical points
12175
f.evaluate(values, y, c);
12177
// Map function values using appropriate mapping
12178
// Affine map: Do nothing
12180
// Note that we do not map the weights (yet).
12182
// Take directional components
12183
for(int k = 0; k < 2; k++)
12184
result += values[k]*D[i][0][k];
12185
// Multiply by weights
12191
/// Evaluate linear functionals for all dofs on the function f
12192
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_dofs(double* values,
12193
const ufc::function& f,
12194
const ufc::cell& c) const
12196
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12199
/// Interpolate vertex values from dof values
12200
void UFC_CahnHilliard2DLinearForm_finite_element_2::interpolate_vertex_values(double* vertex_values,
12201
const double* dof_values,
12202
const ufc::cell& c) const
12204
// Evaluate at vertices and use affine mapping
12205
vertex_values[0] = dof_values[0];
12206
vertex_values[2] = dof_values[1];
12207
vertex_values[4] = dof_values[2];
12208
// Evaluate at vertices and use affine mapping
12209
vertex_values[1] = dof_values[3];
12210
vertex_values[3] = dof_values[4];
12211
vertex_values[5] = dof_values[5];
12214
/// Return the number of sub elements (for a mixed element)
12215
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::num_sub_elements() const
12220
/// Create a new finite element for sub element i (for a mixed element)
12221
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_2::create_sub_element(unsigned int i) const
12226
return new UFC_CahnHilliard2DLinearForm_finite_element_2_0();
12229
return new UFC_CahnHilliard2DLinearForm_finite_element_2_1();
12237
UFC_CahnHilliard2DLinearForm_finite_element_3::UFC_CahnHilliard2DLinearForm_finite_element_3() : ufc::finite_element()
12243
UFC_CahnHilliard2DLinearForm_finite_element_3::~UFC_CahnHilliard2DLinearForm_finite_element_3()
12248
/// Return a string identifying the finite element
12249
const char* UFC_CahnHilliard2DLinearForm_finite_element_3::signature() const
12251
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
12254
/// Return the cell shape
12255
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_3::cell_shape() const
12257
return ufc::triangle;
12260
/// Return the dimension of the finite element function space
12261
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::space_dimension() const
12266
/// Return the rank of the value space
12267
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::value_rank() const
12272
/// Return the dimension of the value space for axis i
12273
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::value_dimension(unsigned int i) const
12278
/// Evaluate basis function i at given point in cell
12279
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis(unsigned int i,
12281
const double* coordinates,
12282
const ufc::cell& c) const
12284
// Extract vertex coordinates
12285
const double * const * element_coordinates = c.coordinates;
12287
// Compute Jacobian of affine map from reference cell
12288
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12289
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12290
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12291
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12293
// Compute determinant of Jacobian
12294
const double detJ = J_00*J_11 - J_01*J_10;
12296
// Compute inverse of Jacobian
12298
// Get coordinates and map to the reference (UFC) element
12299
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12300
element_coordinates[0][0]*element_coordinates[2][1] +\
12301
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12302
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12303
element_coordinates[1][0]*element_coordinates[0][1] -\
12304
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12306
// Map coordinates to the reference square
12307
if (std::abs(y - 1.0) < 1e-14)
12310
x = 2.0 *x/(1.0 - y) - 1.0;
12316
// Map degree of freedom to element degree of freedom
12317
const unsigned int dof = i;
12319
// Generate scalings
12320
const double scalings_y_0 = 1;
12322
// Compute psitilde_a
12323
const double psitilde_a_0 = 1;
12325
// Compute psitilde_bs
12326
const double psitilde_bs_0_0 = 1;
12328
// Compute basisvalues
12329
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12331
// Table(s) of coefficients
12332
const static double coefficients0[1][1] = \
12333
{{1.41421356237309}};
12335
// Extract relevant coefficients
12336
const double coeff0_0 = coefficients0[dof][0];
12338
// Compute value(s)
12339
*values = coeff0_0*basisvalue0;
12342
/// Evaluate all basis functions at given point in cell
12343
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis_all(double* values,
12344
const double* coordinates,
12345
const ufc::cell& c) const
12347
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12350
/// Evaluate order n derivatives of basis function i at given point in cell
12351
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis_derivatives(unsigned int i,
12354
const double* coordinates,
12355
const ufc::cell& c) const
12357
// Extract vertex coordinates
12358
const double * const * element_coordinates = c.coordinates;
12360
// Compute Jacobian of affine map from reference cell
12361
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12362
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12363
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12364
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12366
// Compute determinant of Jacobian
12367
const double detJ = J_00*J_11 - J_01*J_10;
12369
// Compute inverse of Jacobian
12371
// Get coordinates and map to the reference (UFC) element
12372
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12373
element_coordinates[0][0]*element_coordinates[2][1] +\
12374
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12375
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12376
element_coordinates[1][0]*element_coordinates[0][1] -\
12377
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12379
// Map coordinates to the reference square
12380
if (std::abs(y - 1.0) < 1e-14)
12383
x = 2.0 *x/(1.0 - y) - 1.0;
12386
// Compute number of derivatives
12387
unsigned int num_derivatives = 1;
12389
for (unsigned int j = 0; j < n; j++)
12390
num_derivatives *= 2;
12393
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12394
unsigned int **combinations = new unsigned int *[num_derivatives];
12396
for (unsigned int j = 0; j < num_derivatives; j++)
12398
combinations[j] = new unsigned int [n];
12399
for (unsigned int k = 0; k < n; k++)
12400
combinations[j][k] = 0;
12403
// Generate combinations of derivatives
12404
for (unsigned int row = 1; row < num_derivatives; row++)
12406
for (unsigned int num = 0; num < row; num++)
12408
for (unsigned int col = n-1; col+1 > 0; col--)
12410
if (combinations[row][col] + 1 > 1)
12411
combinations[row][col] = 0;
12414
combinations[row][col] += 1;
12421
// Compute inverse of Jacobian
12422
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12424
// Declare transformation matrix
12425
// Declare pointer to two dimensional array and initialise
12426
double **transform = new double *[num_derivatives];
12428
for (unsigned int j = 0; j < num_derivatives; j++)
12430
transform[j] = new double [num_derivatives];
12431
for (unsigned int k = 0; k < num_derivatives; k++)
12432
transform[j][k] = 1;
12435
// Construct transformation matrix
12436
for (unsigned int row = 0; row < num_derivatives; row++)
12438
for (unsigned int col = 0; col < num_derivatives; col++)
12440
for (unsigned int k = 0; k < n; k++)
12441
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12446
for (unsigned int j = 0; j < 1*num_derivatives; j++)
12449
// Map degree of freedom to element degree of freedom
12450
const unsigned int dof = i;
12452
// Generate scalings
12453
const double scalings_y_0 = 1;
12455
// Compute psitilde_a
12456
const double psitilde_a_0 = 1;
12458
// Compute psitilde_bs
12459
const double psitilde_bs_0_0 = 1;
12461
// Compute basisvalues
12462
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12464
// Table(s) of coefficients
12465
const static double coefficients0[1][1] = \
12466
{{1.41421356237309}};
12468
// Interesting (new) part
12469
// Tables of derivatives of the polynomial base (transpose)
12470
const static double dmats0[1][1] = \
12473
const static double dmats1[1][1] = \
12476
// Compute reference derivatives
12477
// Declare pointer to array of derivatives on FIAT element
12478
double *derivatives = new double [num_derivatives];
12480
// Declare coefficients
12481
double coeff0_0 = 0;
12483
// Declare new coefficients
12484
double new_coeff0_0 = 0;
12486
// Loop possible derivatives
12487
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12489
// Get values from coefficients array
12490
new_coeff0_0 = coefficients0[dof][0];
12492
// Loop derivative order
12493
for (unsigned int j = 0; j < n; j++)
12495
// Update old coefficients
12496
coeff0_0 = new_coeff0_0;
12498
if(combinations[deriv_num][j] == 0)
12500
new_coeff0_0 = coeff0_0*dmats0[0][0];
12502
if(combinations[deriv_num][j] == 1)
12504
new_coeff0_0 = coeff0_0*dmats1[0][0];
12508
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12509
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
12512
// Transform derivatives back to physical element
12513
for (unsigned int row = 0; row < num_derivatives; row++)
12515
for (unsigned int col = 0; col < num_derivatives; col++)
12517
values[row] += transform[row][col]*derivatives[col];
12520
// Delete pointer to array of derivatives on FIAT element
12521
delete [] derivatives;
12523
// Delete pointer to array of combinations of derivatives and transform
12524
for (unsigned int row = 0; row < num_derivatives; row++)
12526
delete [] combinations[row];
12527
delete [] transform[row];
12530
delete [] combinations;
12531
delete [] transform;
12534
/// Evaluate order n derivatives of all basis functions at given point in cell
12535
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
12537
const double* coordinates,
12538
const ufc::cell& c) const
12540
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12543
/// Evaluate linear functional for dof i on the function f
12544
double UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_dof(unsigned int i,
12545
const ufc::function& f,
12546
const ufc::cell& c) const
12548
// The reference points, direction and weights:
12549
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
12550
const static double W[1][1] = {{1}};
12551
const static double D[1][1][1] = {{{1}}};
12553
const double * const * x = c.coordinates;
12554
double result = 0.0;
12555
// Iterate over the points:
12556
// Evaluate basis functions for affine mapping
12557
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12558
const double w1 = X[i][0][0];
12559
const double w2 = X[i][0][1];
12561
// Compute affine mapping y = F(X)
12563
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12564
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12566
// Evaluate function at physical points
12568
f.evaluate(values, y, c);
12570
// Map function values using appropriate mapping
12571
// Affine map: Do nothing
12573
// Note that we do not map the weights (yet).
12575
// Take directional components
12576
for(int k = 0; k < 1; k++)
12577
result += values[k]*D[i][0][k];
12578
// Multiply by weights
12584
/// Evaluate linear functionals for all dofs on the function f
12585
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_dofs(double* values,
12586
const ufc::function& f,
12587
const ufc::cell& c) const
12589
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12592
/// Interpolate vertex values from dof values
12593
void UFC_CahnHilliard2DLinearForm_finite_element_3::interpolate_vertex_values(double* vertex_values,
12594
const double* dof_values,
12595
const ufc::cell& c) const
12597
// Evaluate at vertices and use affine mapping
12598
vertex_values[0] = dof_values[0];
12599
vertex_values[1] = dof_values[0];
12600
vertex_values[2] = dof_values[0];
12603
/// Return the number of sub elements (for a mixed element)
12604
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::num_sub_elements() const
12609
/// Create a new finite element for sub element i (for a mixed element)
12610
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_3::create_sub_element(unsigned int i) const
12612
return new UFC_CahnHilliard2DLinearForm_finite_element_3();
12617
UFC_CahnHilliard2DLinearForm_finite_element_4::UFC_CahnHilliard2DLinearForm_finite_element_4() : ufc::finite_element()
12623
UFC_CahnHilliard2DLinearForm_finite_element_4::~UFC_CahnHilliard2DLinearForm_finite_element_4()
12628
/// Return a string identifying the finite element
12629
const char* UFC_CahnHilliard2DLinearForm_finite_element_4::signature() const
12631
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
12634
/// Return the cell shape
12635
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_4::cell_shape() const
12637
return ufc::triangle;
12640
/// Return the dimension of the finite element function space
12641
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::space_dimension() const
12646
/// Return the rank of the value space
12647
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::value_rank() const
12652
/// Return the dimension of the value space for axis i
12653
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::value_dimension(unsigned int i) const
12658
/// Evaluate basis function i at given point in cell
12659
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis(unsigned int i,
12661
const double* coordinates,
12662
const ufc::cell& c) const
12664
// Extract vertex coordinates
12665
const double * const * element_coordinates = c.coordinates;
12667
// Compute Jacobian of affine map from reference cell
12668
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12669
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12670
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12671
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12673
// Compute determinant of Jacobian
12674
const double detJ = J_00*J_11 - J_01*J_10;
12676
// Compute inverse of Jacobian
12678
// Get coordinates and map to the reference (UFC) element
12679
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12680
element_coordinates[0][0]*element_coordinates[2][1] +\
12681
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12682
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12683
element_coordinates[1][0]*element_coordinates[0][1] -\
12684
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12686
// Map coordinates to the reference square
12687
if (std::abs(y - 1.0) < 1e-14)
12690
x = 2.0 *x/(1.0 - y) - 1.0;
12696
// Map degree of freedom to element degree of freedom
12697
const unsigned int dof = i;
12699
// Generate scalings
12700
const double scalings_y_0 = 1;
12702
// Compute psitilde_a
12703
const double psitilde_a_0 = 1;
12705
// Compute psitilde_bs
12706
const double psitilde_bs_0_0 = 1;
12708
// Compute basisvalues
12709
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12711
// Table(s) of coefficients
12712
const static double coefficients0[1][1] = \
12713
{{1.41421356237309}};
12715
// Extract relevant coefficients
12716
const double coeff0_0 = coefficients0[dof][0];
12718
// Compute value(s)
12719
*values = coeff0_0*basisvalue0;
12722
/// Evaluate all basis functions at given point in cell
12723
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis_all(double* values,
12724
const double* coordinates,
12725
const ufc::cell& c) const
12727
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12730
/// Evaluate order n derivatives of basis function i at given point in cell
12731
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis_derivatives(unsigned int i,
12734
const double* coordinates,
12735
const ufc::cell& c) const
12737
// Extract vertex coordinates
12738
const double * const * element_coordinates = c.coordinates;
12740
// Compute Jacobian of affine map from reference cell
12741
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12742
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12743
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12744
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12746
// Compute determinant of Jacobian
12747
const double detJ = J_00*J_11 - J_01*J_10;
12749
// Compute inverse of Jacobian
12751
// Get coordinates and map to the reference (UFC) element
12752
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12753
element_coordinates[0][0]*element_coordinates[2][1] +\
12754
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12755
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12756
element_coordinates[1][0]*element_coordinates[0][1] -\
12757
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12759
// Map coordinates to the reference square
12760
if (std::abs(y - 1.0) < 1e-14)
12763
x = 2.0 *x/(1.0 - y) - 1.0;
12766
// Compute number of derivatives
12767
unsigned int num_derivatives = 1;
12769
for (unsigned int j = 0; j < n; j++)
12770
num_derivatives *= 2;
12773
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12774
unsigned int **combinations = new unsigned int *[num_derivatives];
12776
for (unsigned int j = 0; j < num_derivatives; j++)
12778
combinations[j] = new unsigned int [n];
12779
for (unsigned int k = 0; k < n; k++)
12780
combinations[j][k] = 0;
12783
// Generate combinations of derivatives
12784
for (unsigned int row = 1; row < num_derivatives; row++)
12786
for (unsigned int num = 0; num < row; num++)
12788
for (unsigned int col = n-1; col+1 > 0; col--)
12790
if (combinations[row][col] + 1 > 1)
12791
combinations[row][col] = 0;
12794
combinations[row][col] += 1;
12801
// Compute inverse of Jacobian
12802
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12804
// Declare transformation matrix
12805
// Declare pointer to two dimensional array and initialise
12806
double **transform = new double *[num_derivatives];
12808
for (unsigned int j = 0; j < num_derivatives; j++)
12810
transform[j] = new double [num_derivatives];
12811
for (unsigned int k = 0; k < num_derivatives; k++)
12812
transform[j][k] = 1;
12815
// Construct transformation matrix
12816
for (unsigned int row = 0; row < num_derivatives; row++)
12818
for (unsigned int col = 0; col < num_derivatives; col++)
12820
for (unsigned int k = 0; k < n; k++)
12821
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12826
for (unsigned int j = 0; j < 1*num_derivatives; j++)
12829
// Map degree of freedom to element degree of freedom
12830
const unsigned int dof = i;
12832
// Generate scalings
12833
const double scalings_y_0 = 1;
12835
// Compute psitilde_a
12836
const double psitilde_a_0 = 1;
12838
// Compute psitilde_bs
12839
const double psitilde_bs_0_0 = 1;
12841
// Compute basisvalues
12842
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12844
// Table(s) of coefficients
12845
const static double coefficients0[1][1] = \
12846
{{1.41421356237309}};
12848
// Interesting (new) part
12849
// Tables of derivatives of the polynomial base (transpose)
12850
const static double dmats0[1][1] = \
12853
const static double dmats1[1][1] = \
12856
// Compute reference derivatives
12857
// Declare pointer to array of derivatives on FIAT element
12858
double *derivatives = new double [num_derivatives];
12860
// Declare coefficients
12861
double coeff0_0 = 0;
12863
// Declare new coefficients
12864
double new_coeff0_0 = 0;
12866
// Loop possible derivatives
12867
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12869
// Get values from coefficients array
12870
new_coeff0_0 = coefficients0[dof][0];
12872
// Loop derivative order
12873
for (unsigned int j = 0; j < n; j++)
12875
// Update old coefficients
12876
coeff0_0 = new_coeff0_0;
12878
if(combinations[deriv_num][j] == 0)
12880
new_coeff0_0 = coeff0_0*dmats0[0][0];
12882
if(combinations[deriv_num][j] == 1)
12884
new_coeff0_0 = coeff0_0*dmats1[0][0];
12888
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12889
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
12892
// Transform derivatives back to physical element
12893
for (unsigned int row = 0; row < num_derivatives; row++)
12895
for (unsigned int col = 0; col < num_derivatives; col++)
12897
values[row] += transform[row][col]*derivatives[col];
12900
// Delete pointer to array of derivatives on FIAT element
12901
delete [] derivatives;
12903
// Delete pointer to array of combinations of derivatives and transform
12904
for (unsigned int row = 0; row < num_derivatives; row++)
12906
delete [] combinations[row];
12907
delete [] transform[row];
12910
delete [] combinations;
12911
delete [] transform;
12914
/// Evaluate order n derivatives of all basis functions at given point in cell
12915
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
12917
const double* coordinates,
12918
const ufc::cell& c) const
12920
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12923
/// Evaluate linear functional for dof i on the function f
12924
double UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_dof(unsigned int i,
12925
const ufc::function& f,
12926
const ufc::cell& c) const
12928
// The reference points, direction and weights:
12929
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
12930
const static double W[1][1] = {{1}};
12931
const static double D[1][1][1] = {{{1}}};
12933
const double * const * x = c.coordinates;
12934
double result = 0.0;
12935
// Iterate over the points:
12936
// Evaluate basis functions for affine mapping
12937
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12938
const double w1 = X[i][0][0];
12939
const double w2 = X[i][0][1];
12941
// Compute affine mapping y = F(X)
12943
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12944
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12946
// Evaluate function at physical points
12948
f.evaluate(values, y, c);
12950
// Map function values using appropriate mapping
12951
// Affine map: Do nothing
12953
// Note that we do not map the weights (yet).
12955
// Take directional components
12956
for(int k = 0; k < 1; k++)
12957
result += values[k]*D[i][0][k];
12958
// Multiply by weights
12964
/// Evaluate linear functionals for all dofs on the function f
12965
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_dofs(double* values,
12966
const ufc::function& f,
12967
const ufc::cell& c) const
12969
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12972
/// Interpolate vertex values from dof values
12973
void UFC_CahnHilliard2DLinearForm_finite_element_4::interpolate_vertex_values(double* vertex_values,
12974
const double* dof_values,
12975
const ufc::cell& c) const
12977
// Evaluate at vertices and use affine mapping
12978
vertex_values[0] = dof_values[0];
12979
vertex_values[1] = dof_values[0];
12980
vertex_values[2] = dof_values[0];
12983
/// Return the number of sub elements (for a mixed element)
12984
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::num_sub_elements() const
12989
/// Create a new finite element for sub element i (for a mixed element)
12990
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_4::create_sub_element(unsigned int i) const
12992
return new UFC_CahnHilliard2DLinearForm_finite_element_4();
12997
UFC_CahnHilliard2DLinearForm_finite_element_5::UFC_CahnHilliard2DLinearForm_finite_element_5() : ufc::finite_element()
13003
UFC_CahnHilliard2DLinearForm_finite_element_5::~UFC_CahnHilliard2DLinearForm_finite_element_5()
13008
/// Return a string identifying the finite element
13009
const char* UFC_CahnHilliard2DLinearForm_finite_element_5::signature() const
13011
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
13014
/// Return the cell shape
13015
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_5::cell_shape() const
13017
return ufc::triangle;
13020
/// Return the dimension of the finite element function space
13021
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::space_dimension() const
13026
/// Return the rank of the value space
13027
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::value_rank() const
13032
/// Return the dimension of the value space for axis i
13033
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::value_dimension(unsigned int i) const
13038
/// Evaluate basis function i at given point in cell
13039
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis(unsigned int i,
13041
const double* coordinates,
13042
const ufc::cell& c) const
13044
// Extract vertex coordinates
13045
const double * const * element_coordinates = c.coordinates;
13047
// Compute Jacobian of affine map from reference cell
13048
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13049
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13050
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13051
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13053
// Compute determinant of Jacobian
13054
const double detJ = J_00*J_11 - J_01*J_10;
13056
// Compute inverse of Jacobian
13058
// Get coordinates and map to the reference (UFC) element
13059
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13060
element_coordinates[0][0]*element_coordinates[2][1] +\
13061
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13062
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13063
element_coordinates[1][0]*element_coordinates[0][1] -\
13064
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13066
// Map coordinates to the reference square
13067
if (std::abs(y - 1.0) < 1e-14)
13070
x = 2.0 *x/(1.0 - y) - 1.0;
13076
// Map degree of freedom to element degree of freedom
13077
const unsigned int dof = i;
13079
// Generate scalings
13080
const double scalings_y_0 = 1;
13082
// Compute psitilde_a
13083
const double psitilde_a_0 = 1;
13085
// Compute psitilde_bs
13086
const double psitilde_bs_0_0 = 1;
13088
// Compute basisvalues
13089
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13091
// Table(s) of coefficients
13092
const static double coefficients0[1][1] = \
13093
{{1.41421356237309}};
13095
// Extract relevant coefficients
13096
const double coeff0_0 = coefficients0[dof][0];
13098
// Compute value(s)
13099
*values = coeff0_0*basisvalue0;
13102
/// Evaluate all basis functions at given point in cell
13103
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis_all(double* values,
13104
const double* coordinates,
13105
const ufc::cell& c) const
13107
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
13110
/// Evaluate order n derivatives of basis function i at given point in cell
13111
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis_derivatives(unsigned int i,
13114
const double* coordinates,
13115
const ufc::cell& c) const
13117
// Extract vertex coordinates
13118
const double * const * element_coordinates = c.coordinates;
13120
// Compute Jacobian of affine map from reference cell
13121
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13122
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13123
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13124
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13126
// Compute determinant of Jacobian
13127
const double detJ = J_00*J_11 - J_01*J_10;
13129
// Compute inverse of Jacobian
13131
// Get coordinates and map to the reference (UFC) element
13132
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13133
element_coordinates[0][0]*element_coordinates[2][1] +\
13134
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13135
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13136
element_coordinates[1][0]*element_coordinates[0][1] -\
13137
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13139
// Map coordinates to the reference square
13140
if (std::abs(y - 1.0) < 1e-14)
13143
x = 2.0 *x/(1.0 - y) - 1.0;
13146
// Compute number of derivatives
13147
unsigned int num_derivatives = 1;
13149
for (unsigned int j = 0; j < n; j++)
13150
num_derivatives *= 2;
13153
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
13154
unsigned int **combinations = new unsigned int *[num_derivatives];
13156
for (unsigned int j = 0; j < num_derivatives; j++)
13158
combinations[j] = new unsigned int [n];
13159
for (unsigned int k = 0; k < n; k++)
13160
combinations[j][k] = 0;
13163
// Generate combinations of derivatives
13164
for (unsigned int row = 1; row < num_derivatives; row++)
13166
for (unsigned int num = 0; num < row; num++)
13168
for (unsigned int col = n-1; col+1 > 0; col--)
13170
if (combinations[row][col] + 1 > 1)
13171
combinations[row][col] = 0;
13174
combinations[row][col] += 1;
13181
// Compute inverse of Jacobian
13182
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
13184
// Declare transformation matrix
13185
// Declare pointer to two dimensional array and initialise
13186
double **transform = new double *[num_derivatives];
13188
for (unsigned int j = 0; j < num_derivatives; j++)
13190
transform[j] = new double [num_derivatives];
13191
for (unsigned int k = 0; k < num_derivatives; k++)
13192
transform[j][k] = 1;
13195
// Construct transformation matrix
13196
for (unsigned int row = 0; row < num_derivatives; row++)
13198
for (unsigned int col = 0; col < num_derivatives; col++)
13200
for (unsigned int k = 0; k < n; k++)
13201
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13206
for (unsigned int j = 0; j < 1*num_derivatives; j++)
13209
// Map degree of freedom to element degree of freedom
13210
const unsigned int dof = i;
13212
// Generate scalings
13213
const double scalings_y_0 = 1;
13215
// Compute psitilde_a
13216
const double psitilde_a_0 = 1;
13218
// Compute psitilde_bs
13219
const double psitilde_bs_0_0 = 1;
13221
// Compute basisvalues
13222
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13224
// Table(s) of coefficients
13225
const static double coefficients0[1][1] = \
13226
{{1.41421356237309}};
13228
// Interesting (new) part
13229
// Tables of derivatives of the polynomial base (transpose)
13230
const static double dmats0[1][1] = \
13233
const static double dmats1[1][1] = \
13236
// Compute reference derivatives
13237
// Declare pointer to array of derivatives on FIAT element
13238
double *derivatives = new double [num_derivatives];
13240
// Declare coefficients
13241
double coeff0_0 = 0;
13243
// Declare new coefficients
13244
double new_coeff0_0 = 0;
13246
// Loop possible derivatives
13247
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13249
// Get values from coefficients array
13250
new_coeff0_0 = coefficients0[dof][0];
13252
// Loop derivative order
13253
for (unsigned int j = 0; j < n; j++)
13255
// Update old coefficients
13256
coeff0_0 = new_coeff0_0;
13258
if(combinations[deriv_num][j] == 0)
13260
new_coeff0_0 = coeff0_0*dmats0[0][0];
13262
if(combinations[deriv_num][j] == 1)
13264
new_coeff0_0 = coeff0_0*dmats1[0][0];
13268
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13269
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
13272
// Transform derivatives back to physical element
13273
for (unsigned int row = 0; row < num_derivatives; row++)
13275
for (unsigned int col = 0; col < num_derivatives; col++)
13277
values[row] += transform[row][col]*derivatives[col];
13280
// Delete pointer to array of derivatives on FIAT element
13281
delete [] derivatives;
13283
// Delete pointer to array of combinations of derivatives and transform
13284
for (unsigned int row = 0; row < num_derivatives; row++)
13286
delete [] combinations[row];
13287
delete [] transform[row];
13290
delete [] combinations;
13291
delete [] transform;
13294
/// Evaluate order n derivatives of all basis functions at given point in cell
13295
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
13297
const double* coordinates,
13298
const ufc::cell& c) const
13300
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13303
/// Evaluate linear functional for dof i on the function f
13304
double UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_dof(unsigned int i,
13305
const ufc::function& f,
13306
const ufc::cell& c) const
13308
// The reference points, direction and weights:
13309
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
13310
const static double W[1][1] = {{1}};
13311
const static double D[1][1][1] = {{{1}}};
13313
const double * const * x = c.coordinates;
13314
double result = 0.0;
13315
// Iterate over the points:
13316
// Evaluate basis functions for affine mapping
13317
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
13318
const double w1 = X[i][0][0];
13319
const double w2 = X[i][0][1];
13321
// Compute affine mapping y = F(X)
13323
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
13324
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
13326
// Evaluate function at physical points
13328
f.evaluate(values, y, c);
13330
// Map function values using appropriate mapping
13331
// Affine map: Do nothing
13333
// Note that we do not map the weights (yet).
13335
// Take directional components
13336
for(int k = 0; k < 1; k++)
13337
result += values[k]*D[i][0][k];
13338
// Multiply by weights
13344
/// Evaluate linear functionals for all dofs on the function f
13345
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_dofs(double* values,
13346
const ufc::function& f,
13347
const ufc::cell& c) const
13349
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13352
/// Interpolate vertex values from dof values
13353
void UFC_CahnHilliard2DLinearForm_finite_element_5::interpolate_vertex_values(double* vertex_values,
13354
const double* dof_values,
13355
const ufc::cell& c) const
13357
// Evaluate at vertices and use affine mapping
13358
vertex_values[0] = dof_values[0];
13359
vertex_values[1] = dof_values[0];
13360
vertex_values[2] = dof_values[0];
13363
/// Return the number of sub elements (for a mixed element)
13364
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::num_sub_elements() const
13369
/// Create a new finite element for sub element i (for a mixed element)
13370
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_5::create_sub_element(unsigned int i) const
13372
return new UFC_CahnHilliard2DLinearForm_finite_element_5();
13377
UFC_CahnHilliard2DLinearForm_finite_element_6::UFC_CahnHilliard2DLinearForm_finite_element_6() : ufc::finite_element()
13383
UFC_CahnHilliard2DLinearForm_finite_element_6::~UFC_CahnHilliard2DLinearForm_finite_element_6()
13388
/// Return a string identifying the finite element
13389
const char* UFC_CahnHilliard2DLinearForm_finite_element_6::signature() const
13391
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
13394
/// Return the cell shape
13395
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_6::cell_shape() const
13397
return ufc::triangle;
13400
/// Return the dimension of the finite element function space
13401
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::space_dimension() const
13406
/// Return the rank of the value space
13407
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::value_rank() const
13412
/// Return the dimension of the value space for axis i
13413
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::value_dimension(unsigned int i) const
13418
/// Evaluate basis function i at given point in cell
13419
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis(unsigned int i,
13421
const double* coordinates,
13422
const ufc::cell& c) const
13424
// Extract vertex coordinates
13425
const double * const * element_coordinates = c.coordinates;
13427
// Compute Jacobian of affine map from reference cell
13428
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13429
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13430
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13431
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13433
// Compute determinant of Jacobian
13434
const double detJ = J_00*J_11 - J_01*J_10;
13436
// Compute inverse of Jacobian
13438
// Get coordinates and map to the reference (UFC) element
13439
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13440
element_coordinates[0][0]*element_coordinates[2][1] +\
13441
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13442
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13443
element_coordinates[1][0]*element_coordinates[0][1] -\
13444
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13446
// Map coordinates to the reference square
13447
if (std::abs(y - 1.0) < 1e-14)
13450
x = 2.0 *x/(1.0 - y) - 1.0;
13456
// Map degree of freedom to element degree of freedom
13457
const unsigned int dof = i;
13459
// Generate scalings
13460
const double scalings_y_0 = 1;
13462
// Compute psitilde_a
13463
const double psitilde_a_0 = 1;
13465
// Compute psitilde_bs
13466
const double psitilde_bs_0_0 = 1;
13468
// Compute basisvalues
13469
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13471
// Table(s) of coefficients
13472
const static double coefficients0[1][1] = \
13473
{{1.41421356237309}};
13475
// Extract relevant coefficients
13476
const double coeff0_0 = coefficients0[dof][0];
13478
// Compute value(s)
13479
*values = coeff0_0*basisvalue0;
13482
/// Evaluate all basis functions at given point in cell
13483
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis_all(double* values,
13484
const double* coordinates,
13485
const ufc::cell& c) const
13487
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
13490
/// Evaluate order n derivatives of basis function i at given point in cell
13491
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis_derivatives(unsigned int i,
13494
const double* coordinates,
13495
const ufc::cell& c) const
13497
// Extract vertex coordinates
13498
const double * const * element_coordinates = c.coordinates;
13500
// Compute Jacobian of affine map from reference cell
13501
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13502
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13503
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13504
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13506
// Compute determinant of Jacobian
13507
const double detJ = J_00*J_11 - J_01*J_10;
13509
// Compute inverse of Jacobian
13511
// Get coordinates and map to the reference (UFC) element
13512
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13513
element_coordinates[0][0]*element_coordinates[2][1] +\
13514
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13515
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13516
element_coordinates[1][0]*element_coordinates[0][1] -\
13517
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13519
// Map coordinates to the reference square
13520
if (std::abs(y - 1.0) < 1e-14)
13523
x = 2.0 *x/(1.0 - y) - 1.0;
13526
// Compute number of derivatives
13527
unsigned int num_derivatives = 1;
13529
for (unsigned int j = 0; j < n; j++)
13530
num_derivatives *= 2;
13533
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
13534
unsigned int **combinations = new unsigned int *[num_derivatives];
13536
for (unsigned int j = 0; j < num_derivatives; j++)
13538
combinations[j] = new unsigned int [n];
13539
for (unsigned int k = 0; k < n; k++)
13540
combinations[j][k] = 0;
13543
// Generate combinations of derivatives
13544
for (unsigned int row = 1; row < num_derivatives; row++)
13546
for (unsigned int num = 0; num < row; num++)
13548
for (unsigned int col = n-1; col+1 > 0; col--)
13550
if (combinations[row][col] + 1 > 1)
13551
combinations[row][col] = 0;
13554
combinations[row][col] += 1;
13561
// Compute inverse of Jacobian
13562
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
13564
// Declare transformation matrix
13565
// Declare pointer to two dimensional array and initialise
13566
double **transform = new double *[num_derivatives];
13568
for (unsigned int j = 0; j < num_derivatives; j++)
13570
transform[j] = new double [num_derivatives];
13571
for (unsigned int k = 0; k < num_derivatives; k++)
13572
transform[j][k] = 1;
13575
// Construct transformation matrix
13576
for (unsigned int row = 0; row < num_derivatives; row++)
13578
for (unsigned int col = 0; col < num_derivatives; col++)
13580
for (unsigned int k = 0; k < n; k++)
13581
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13586
for (unsigned int j = 0; j < 1*num_derivatives; j++)
13589
// Map degree of freedom to element degree of freedom
13590
const unsigned int dof = i;
13592
// Generate scalings
13593
const double scalings_y_0 = 1;
13595
// Compute psitilde_a
13596
const double psitilde_a_0 = 1;
13598
// Compute psitilde_bs
13599
const double psitilde_bs_0_0 = 1;
13601
// Compute basisvalues
13602
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13604
// Table(s) of coefficients
13605
const static double coefficients0[1][1] = \
13606
{{1.41421356237309}};
13608
// Interesting (new) part
13609
// Tables of derivatives of the polynomial base (transpose)
13610
const static double dmats0[1][1] = \
13613
const static double dmats1[1][1] = \
13616
// Compute reference derivatives
13617
// Declare pointer to array of derivatives on FIAT element
13618
double *derivatives = new double [num_derivatives];
13620
// Declare coefficients
13621
double coeff0_0 = 0;
13623
// Declare new coefficients
13624
double new_coeff0_0 = 0;
13626
// Loop possible derivatives
13627
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13629
// Get values from coefficients array
13630
new_coeff0_0 = coefficients0[dof][0];
13632
// Loop derivative order
13633
for (unsigned int j = 0; j < n; j++)
13635
// Update old coefficients
13636
coeff0_0 = new_coeff0_0;
13638
if(combinations[deriv_num][j] == 0)
13640
new_coeff0_0 = coeff0_0*dmats0[0][0];
13642
if(combinations[deriv_num][j] == 1)
13644
new_coeff0_0 = coeff0_0*dmats1[0][0];
13648
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13649
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
13652
// Transform derivatives back to physical element
13653
for (unsigned int row = 0; row < num_derivatives; row++)
13655
for (unsigned int col = 0; col < num_derivatives; col++)
13657
values[row] += transform[row][col]*derivatives[col];
13660
// Delete pointer to array of derivatives on FIAT element
13661
delete [] derivatives;
13663
// Delete pointer to array of combinations of derivatives and transform
13664
for (unsigned int row = 0; row < num_derivatives; row++)
13666
delete [] combinations[row];
13667
delete [] transform[row];
13670
delete [] combinations;
13671
delete [] transform;
13674
/// Evaluate order n derivatives of all basis functions at given point in cell
13675
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
13677
const double* coordinates,
13678
const ufc::cell& c) const
13680
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13683
/// Evaluate linear functional for dof i on the function f
13684
double UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_dof(unsigned int i,
13685
const ufc::function& f,
13686
const ufc::cell& c) const
13688
// The reference points, direction and weights:
13689
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
13690
const static double W[1][1] = {{1}};
13691
const static double D[1][1][1] = {{{1}}};
13693
const double * const * x = c.coordinates;
13694
double result = 0.0;
13695
// Iterate over the points:
13696
// Evaluate basis functions for affine mapping
13697
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
13698
const double w1 = X[i][0][0];
13699
const double w2 = X[i][0][1];
13701
// Compute affine mapping y = F(X)
13703
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
13704
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
13706
// Evaluate function at physical points
13708
f.evaluate(values, y, c);
13710
// Map function values using appropriate mapping
13711
// Affine map: Do nothing
13713
// Note that we do not map the weights (yet).
13715
// Take directional components
13716
for(int k = 0; k < 1; k++)
13717
result += values[k]*D[i][0][k];
13718
// Multiply by weights
13724
/// Evaluate linear functionals for all dofs on the function f
13725
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_dofs(double* values,
13726
const ufc::function& f,
13727
const ufc::cell& c) const
13729
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13732
/// Interpolate vertex values from dof values
13733
void UFC_CahnHilliard2DLinearForm_finite_element_6::interpolate_vertex_values(double* vertex_values,
13734
const double* dof_values,
13735
const ufc::cell& c) const
13737
// Evaluate at vertices and use affine mapping
13738
vertex_values[0] = dof_values[0];
13739
vertex_values[1] = dof_values[0];
13740
vertex_values[2] = dof_values[0];
13743
/// Return the number of sub elements (for a mixed element)
13744
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::num_sub_elements() const
13749
/// Create a new finite element for sub element i (for a mixed element)
13750
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_6::create_sub_element(unsigned int i) const
13752
return new UFC_CahnHilliard2DLinearForm_finite_element_6();
13756
UFC_CahnHilliard2DLinearForm_dof_map_0_0::UFC_CahnHilliard2DLinearForm_dof_map_0_0() : ufc::dof_map()
13758
__global_dimension = 0;
13762
UFC_CahnHilliard2DLinearForm_dof_map_0_0::~UFC_CahnHilliard2DLinearForm_dof_map_0_0()
13767
/// Return a string identifying the dof map
13768
const char* UFC_CahnHilliard2DLinearForm_dof_map_0_0::signature() const
13770
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
13773
/// Return true iff mesh entities of topological dimension d are needed
13774
bool UFC_CahnHilliard2DLinearForm_dof_map_0_0::needs_mesh_entities(unsigned int d) const
13791
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13792
bool UFC_CahnHilliard2DLinearForm_dof_map_0_0::init_mesh(const ufc::mesh& m)
13794
__global_dimension = m.num_entities[0];
13798
/// Initialize dof map for given cell
13799
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::init_cell(const ufc::mesh& m,
13800
const ufc::cell& c)
13805
/// Finish initialization of dof map for cells
13806
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::init_cell_finalize()
13811
/// Return the dimension of the global finite element function space
13812
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::global_dimension() const
13814
return __global_dimension;
13817
/// Return the dimension of the local finite element function space
13818
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::local_dimension() const
13823
// Return the geometric dimension of the coordinates this dof map provides
13824
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::geometric_dimension() const
13829
/// Return the number of dofs on each cell facet
13830
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::num_facet_dofs() const
13835
/// Return the number of dofs associated with each cell entity of dimension d
13836
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::num_entity_dofs(unsigned int d) const
13838
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13841
/// Tabulate the local-to-global mapping of dofs on a cell
13842
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
13843
const ufc::mesh& m,
13844
const ufc::cell& c) const
13846
dofs[0] = c.entity_indices[0][0];
13847
dofs[1] = c.entity_indices[0][1];
13848
dofs[2] = c.entity_indices[0][2];
13851
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
13852
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
13853
unsigned int facet) const
13872
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
13873
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
13874
unsigned int d, unsigned int i) const
13876
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13879
/// Tabulate the coordinates of all dofs on a cell
13880
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_coordinates(double** coordinates,
13881
const ufc::cell& c) const
13883
const double * const * x = c.coordinates;
13884
coordinates[0][0] = x[0][0];
13885
coordinates[0][1] = x[0][1];
13886
coordinates[1][0] = x[1][0];
13887
coordinates[1][1] = x[1][1];
13888
coordinates[2][0] = x[2][0];
13889
coordinates[2][1] = x[2][1];
13892
/// Return the number of sub dof maps (for a mixed element)
13893
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::num_sub_dof_maps() const
13898
/// Create a new dof_map for sub dof map i (for a mixed element)
13899
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_0_0::create_sub_dof_map(unsigned int i) const
13901
return new UFC_CahnHilliard2DLinearForm_dof_map_0_0();
13906
UFC_CahnHilliard2DLinearForm_dof_map_0_1::UFC_CahnHilliard2DLinearForm_dof_map_0_1() : ufc::dof_map()
13908
__global_dimension = 0;
13912
UFC_CahnHilliard2DLinearForm_dof_map_0_1::~UFC_CahnHilliard2DLinearForm_dof_map_0_1()
13917
/// Return a string identifying the dof map
13918
const char* UFC_CahnHilliard2DLinearForm_dof_map_0_1::signature() const
13920
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
13923
/// Return true iff mesh entities of topological dimension d are needed
13924
bool UFC_CahnHilliard2DLinearForm_dof_map_0_1::needs_mesh_entities(unsigned int d) const
13941
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13942
bool UFC_CahnHilliard2DLinearForm_dof_map_0_1::init_mesh(const ufc::mesh& m)
13944
__global_dimension = m.num_entities[0];
13948
/// Initialize dof map for given cell
13949
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::init_cell(const ufc::mesh& m,
13950
const ufc::cell& c)
13955
/// Finish initialization of dof map for cells
13956
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::init_cell_finalize()
13961
/// Return the dimension of the global finite element function space
13962
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::global_dimension() const
13964
return __global_dimension;
13967
/// Return the dimension of the local finite element function space
13968
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::local_dimension() const
13973
// Return the geometric dimension of the coordinates this dof map provides
13974
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::geometric_dimension() const
13979
/// Return the number of dofs on each cell facet
13980
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::num_facet_dofs() const
13985
/// Return the number of dofs associated with each cell entity of dimension d
13986
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::num_entity_dofs(unsigned int d) const
13988
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13991
/// Tabulate the local-to-global mapping of dofs on a cell
13992
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
13993
const ufc::mesh& m,
13994
const ufc::cell& c) const
13996
dofs[0] = c.entity_indices[0][0];
13997
dofs[1] = c.entity_indices[0][1];
13998
dofs[2] = c.entity_indices[0][2];
14001
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14002
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
14003
unsigned int facet) const
14022
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14023
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
14024
unsigned int d, unsigned int i) const
14026
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14029
/// Tabulate the coordinates of all dofs on a cell
14030
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_coordinates(double** coordinates,
14031
const ufc::cell& c) const
14033
const double * const * x = c.coordinates;
14034
coordinates[0][0] = x[0][0];
14035
coordinates[0][1] = x[0][1];
14036
coordinates[1][0] = x[1][0];
14037
coordinates[1][1] = x[1][1];
14038
coordinates[2][0] = x[2][0];
14039
coordinates[2][1] = x[2][1];
14042
/// Return the number of sub dof maps (for a mixed element)
14043
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::num_sub_dof_maps() const
14048
/// Create a new dof_map for sub dof map i (for a mixed element)
14049
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_0_1::create_sub_dof_map(unsigned int i) const
14051
return new UFC_CahnHilliard2DLinearForm_dof_map_0_1();
14056
UFC_CahnHilliard2DLinearForm_dof_map_0::UFC_CahnHilliard2DLinearForm_dof_map_0() : ufc::dof_map()
14058
__global_dimension = 0;
14062
UFC_CahnHilliard2DLinearForm_dof_map_0::~UFC_CahnHilliard2DLinearForm_dof_map_0()
14067
/// Return a string identifying the dof map
14068
const char* UFC_CahnHilliard2DLinearForm_dof_map_0::signature() const
14070
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
14073
/// Return true iff mesh entities of topological dimension d are needed
14074
bool UFC_CahnHilliard2DLinearForm_dof_map_0::needs_mesh_entities(unsigned int d) const
14091
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14092
bool UFC_CahnHilliard2DLinearForm_dof_map_0::init_mesh(const ufc::mesh& m)
14094
__global_dimension = 2*m.num_entities[0];
14098
/// Initialize dof map for given cell
14099
void UFC_CahnHilliard2DLinearForm_dof_map_0::init_cell(const ufc::mesh& m,
14100
const ufc::cell& c)
14105
/// Finish initialization of dof map for cells
14106
void UFC_CahnHilliard2DLinearForm_dof_map_0::init_cell_finalize()
14111
/// Return the dimension of the global finite element function space
14112
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::global_dimension() const
14114
return __global_dimension;
14117
/// Return the dimension of the local finite element function space
14118
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::local_dimension() const
14123
// Return the geometric dimension of the coordinates this dof map provides
14124
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::geometric_dimension() const
14129
/// Return the number of dofs on each cell facet
14130
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::num_facet_dofs() const
14135
/// Return the number of dofs associated with each cell entity of dimension d
14136
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::num_entity_dofs(unsigned int d) const
14138
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14141
/// Tabulate the local-to-global mapping of dofs on a cell
14142
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_dofs(unsigned int* dofs,
14143
const ufc::mesh& m,
14144
const ufc::cell& c) const
14146
dofs[0] = c.entity_indices[0][0];
14147
dofs[1] = c.entity_indices[0][1];
14148
dofs[2] = c.entity_indices[0][2];
14149
unsigned int offset = m.num_entities[0];
14150
dofs[3] = offset + c.entity_indices[0][0];
14151
dofs[4] = offset + c.entity_indices[0][1];
14152
dofs[5] = offset + c.entity_indices[0][2];
14155
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14156
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
14157
unsigned int facet) const
14182
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14183
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
14184
unsigned int d, unsigned int i) const
14186
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14189
/// Tabulate the coordinates of all dofs on a cell
14190
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_coordinates(double** coordinates,
14191
const ufc::cell& c) const
14193
const double * const * x = c.coordinates;
14194
coordinates[0][0] = x[0][0];
14195
coordinates[0][1] = x[0][1];
14196
coordinates[1][0] = x[1][0];
14197
coordinates[1][1] = x[1][1];
14198
coordinates[2][0] = x[2][0];
14199
coordinates[2][1] = x[2][1];
14200
coordinates[3][0] = x[0][0];
14201
coordinates[3][1] = x[0][1];
14202
coordinates[4][0] = x[1][0];
14203
coordinates[4][1] = x[1][1];
14204
coordinates[5][0] = x[2][0];
14205
coordinates[5][1] = x[2][1];
14208
/// Return the number of sub dof maps (for a mixed element)
14209
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::num_sub_dof_maps() const
14214
/// Create a new dof_map for sub dof map i (for a mixed element)
14215
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_0::create_sub_dof_map(unsigned int i) const
14220
return new UFC_CahnHilliard2DLinearForm_dof_map_0_0();
14223
return new UFC_CahnHilliard2DLinearForm_dof_map_0_1();
14231
UFC_CahnHilliard2DLinearForm_dof_map_1_0::UFC_CahnHilliard2DLinearForm_dof_map_1_0() : ufc::dof_map()
14233
__global_dimension = 0;
14237
UFC_CahnHilliard2DLinearForm_dof_map_1_0::~UFC_CahnHilliard2DLinearForm_dof_map_1_0()
14242
/// Return a string identifying the dof map
14243
const char* UFC_CahnHilliard2DLinearForm_dof_map_1_0::signature() const
14245
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14248
/// Return true iff mesh entities of topological dimension d are needed
14249
bool UFC_CahnHilliard2DLinearForm_dof_map_1_0::needs_mesh_entities(unsigned int d) const
14266
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14267
bool UFC_CahnHilliard2DLinearForm_dof_map_1_0::init_mesh(const ufc::mesh& m)
14269
__global_dimension = m.num_entities[0];
14273
/// Initialize dof map for given cell
14274
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::init_cell(const ufc::mesh& m,
14275
const ufc::cell& c)
14280
/// Finish initialization of dof map for cells
14281
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::init_cell_finalize()
14286
/// Return the dimension of the global finite element function space
14287
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::global_dimension() const
14289
return __global_dimension;
14292
/// Return the dimension of the local finite element function space
14293
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::local_dimension() const
14298
// Return the geometric dimension of the coordinates this dof map provides
14299
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::geometric_dimension() const
14304
/// Return the number of dofs on each cell facet
14305
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::num_facet_dofs() const
14310
/// Return the number of dofs associated with each cell entity of dimension d
14311
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::num_entity_dofs(unsigned int d) const
14313
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14316
/// Tabulate the local-to-global mapping of dofs on a cell
14317
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
14318
const ufc::mesh& m,
14319
const ufc::cell& c) const
14321
dofs[0] = c.entity_indices[0][0];
14322
dofs[1] = c.entity_indices[0][1];
14323
dofs[2] = c.entity_indices[0][2];
14326
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14327
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
14328
unsigned int facet) const
14347
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14348
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
14349
unsigned int d, unsigned int i) const
14351
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14354
/// Tabulate the coordinates of all dofs on a cell
14355
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_coordinates(double** coordinates,
14356
const ufc::cell& c) const
14358
const double * const * x = c.coordinates;
14359
coordinates[0][0] = x[0][0];
14360
coordinates[0][1] = x[0][1];
14361
coordinates[1][0] = x[1][0];
14362
coordinates[1][1] = x[1][1];
14363
coordinates[2][0] = x[2][0];
14364
coordinates[2][1] = x[2][1];
14367
/// Return the number of sub dof maps (for a mixed element)
14368
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::num_sub_dof_maps() const
14373
/// Create a new dof_map for sub dof map i (for a mixed element)
14374
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_1_0::create_sub_dof_map(unsigned int i) const
14376
return new UFC_CahnHilliard2DLinearForm_dof_map_1_0();
14381
UFC_CahnHilliard2DLinearForm_dof_map_1_1::UFC_CahnHilliard2DLinearForm_dof_map_1_1() : ufc::dof_map()
14383
__global_dimension = 0;
14387
UFC_CahnHilliard2DLinearForm_dof_map_1_1::~UFC_CahnHilliard2DLinearForm_dof_map_1_1()
14392
/// Return a string identifying the dof map
14393
const char* UFC_CahnHilliard2DLinearForm_dof_map_1_1::signature() const
14395
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14398
/// Return true iff mesh entities of topological dimension d are needed
14399
bool UFC_CahnHilliard2DLinearForm_dof_map_1_1::needs_mesh_entities(unsigned int d) const
14416
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14417
bool UFC_CahnHilliard2DLinearForm_dof_map_1_1::init_mesh(const ufc::mesh& m)
14419
__global_dimension = m.num_entities[0];
14423
/// Initialize dof map for given cell
14424
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::init_cell(const ufc::mesh& m,
14425
const ufc::cell& c)
14430
/// Finish initialization of dof map for cells
14431
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::init_cell_finalize()
14436
/// Return the dimension of the global finite element function space
14437
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::global_dimension() const
14439
return __global_dimension;
14442
/// Return the dimension of the local finite element function space
14443
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::local_dimension() const
14448
// Return the geometric dimension of the coordinates this dof map provides
14449
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::geometric_dimension() const
14454
/// Return the number of dofs on each cell facet
14455
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::num_facet_dofs() const
14460
/// Return the number of dofs associated with each cell entity of dimension d
14461
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::num_entity_dofs(unsigned int d) const
14463
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14466
/// Tabulate the local-to-global mapping of dofs on a cell
14467
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
14468
const ufc::mesh& m,
14469
const ufc::cell& c) const
14471
dofs[0] = c.entity_indices[0][0];
14472
dofs[1] = c.entity_indices[0][1];
14473
dofs[2] = c.entity_indices[0][2];
14476
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14477
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
14478
unsigned int facet) const
14497
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14498
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
14499
unsigned int d, unsigned int i) const
14501
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14504
/// Tabulate the coordinates of all dofs on a cell
14505
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_coordinates(double** coordinates,
14506
const ufc::cell& c) const
14508
const double * const * x = c.coordinates;
14509
coordinates[0][0] = x[0][0];
14510
coordinates[0][1] = x[0][1];
14511
coordinates[1][0] = x[1][0];
14512
coordinates[1][1] = x[1][1];
14513
coordinates[2][0] = x[2][0];
14514
coordinates[2][1] = x[2][1];
14517
/// Return the number of sub dof maps (for a mixed element)
14518
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::num_sub_dof_maps() const
14523
/// Create a new dof_map for sub dof map i (for a mixed element)
14524
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_1_1::create_sub_dof_map(unsigned int i) const
14526
return new UFC_CahnHilliard2DLinearForm_dof_map_1_1();
14531
UFC_CahnHilliard2DLinearForm_dof_map_1::UFC_CahnHilliard2DLinearForm_dof_map_1() : ufc::dof_map()
14533
__global_dimension = 0;
14537
UFC_CahnHilliard2DLinearForm_dof_map_1::~UFC_CahnHilliard2DLinearForm_dof_map_1()
14542
/// Return a string identifying the dof map
14543
const char* UFC_CahnHilliard2DLinearForm_dof_map_1::signature() const
14545
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
14548
/// Return true iff mesh entities of topological dimension d are needed
14549
bool UFC_CahnHilliard2DLinearForm_dof_map_1::needs_mesh_entities(unsigned int d) const
14566
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14567
bool UFC_CahnHilliard2DLinearForm_dof_map_1::init_mesh(const ufc::mesh& m)
14569
__global_dimension = 2*m.num_entities[0];
14573
/// Initialize dof map for given cell
14574
void UFC_CahnHilliard2DLinearForm_dof_map_1::init_cell(const ufc::mesh& m,
14575
const ufc::cell& c)
14580
/// Finish initialization of dof map for cells
14581
void UFC_CahnHilliard2DLinearForm_dof_map_1::init_cell_finalize()
14586
/// Return the dimension of the global finite element function space
14587
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::global_dimension() const
14589
return __global_dimension;
14592
/// Return the dimension of the local finite element function space
14593
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::local_dimension() const
14598
// Return the geometric dimension of the coordinates this dof map provides
14599
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::geometric_dimension() const
14604
/// Return the number of dofs on each cell facet
14605
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::num_facet_dofs() const
14610
/// Return the number of dofs associated with each cell entity of dimension d
14611
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::num_entity_dofs(unsigned int d) const
14613
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14616
/// Tabulate the local-to-global mapping of dofs on a cell
14617
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_dofs(unsigned int* dofs,
14618
const ufc::mesh& m,
14619
const ufc::cell& c) const
14621
dofs[0] = c.entity_indices[0][0];
14622
dofs[1] = c.entity_indices[0][1];
14623
dofs[2] = c.entity_indices[0][2];
14624
unsigned int offset = m.num_entities[0];
14625
dofs[3] = offset + c.entity_indices[0][0];
14626
dofs[4] = offset + c.entity_indices[0][1];
14627
dofs[5] = offset + c.entity_indices[0][2];
14630
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14631
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
14632
unsigned int facet) const
14657
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14658
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
14659
unsigned int d, unsigned int i) const
14661
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14664
/// Tabulate the coordinates of all dofs on a cell
14665
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_coordinates(double** coordinates,
14666
const ufc::cell& c) const
14668
const double * const * x = c.coordinates;
14669
coordinates[0][0] = x[0][0];
14670
coordinates[0][1] = x[0][1];
14671
coordinates[1][0] = x[1][0];
14672
coordinates[1][1] = x[1][1];
14673
coordinates[2][0] = x[2][0];
14674
coordinates[2][1] = x[2][1];
14675
coordinates[3][0] = x[0][0];
14676
coordinates[3][1] = x[0][1];
14677
coordinates[4][0] = x[1][0];
14678
coordinates[4][1] = x[1][1];
14679
coordinates[5][0] = x[2][0];
14680
coordinates[5][1] = x[2][1];
14683
/// Return the number of sub dof maps (for a mixed element)
14684
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::num_sub_dof_maps() const
14689
/// Create a new dof_map for sub dof map i (for a mixed element)
14690
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_1::create_sub_dof_map(unsigned int i) const
14695
return new UFC_CahnHilliard2DLinearForm_dof_map_1_0();
14698
return new UFC_CahnHilliard2DLinearForm_dof_map_1_1();
14706
UFC_CahnHilliard2DLinearForm_dof_map_2_0::UFC_CahnHilliard2DLinearForm_dof_map_2_0() : ufc::dof_map()
14708
__global_dimension = 0;
14712
UFC_CahnHilliard2DLinearForm_dof_map_2_0::~UFC_CahnHilliard2DLinearForm_dof_map_2_0()
14717
/// Return a string identifying the dof map
14718
const char* UFC_CahnHilliard2DLinearForm_dof_map_2_0::signature() const
14720
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14723
/// Return true iff mesh entities of topological dimension d are needed
14724
bool UFC_CahnHilliard2DLinearForm_dof_map_2_0::needs_mesh_entities(unsigned int d) const
14741
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14742
bool UFC_CahnHilliard2DLinearForm_dof_map_2_0::init_mesh(const ufc::mesh& m)
14744
__global_dimension = m.num_entities[0];
14748
/// Initialize dof map for given cell
14749
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::init_cell(const ufc::mesh& m,
14750
const ufc::cell& c)
14755
/// Finish initialization of dof map for cells
14756
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::init_cell_finalize()
14761
/// Return the dimension of the global finite element function space
14762
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::global_dimension() const
14764
return __global_dimension;
14767
/// Return the dimension of the local finite element function space
14768
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::local_dimension() const
14773
// Return the geometric dimension of the coordinates this dof map provides
14774
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::geometric_dimension() const
14779
/// Return the number of dofs on each cell facet
14780
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::num_facet_dofs() const
14785
/// Return the number of dofs associated with each cell entity of dimension d
14786
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::num_entity_dofs(unsigned int d) const
14788
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14791
/// Tabulate the local-to-global mapping of dofs on a cell
14792
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
14793
const ufc::mesh& m,
14794
const ufc::cell& c) const
14796
dofs[0] = c.entity_indices[0][0];
14797
dofs[1] = c.entity_indices[0][1];
14798
dofs[2] = c.entity_indices[0][2];
14801
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14802
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
14803
unsigned int facet) const
14822
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14823
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
14824
unsigned int d, unsigned int i) const
14826
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14829
/// Tabulate the coordinates of all dofs on a cell
14830
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_coordinates(double** coordinates,
14831
const ufc::cell& c) const
14833
const double * const * x = c.coordinates;
14834
coordinates[0][0] = x[0][0];
14835
coordinates[0][1] = x[0][1];
14836
coordinates[1][0] = x[1][0];
14837
coordinates[1][1] = x[1][1];
14838
coordinates[2][0] = x[2][0];
14839
coordinates[2][1] = x[2][1];
14842
/// Return the number of sub dof maps (for a mixed element)
14843
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::num_sub_dof_maps() const
14848
/// Create a new dof_map for sub dof map i (for a mixed element)
14849
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_2_0::create_sub_dof_map(unsigned int i) const
14851
return new UFC_CahnHilliard2DLinearForm_dof_map_2_0();
14856
UFC_CahnHilliard2DLinearForm_dof_map_2_1::UFC_CahnHilliard2DLinearForm_dof_map_2_1() : ufc::dof_map()
14858
__global_dimension = 0;
14862
UFC_CahnHilliard2DLinearForm_dof_map_2_1::~UFC_CahnHilliard2DLinearForm_dof_map_2_1()
14867
/// Return a string identifying the dof map
14868
const char* UFC_CahnHilliard2DLinearForm_dof_map_2_1::signature() const
14870
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14873
/// Return true iff mesh entities of topological dimension d are needed
14874
bool UFC_CahnHilliard2DLinearForm_dof_map_2_1::needs_mesh_entities(unsigned int d) const
14891
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14892
bool UFC_CahnHilliard2DLinearForm_dof_map_2_1::init_mesh(const ufc::mesh& m)
14894
__global_dimension = m.num_entities[0];
14898
/// Initialize dof map for given cell
14899
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::init_cell(const ufc::mesh& m,
14900
const ufc::cell& c)
14905
/// Finish initialization of dof map for cells
14906
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::init_cell_finalize()
14911
/// Return the dimension of the global finite element function space
14912
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::global_dimension() const
14914
return __global_dimension;
14917
/// Return the dimension of the local finite element function space
14918
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::local_dimension() const
14923
// Return the geometric dimension of the coordinates this dof map provides
14924
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::geometric_dimension() const
14929
/// Return the number of dofs on each cell facet
14930
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::num_facet_dofs() const
14935
/// Return the number of dofs associated with each cell entity of dimension d
14936
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::num_entity_dofs(unsigned int d) const
14938
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14941
/// Tabulate the local-to-global mapping of dofs on a cell
14942
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
14943
const ufc::mesh& m,
14944
const ufc::cell& c) const
14946
dofs[0] = c.entity_indices[0][0];
14947
dofs[1] = c.entity_indices[0][1];
14948
dofs[2] = c.entity_indices[0][2];
14951
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14952
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
14953
unsigned int facet) const
14972
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14973
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
14974
unsigned int d, unsigned int i) const
14976
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14979
/// Tabulate the coordinates of all dofs on a cell
14980
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_coordinates(double** coordinates,
14981
const ufc::cell& c) const
14983
const double * const * x = c.coordinates;
14984
coordinates[0][0] = x[0][0];
14985
coordinates[0][1] = x[0][1];
14986
coordinates[1][0] = x[1][0];
14987
coordinates[1][1] = x[1][1];
14988
coordinates[2][0] = x[2][0];
14989
coordinates[2][1] = x[2][1];
14992
/// Return the number of sub dof maps (for a mixed element)
14993
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::num_sub_dof_maps() const
14998
/// Create a new dof_map for sub dof map i (for a mixed element)
14999
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_2_1::create_sub_dof_map(unsigned int i) const
15001
return new UFC_CahnHilliard2DLinearForm_dof_map_2_1();
15006
UFC_CahnHilliard2DLinearForm_dof_map_2::UFC_CahnHilliard2DLinearForm_dof_map_2() : ufc::dof_map()
15008
__global_dimension = 0;
15012
UFC_CahnHilliard2DLinearForm_dof_map_2::~UFC_CahnHilliard2DLinearForm_dof_map_2()
15017
/// Return a string identifying the dof map
15018
const char* UFC_CahnHilliard2DLinearForm_dof_map_2::signature() const
15020
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
15023
/// Return true iff mesh entities of topological dimension d are needed
15024
bool UFC_CahnHilliard2DLinearForm_dof_map_2::needs_mesh_entities(unsigned int d) const
15041
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15042
bool UFC_CahnHilliard2DLinearForm_dof_map_2::init_mesh(const ufc::mesh& m)
15044
__global_dimension = 2*m.num_entities[0];
15048
/// Initialize dof map for given cell
15049
void UFC_CahnHilliard2DLinearForm_dof_map_2::init_cell(const ufc::mesh& m,
15050
const ufc::cell& c)
15055
/// Finish initialization of dof map for cells
15056
void UFC_CahnHilliard2DLinearForm_dof_map_2::init_cell_finalize()
15061
/// Return the dimension of the global finite element function space
15062
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::global_dimension() const
15064
return __global_dimension;
15067
/// Return the dimension of the local finite element function space
15068
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::local_dimension() const
15073
// Return the geometric dimension of the coordinates this dof map provides
15074
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::geometric_dimension() const
15079
/// Return the number of dofs on each cell facet
15080
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::num_facet_dofs() const
15085
/// Return the number of dofs associated with each cell entity of dimension d
15086
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::num_entity_dofs(unsigned int d) const
15088
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15091
/// Tabulate the local-to-global mapping of dofs on a cell
15092
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_dofs(unsigned int* dofs,
15093
const ufc::mesh& m,
15094
const ufc::cell& c) const
15096
dofs[0] = c.entity_indices[0][0];
15097
dofs[1] = c.entity_indices[0][1];
15098
dofs[2] = c.entity_indices[0][2];
15099
unsigned int offset = m.num_entities[0];
15100
dofs[3] = offset + c.entity_indices[0][0];
15101
dofs[4] = offset + c.entity_indices[0][1];
15102
dofs[5] = offset + c.entity_indices[0][2];
15105
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15106
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
15107
unsigned int facet) const
15132
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15133
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
15134
unsigned int d, unsigned int i) const
15136
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15139
/// Tabulate the coordinates of all dofs on a cell
15140
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_coordinates(double** coordinates,
15141
const ufc::cell& c) const
15143
const double * const * x = c.coordinates;
15144
coordinates[0][0] = x[0][0];
15145
coordinates[0][1] = x[0][1];
15146
coordinates[1][0] = x[1][0];
15147
coordinates[1][1] = x[1][1];
15148
coordinates[2][0] = x[2][0];
15149
coordinates[2][1] = x[2][1];
15150
coordinates[3][0] = x[0][0];
15151
coordinates[3][1] = x[0][1];
15152
coordinates[4][0] = x[1][0];
15153
coordinates[4][1] = x[1][1];
15154
coordinates[5][0] = x[2][0];
15155
coordinates[5][1] = x[2][1];
15158
/// Return the number of sub dof maps (for a mixed element)
15159
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::num_sub_dof_maps() const
15164
/// Create a new dof_map for sub dof map i (for a mixed element)
15165
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_2::create_sub_dof_map(unsigned int i) const
15170
return new UFC_CahnHilliard2DLinearForm_dof_map_2_0();
15173
return new UFC_CahnHilliard2DLinearForm_dof_map_2_1();
15181
UFC_CahnHilliard2DLinearForm_dof_map_3::UFC_CahnHilliard2DLinearForm_dof_map_3() : ufc::dof_map()
15183
__global_dimension = 0;
15187
UFC_CahnHilliard2DLinearForm_dof_map_3::~UFC_CahnHilliard2DLinearForm_dof_map_3()
15192
/// Return a string identifying the dof map
15193
const char* UFC_CahnHilliard2DLinearForm_dof_map_3::signature() const
15195
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15198
/// Return true iff mesh entities of topological dimension d are needed
15199
bool UFC_CahnHilliard2DLinearForm_dof_map_3::needs_mesh_entities(unsigned int d) const
15216
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15217
bool UFC_CahnHilliard2DLinearForm_dof_map_3::init_mesh(const ufc::mesh& m)
15219
__global_dimension = m.num_entities[2];
15223
/// Initialize dof map for given cell
15224
void UFC_CahnHilliard2DLinearForm_dof_map_3::init_cell(const ufc::mesh& m,
15225
const ufc::cell& c)
15230
/// Finish initialization of dof map for cells
15231
void UFC_CahnHilliard2DLinearForm_dof_map_3::init_cell_finalize()
15236
/// Return the dimension of the global finite element function space
15237
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::global_dimension() const
15239
return __global_dimension;
15242
/// Return the dimension of the local finite element function space
15243
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::local_dimension() const
15248
// Return the geometric dimension of the coordinates this dof map provides
15249
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::geometric_dimension() const
15254
/// Return the number of dofs on each cell facet
15255
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::num_facet_dofs() const
15260
/// Return the number of dofs associated with each cell entity of dimension d
15261
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::num_entity_dofs(unsigned int d) const
15263
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15266
/// Tabulate the local-to-global mapping of dofs on a cell
15267
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_dofs(unsigned int* dofs,
15268
const ufc::mesh& m,
15269
const ufc::cell& c) const
15271
dofs[0] = c.entity_indices[2][0];
15274
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15275
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
15276
unsigned int facet) const
15292
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15293
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
15294
unsigned int d, unsigned int i) const
15296
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15299
/// Tabulate the coordinates of all dofs on a cell
15300
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_coordinates(double** coordinates,
15301
const ufc::cell& c) const
15303
const double * const * x = c.coordinates;
15304
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15305
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15308
/// Return the number of sub dof maps (for a mixed element)
15309
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::num_sub_dof_maps() const
15314
/// Create a new dof_map for sub dof map i (for a mixed element)
15315
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_3::create_sub_dof_map(unsigned int i) const
15317
return new UFC_CahnHilliard2DLinearForm_dof_map_3();
15322
UFC_CahnHilliard2DLinearForm_dof_map_4::UFC_CahnHilliard2DLinearForm_dof_map_4() : ufc::dof_map()
15324
__global_dimension = 0;
15328
UFC_CahnHilliard2DLinearForm_dof_map_4::~UFC_CahnHilliard2DLinearForm_dof_map_4()
15333
/// Return a string identifying the dof map
15334
const char* UFC_CahnHilliard2DLinearForm_dof_map_4::signature() const
15336
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15339
/// Return true iff mesh entities of topological dimension d are needed
15340
bool UFC_CahnHilliard2DLinearForm_dof_map_4::needs_mesh_entities(unsigned int d) const
15357
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15358
bool UFC_CahnHilliard2DLinearForm_dof_map_4::init_mesh(const ufc::mesh& m)
15360
__global_dimension = m.num_entities[2];
15364
/// Initialize dof map for given cell
15365
void UFC_CahnHilliard2DLinearForm_dof_map_4::init_cell(const ufc::mesh& m,
15366
const ufc::cell& c)
15371
/// Finish initialization of dof map for cells
15372
void UFC_CahnHilliard2DLinearForm_dof_map_4::init_cell_finalize()
15377
/// Return the dimension of the global finite element function space
15378
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::global_dimension() const
15380
return __global_dimension;
15383
/// Return the dimension of the local finite element function space
15384
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::local_dimension() const
15389
// Return the geometric dimension of the coordinates this dof map provides
15390
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::geometric_dimension() const
15395
/// Return the number of dofs on each cell facet
15396
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::num_facet_dofs() const
15401
/// Return the number of dofs associated with each cell entity of dimension d
15402
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::num_entity_dofs(unsigned int d) const
15404
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15407
/// Tabulate the local-to-global mapping of dofs on a cell
15408
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_dofs(unsigned int* dofs,
15409
const ufc::mesh& m,
15410
const ufc::cell& c) const
15412
dofs[0] = c.entity_indices[2][0];
15415
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15416
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
15417
unsigned int facet) const
15433
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15434
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
15435
unsigned int d, unsigned int i) const
15437
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15440
/// Tabulate the coordinates of all dofs on a cell
15441
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_coordinates(double** coordinates,
15442
const ufc::cell& c) const
15444
const double * const * x = c.coordinates;
15445
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15446
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15449
/// Return the number of sub dof maps (for a mixed element)
15450
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::num_sub_dof_maps() const
15455
/// Create a new dof_map for sub dof map i (for a mixed element)
15456
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_4::create_sub_dof_map(unsigned int i) const
15458
return new UFC_CahnHilliard2DLinearForm_dof_map_4();
15463
UFC_CahnHilliard2DLinearForm_dof_map_5::UFC_CahnHilliard2DLinearForm_dof_map_5() : ufc::dof_map()
15465
__global_dimension = 0;
15469
UFC_CahnHilliard2DLinearForm_dof_map_5::~UFC_CahnHilliard2DLinearForm_dof_map_5()
15474
/// Return a string identifying the dof map
15475
const char* UFC_CahnHilliard2DLinearForm_dof_map_5::signature() const
15477
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15480
/// Return true iff mesh entities of topological dimension d are needed
15481
bool UFC_CahnHilliard2DLinearForm_dof_map_5::needs_mesh_entities(unsigned int d) const
15498
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15499
bool UFC_CahnHilliard2DLinearForm_dof_map_5::init_mesh(const ufc::mesh& m)
15501
__global_dimension = m.num_entities[2];
15505
/// Initialize dof map for given cell
15506
void UFC_CahnHilliard2DLinearForm_dof_map_5::init_cell(const ufc::mesh& m,
15507
const ufc::cell& c)
15512
/// Finish initialization of dof map for cells
15513
void UFC_CahnHilliard2DLinearForm_dof_map_5::init_cell_finalize()
15518
/// Return the dimension of the global finite element function space
15519
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::global_dimension() const
15521
return __global_dimension;
15524
/// Return the dimension of the local finite element function space
15525
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::local_dimension() const
15530
// Return the geometric dimension of the coordinates this dof map provides
15531
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::geometric_dimension() const
15536
/// Return the number of dofs on each cell facet
15537
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::num_facet_dofs() const
15542
/// Return the number of dofs associated with each cell entity of dimension d
15543
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::num_entity_dofs(unsigned int d) const
15545
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15548
/// Tabulate the local-to-global mapping of dofs on a cell
15549
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_dofs(unsigned int* dofs,
15550
const ufc::mesh& m,
15551
const ufc::cell& c) const
15553
dofs[0] = c.entity_indices[2][0];
15556
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15557
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
15558
unsigned int facet) const
15574
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15575
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
15576
unsigned int d, unsigned int i) const
15578
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15581
/// Tabulate the coordinates of all dofs on a cell
15582
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_coordinates(double** coordinates,
15583
const ufc::cell& c) const
15585
const double * const * x = c.coordinates;
15586
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15587
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15590
/// Return the number of sub dof maps (for a mixed element)
15591
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::num_sub_dof_maps() const
15596
/// Create a new dof_map for sub dof map i (for a mixed element)
15597
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_5::create_sub_dof_map(unsigned int i) const
15599
return new UFC_CahnHilliard2DLinearForm_dof_map_5();
15604
UFC_CahnHilliard2DLinearForm_dof_map_6::UFC_CahnHilliard2DLinearForm_dof_map_6() : ufc::dof_map()
15606
__global_dimension = 0;
15610
UFC_CahnHilliard2DLinearForm_dof_map_6::~UFC_CahnHilliard2DLinearForm_dof_map_6()
15615
/// Return a string identifying the dof map
15616
const char* UFC_CahnHilliard2DLinearForm_dof_map_6::signature() const
15618
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15621
/// Return true iff mesh entities of topological dimension d are needed
15622
bool UFC_CahnHilliard2DLinearForm_dof_map_6::needs_mesh_entities(unsigned int d) const
15639
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15640
bool UFC_CahnHilliard2DLinearForm_dof_map_6::init_mesh(const ufc::mesh& m)
15642
__global_dimension = m.num_entities[2];
15646
/// Initialize dof map for given cell
15647
void UFC_CahnHilliard2DLinearForm_dof_map_6::init_cell(const ufc::mesh& m,
15648
const ufc::cell& c)
15653
/// Finish initialization of dof map for cells
15654
void UFC_CahnHilliard2DLinearForm_dof_map_6::init_cell_finalize()
15659
/// Return the dimension of the global finite element function space
15660
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::global_dimension() const
15662
return __global_dimension;
15665
/// Return the dimension of the local finite element function space
15666
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::local_dimension() const
15671
// Return the geometric dimension of the coordinates this dof map provides
15672
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::geometric_dimension() const
15677
/// Return the number of dofs on each cell facet
15678
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::num_facet_dofs() const
15683
/// Return the number of dofs associated with each cell entity of dimension d
15684
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::num_entity_dofs(unsigned int d) const
15686
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15689
/// Tabulate the local-to-global mapping of dofs on a cell
15690
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_dofs(unsigned int* dofs,
15691
const ufc::mesh& m,
15692
const ufc::cell& c) const
15694
dofs[0] = c.entity_indices[2][0];
15697
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15698
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
15699
unsigned int facet) const
15715
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15716
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
15717
unsigned int d, unsigned int i) const
15719
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15722
/// Tabulate the coordinates of all dofs on a cell
15723
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_coordinates(double** coordinates,
15724
const ufc::cell& c) const
15726
const double * const * x = c.coordinates;
15727
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15728
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15731
/// Return the number of sub dof maps (for a mixed element)
15732
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::num_sub_dof_maps() const
15737
/// Create a new dof_map for sub dof map i (for a mixed element)
15738
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_6::create_sub_dof_map(unsigned int i) const
15740
return new UFC_CahnHilliard2DLinearForm_dof_map_6();
15745
UFC_CahnHilliard2DLinearForm_cell_integral_0::UFC_CahnHilliard2DLinearForm_cell_integral_0() : ufc::cell_integral()
15751
UFC_CahnHilliard2DLinearForm_cell_integral_0::~UFC_CahnHilliard2DLinearForm_cell_integral_0()
8148
ufc::interior_facet_integral* cahnhilliard2d_form_0::create_interior_facet_integral(unsigned int i) const
8155
cahnhilliard2d_1_finite_element_0_0::cahnhilliard2d_1_finite_element_0_0() : ufc::finite_element()
8161
cahnhilliard2d_1_finite_element_0_0::~cahnhilliard2d_1_finite_element_0_0()
8166
/// Return a string identifying the finite element
8167
const char* cahnhilliard2d_1_finite_element_0_0::signature() const
8169
return "FiniteElement('Lagrange', 'triangle', 1)";
8172
/// Return the cell shape
8173
ufc::shape cahnhilliard2d_1_finite_element_0_0::cell_shape() const
8175
return ufc::triangle;
8178
/// Return the dimension of the finite element function space
8179
unsigned int cahnhilliard2d_1_finite_element_0_0::space_dimension() const
8184
/// Return the rank of the value space
8185
unsigned int cahnhilliard2d_1_finite_element_0_0::value_rank() const
8190
/// Return the dimension of the value space for axis i
8191
unsigned int cahnhilliard2d_1_finite_element_0_0::value_dimension(unsigned int i) const
8196
/// Evaluate basis function i at given point in cell
8197
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis(unsigned int i,
8199
const double* coordinates,
8200
const ufc::cell& c) const
8202
// Extract vertex coordinates
8203
const double * const * element_coordinates = c.coordinates;
8205
// Compute Jacobian of affine map from reference cell
8206
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8207
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8208
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8209
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8211
// Compute determinant of Jacobian
8212
const double detJ = J_00*J_11 - J_01*J_10;
8214
// Compute inverse of Jacobian
8216
// Get coordinates and map to the reference (UFC) element
8217
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8218
element_coordinates[0][0]*element_coordinates[2][1] +\
8219
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8220
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8221
element_coordinates[1][0]*element_coordinates[0][1] -\
8222
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8224
// Map coordinates to the reference square
8225
if (std::abs(y - 1.0) < 1e-14)
8228
x = 2.0 *x/(1.0 - y) - 1.0;
8234
// Map degree of freedom to element degree of freedom
8235
const unsigned int dof = i;
8237
// Generate scalings
8238
const double scalings_y_0 = 1;
8239
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8241
// Compute psitilde_a
8242
const double psitilde_a_0 = 1;
8243
const double psitilde_a_1 = x;
8245
// Compute psitilde_bs
8246
const double psitilde_bs_0_0 = 1;
8247
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8248
const double psitilde_bs_1_0 = 1;
8250
// Compute basisvalues
8251
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8252
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8253
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8255
// Table(s) of coefficients
8256
static const double coefficients0[3][3] = \
8257
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8258
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8259
{0.471404520791032, 0, 0.333333333333333}};
8261
// Extract relevant coefficients
8262
const double coeff0_0 = coefficients0[dof][0];
8263
const double coeff0_1 = coefficients0[dof][1];
8264
const double coeff0_2 = coefficients0[dof][2];
8267
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8270
/// Evaluate all basis functions at given point in cell
8271
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis_all(double* values,
8272
const double* coordinates,
8273
const ufc::cell& c) const
8275
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8278
/// Evaluate order n derivatives of basis function i at given point in cell
8279
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis_derivatives(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-14)
8311
x = 2.0 *x/(1.0 - y) - 1.0;
8314
// Compute number of derivatives
8315
unsigned int num_derivatives = 1;
8317
for (unsigned int j = 0; j < n; j++)
8318
num_derivatives *= 2;
8321
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8322
unsigned int **combinations = new unsigned int *[num_derivatives];
8324
for (unsigned int j = 0; j < num_derivatives; j++)
8326
combinations[j] = new unsigned int [n];
8327
for (unsigned int k = 0; k < n; k++)
8328
combinations[j][k] = 0;
8331
// Generate combinations of derivatives
8332
for (unsigned int row = 1; row < num_derivatives; row++)
8334
for (unsigned int num = 0; num < row; num++)
8336
for (unsigned int col = n-1; col+1 > 0; col--)
8338
if (combinations[row][col] + 1 > 1)
8339
combinations[row][col] = 0;
8342
combinations[row][col] += 1;
8349
// Compute inverse of Jacobian
8350
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8352
// Declare transformation matrix
8353
// Declare pointer to two dimensional array and initialise
8354
double **transform = new double *[num_derivatives];
8356
for (unsigned int j = 0; j < num_derivatives; j++)
8358
transform[j] = new double [num_derivatives];
8359
for (unsigned int k = 0; k < num_derivatives; k++)
8360
transform[j][k] = 1;
8363
// Construct transformation matrix
8364
for (unsigned int row = 0; row < num_derivatives; row++)
8366
for (unsigned int col = 0; col < num_derivatives; col++)
8368
for (unsigned int k = 0; k < n; k++)
8369
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8374
for (unsigned int j = 0; j < 1*num_derivatives; j++)
8377
// Map degree of freedom to element degree of freedom
8378
const unsigned int dof = i;
8380
// Generate scalings
8381
const double scalings_y_0 = 1;
8382
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8384
// Compute psitilde_a
8385
const double psitilde_a_0 = 1;
8386
const double psitilde_a_1 = x;
8388
// Compute psitilde_bs
8389
const double psitilde_bs_0_0 = 1;
8390
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8391
const double psitilde_bs_1_0 = 1;
8393
// Compute basisvalues
8394
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8395
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8396
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8398
// Table(s) of coefficients
8399
static const double coefficients0[3][3] = \
8400
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8401
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8402
{0.471404520791032, 0, 0.333333333333333}};
8404
// Interesting (new) part
8405
// Tables of derivatives of the polynomial base (transpose)
8406
static const double dmats0[3][3] = \
8408
{4.89897948556636, 0, 0},
8411
static const double dmats1[3][3] = \
8413
{2.44948974278318, 0, 0},
8414
{4.24264068711928, 0, 0}};
8416
// Compute reference derivatives
8417
// Declare pointer to array of derivatives on FIAT element
8418
double *derivatives = new double [num_derivatives];
8420
// Declare coefficients
8421
double coeff0_0 = 0;
8422
double coeff0_1 = 0;
8423
double coeff0_2 = 0;
8425
// Declare new coefficients
8426
double new_coeff0_0 = 0;
8427
double new_coeff0_1 = 0;
8428
double new_coeff0_2 = 0;
8430
// Loop possible derivatives
8431
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8433
// Get values from coefficients array
8434
new_coeff0_0 = coefficients0[dof][0];
8435
new_coeff0_1 = coefficients0[dof][1];
8436
new_coeff0_2 = coefficients0[dof][2];
8438
// Loop derivative order
8439
for (unsigned int j = 0; j < n; j++)
8441
// Update old coefficients
8442
coeff0_0 = new_coeff0_0;
8443
coeff0_1 = new_coeff0_1;
8444
coeff0_2 = new_coeff0_2;
8446
if(combinations[deriv_num][j] == 0)
8448
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
8449
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
8450
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
8452
if(combinations[deriv_num][j] == 1)
8454
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
8455
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
8456
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
8460
// Compute derivatives on reference element as dot product of coefficients and basisvalues
8461
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
8464
// Transform derivatives back to physical element
8465
for (unsigned int row = 0; row < num_derivatives; row++)
8467
for (unsigned int col = 0; col < num_derivatives; col++)
8469
values[row] += transform[row][col]*derivatives[col];
8472
// Delete pointer to array of derivatives on FIAT element
8473
delete [] derivatives;
8475
// Delete pointer to array of combinations of derivatives and transform
8476
for (unsigned int row = 0; row < num_derivatives; row++)
8478
delete [] combinations[row];
8479
delete [] transform[row];
8482
delete [] combinations;
8483
delete [] transform;
8486
/// Evaluate order n derivatives of all basis functions at given point in cell
8487
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
8489
const double* coordinates,
8490
const ufc::cell& c) const
8492
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8495
/// Evaluate linear functional for dof i on the function f
8496
double cahnhilliard2d_1_finite_element_0_0::evaluate_dof(unsigned int i,
8497
const ufc::function& f,
8498
const ufc::cell& c) const
8500
// The reference points, direction and weights:
8501
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
8502
static const double W[3][1] = {{1}, {1}, {1}};
8503
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
8505
const double * const * x = c.coordinates;
8506
double result = 0.0;
8507
// Iterate over the points:
8508
// Evaluate basis functions for affine mapping
8509
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
8510
const double w1 = X[i][0][0];
8511
const double w2 = X[i][0][1];
8513
// Compute affine mapping y = F(X)
8515
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
8516
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
8518
// Evaluate function at physical points
8520
f.evaluate(values, y, c);
8522
// Map function values using appropriate mapping
8523
// Affine map: Do nothing
8525
// Note that we do not map the weights (yet).
8527
// Take directional components
8528
for(int k = 0; k < 1; k++)
8529
result += values[k]*D[i][0][k];
8530
// Multiply by weights
8536
/// Evaluate linear functionals for all dofs on the function f
8537
void cahnhilliard2d_1_finite_element_0_0::evaluate_dofs(double* values,
8538
const ufc::function& f,
8539
const ufc::cell& c) const
8541
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8544
/// Interpolate vertex values from dof values
8545
void cahnhilliard2d_1_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
8546
const double* dof_values,
8547
const ufc::cell& c) const
8549
// Evaluate at vertices and use affine mapping
8550
vertex_values[0] = dof_values[0];
8551
vertex_values[1] = dof_values[1];
8552
vertex_values[2] = dof_values[2];
8555
/// Return the number of sub elements (for a mixed element)
8556
unsigned int cahnhilliard2d_1_finite_element_0_0::num_sub_elements() const
8561
/// Create a new finite element for sub element i (for a mixed element)
8562
ufc::finite_element* cahnhilliard2d_1_finite_element_0_0::create_sub_element(unsigned int i) const
8564
return new cahnhilliard2d_1_finite_element_0_0();
8569
cahnhilliard2d_1_finite_element_0_1::cahnhilliard2d_1_finite_element_0_1() : ufc::finite_element()
8575
cahnhilliard2d_1_finite_element_0_1::~cahnhilliard2d_1_finite_element_0_1()
8580
/// Return a string identifying the finite element
8581
const char* cahnhilliard2d_1_finite_element_0_1::signature() const
8583
return "FiniteElement('Lagrange', 'triangle', 1)";
8586
/// Return the cell shape
8587
ufc::shape cahnhilliard2d_1_finite_element_0_1::cell_shape() const
8589
return ufc::triangle;
8592
/// Return the dimension of the finite element function space
8593
unsigned int cahnhilliard2d_1_finite_element_0_1::space_dimension() const
8598
/// Return the rank of the value space
8599
unsigned int cahnhilliard2d_1_finite_element_0_1::value_rank() const
8604
/// Return the dimension of the value space for axis i
8605
unsigned int cahnhilliard2d_1_finite_element_0_1::value_dimension(unsigned int i) const
8610
/// Evaluate basis function i at given point in cell
8611
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis(unsigned int i,
8613
const double* coordinates,
8614
const ufc::cell& c) const
8616
// Extract vertex coordinates
8617
const double * const * element_coordinates = c.coordinates;
8619
// Compute Jacobian of affine map from reference cell
8620
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8621
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8622
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8623
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8625
// Compute determinant of Jacobian
8626
const double detJ = J_00*J_11 - J_01*J_10;
8628
// Compute inverse of Jacobian
8630
// Get coordinates and map to the reference (UFC) element
8631
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8632
element_coordinates[0][0]*element_coordinates[2][1] +\
8633
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8634
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8635
element_coordinates[1][0]*element_coordinates[0][1] -\
8636
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8638
// Map coordinates to the reference square
8639
if (std::abs(y - 1.0) < 1e-14)
8642
x = 2.0 *x/(1.0 - y) - 1.0;
8648
// Map degree of freedom to element degree of freedom
8649
const unsigned int dof = i;
8651
// Generate scalings
8652
const double scalings_y_0 = 1;
8653
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8655
// Compute psitilde_a
8656
const double psitilde_a_0 = 1;
8657
const double psitilde_a_1 = x;
8659
// Compute psitilde_bs
8660
const double psitilde_bs_0_0 = 1;
8661
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8662
const double psitilde_bs_1_0 = 1;
8664
// Compute basisvalues
8665
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8666
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8667
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8669
// Table(s) of coefficients
8670
static const double coefficients0[3][3] = \
8671
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8672
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8673
{0.471404520791032, 0, 0.333333333333333}};
8675
// Extract relevant coefficients
8676
const double coeff0_0 = coefficients0[dof][0];
8677
const double coeff0_1 = coefficients0[dof][1];
8678
const double coeff0_2 = coefficients0[dof][2];
8681
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8684
/// Evaluate all basis functions at given point in cell
8685
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis_all(double* values,
8686
const double* coordinates,
8687
const ufc::cell& c) const
8689
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8692
/// Evaluate order n derivatives of basis function i at given point in cell
8693
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
8696
const double* coordinates,
8697
const ufc::cell& c) const
8699
// Extract vertex coordinates
8700
const double * const * element_coordinates = c.coordinates;
8702
// Compute Jacobian of affine map from reference cell
8703
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8704
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8705
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8706
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8708
// Compute determinant of Jacobian
8709
const double detJ = J_00*J_11 - J_01*J_10;
8711
// Compute inverse of Jacobian
8713
// Get coordinates and map to the reference (UFC) element
8714
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8715
element_coordinates[0][0]*element_coordinates[2][1] +\
8716
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8717
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8718
element_coordinates[1][0]*element_coordinates[0][1] -\
8719
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8721
// Map coordinates to the reference square
8722
if (std::abs(y - 1.0) < 1e-14)
8725
x = 2.0 *x/(1.0 - y) - 1.0;
8728
// Compute number of derivatives
8729
unsigned int num_derivatives = 1;
8731
for (unsigned int j = 0; j < n; j++)
8732
num_derivatives *= 2;
8735
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8736
unsigned int **combinations = new unsigned int *[num_derivatives];
8738
for (unsigned int j = 0; j < num_derivatives; j++)
8740
combinations[j] = new unsigned int [n];
8741
for (unsigned int k = 0; k < n; k++)
8742
combinations[j][k] = 0;
8745
// Generate combinations of derivatives
8746
for (unsigned int row = 1; row < num_derivatives; row++)
8748
for (unsigned int num = 0; num < row; num++)
8750
for (unsigned int col = n-1; col+1 > 0; col--)
8752
if (combinations[row][col] + 1 > 1)
8753
combinations[row][col] = 0;
8756
combinations[row][col] += 1;
8763
// Compute inverse of Jacobian
8764
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8766
// Declare transformation matrix
8767
// Declare pointer to two dimensional array and initialise
8768
double **transform = new double *[num_derivatives];
8770
for (unsigned int j = 0; j < num_derivatives; j++)
8772
transform[j] = new double [num_derivatives];
8773
for (unsigned int k = 0; k < num_derivatives; k++)
8774
transform[j][k] = 1;
8777
// Construct transformation matrix
8778
for (unsigned int row = 0; row < num_derivatives; row++)
8780
for (unsigned int col = 0; col < num_derivatives; col++)
8782
for (unsigned int k = 0; k < n; k++)
8783
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8788
for (unsigned int j = 0; j < 1*num_derivatives; j++)
8791
// Map degree of freedom to element degree of freedom
8792
const unsigned int dof = i;
8794
// Generate scalings
8795
const double scalings_y_0 = 1;
8796
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8798
// Compute psitilde_a
8799
const double psitilde_a_0 = 1;
8800
const double psitilde_a_1 = x;
8802
// Compute psitilde_bs
8803
const double psitilde_bs_0_0 = 1;
8804
const double psitilde_bs_0_1 = 1.5*y + 0.5;
8805
const double psitilde_bs_1_0 = 1;
8807
// Compute basisvalues
8808
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8809
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8810
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8812
// Table(s) of coefficients
8813
static const double coefficients0[3][3] = \
8814
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
8815
{0.471404520791032, 0.288675134594813, -0.166666666666667},
8816
{0.471404520791032, 0, 0.333333333333333}};
8818
// Interesting (new) part
8819
// Tables of derivatives of the polynomial base (transpose)
8820
static const double dmats0[3][3] = \
8822
{4.89897948556636, 0, 0},
8825
static const double dmats1[3][3] = \
8827
{2.44948974278318, 0, 0},
8828
{4.24264068711928, 0, 0}};
8830
// Compute reference derivatives
8831
// Declare pointer to array of derivatives on FIAT element
8832
double *derivatives = new double [num_derivatives];
8834
// Declare coefficients
8835
double coeff0_0 = 0;
8836
double coeff0_1 = 0;
8837
double coeff0_2 = 0;
8839
// Declare new coefficients
8840
double new_coeff0_0 = 0;
8841
double new_coeff0_1 = 0;
8842
double new_coeff0_2 = 0;
8844
// Loop possible derivatives
8845
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8847
// Get values from coefficients array
8848
new_coeff0_0 = coefficients0[dof][0];
8849
new_coeff0_1 = coefficients0[dof][1];
8850
new_coeff0_2 = coefficients0[dof][2];
8852
// Loop derivative order
8853
for (unsigned int j = 0; j < n; j++)
8855
// Update old coefficients
8856
coeff0_0 = new_coeff0_0;
8857
coeff0_1 = new_coeff0_1;
8858
coeff0_2 = new_coeff0_2;
8860
if(combinations[deriv_num][j] == 0)
8862
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
8863
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
8864
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
8866
if(combinations[deriv_num][j] == 1)
8868
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
8869
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
8870
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
8874
// Compute derivatives on reference element as dot product of coefficients and basisvalues
8875
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
8878
// Transform derivatives back to physical element
8879
for (unsigned int row = 0; row < num_derivatives; row++)
8881
for (unsigned int col = 0; col < num_derivatives; col++)
8883
values[row] += transform[row][col]*derivatives[col];
8886
// Delete pointer to array of derivatives on FIAT element
8887
delete [] derivatives;
8889
// Delete pointer to array of combinations of derivatives and transform
8890
for (unsigned int row = 0; row < num_derivatives; row++)
8892
delete [] combinations[row];
8893
delete [] transform[row];
8896
delete [] combinations;
8897
delete [] transform;
8900
/// Evaluate order n derivatives of all basis functions at given point in cell
8901
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
8903
const double* coordinates,
8904
const ufc::cell& c) const
8906
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8909
/// Evaluate linear functional for dof i on the function f
8910
double cahnhilliard2d_1_finite_element_0_1::evaluate_dof(unsigned int i,
8911
const ufc::function& f,
8912
const ufc::cell& c) const
8914
// The reference points, direction and weights:
8915
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
8916
static const double W[3][1] = {{1}, {1}, {1}};
8917
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
8919
const double * const * x = c.coordinates;
8920
double result = 0.0;
8921
// Iterate over the points:
8922
// Evaluate basis functions for affine mapping
8923
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
8924
const double w1 = X[i][0][0];
8925
const double w2 = X[i][0][1];
8927
// Compute affine mapping y = F(X)
8929
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
8930
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
8932
// Evaluate function at physical points
8934
f.evaluate(values, y, c);
8936
// Map function values using appropriate mapping
8937
// Affine map: Do nothing
8939
// Note that we do not map the weights (yet).
8941
// Take directional components
8942
for(int k = 0; k < 1; k++)
8943
result += values[k]*D[i][0][k];
8944
// Multiply by weights
8950
/// Evaluate linear functionals for all dofs on the function f
8951
void cahnhilliard2d_1_finite_element_0_1::evaluate_dofs(double* values,
8952
const ufc::function& f,
8953
const ufc::cell& c) const
8955
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8958
/// Interpolate vertex values from dof values
8959
void cahnhilliard2d_1_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
8960
const double* dof_values,
8961
const ufc::cell& c) const
8963
// Evaluate at vertices and use affine mapping
8964
vertex_values[0] = dof_values[0];
8965
vertex_values[1] = dof_values[1];
8966
vertex_values[2] = dof_values[2];
8969
/// Return the number of sub elements (for a mixed element)
8970
unsigned int cahnhilliard2d_1_finite_element_0_1::num_sub_elements() const
8975
/// Create a new finite element for sub element i (for a mixed element)
8976
ufc::finite_element* cahnhilliard2d_1_finite_element_0_1::create_sub_element(unsigned int i) const
8978
return new cahnhilliard2d_1_finite_element_0_1();
8983
cahnhilliard2d_1_finite_element_0::cahnhilliard2d_1_finite_element_0() : ufc::finite_element()
8989
cahnhilliard2d_1_finite_element_0::~cahnhilliard2d_1_finite_element_0()
8994
/// Return a string identifying the finite element
8995
const char* cahnhilliard2d_1_finite_element_0::signature() const
8997
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
9000
/// Return the cell shape
9001
ufc::shape cahnhilliard2d_1_finite_element_0::cell_shape() const
9003
return ufc::triangle;
9006
/// Return the dimension of the finite element function space
9007
unsigned int cahnhilliard2d_1_finite_element_0::space_dimension() const
9012
/// Return the rank of the value space
9013
unsigned int cahnhilliard2d_1_finite_element_0::value_rank() const
9018
/// Return the dimension of the value space for axis i
9019
unsigned int cahnhilliard2d_1_finite_element_0::value_dimension(unsigned int i) const
9024
/// Evaluate basis function i at given point in cell
9025
void cahnhilliard2d_1_finite_element_0::evaluate_basis(unsigned int i,
9027
const double* coordinates,
9028
const ufc::cell& c) const
9030
// Extract vertex coordinates
9031
const double * const * element_coordinates = c.coordinates;
9033
// Compute Jacobian of affine map from reference cell
9034
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9035
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9036
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9037
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9039
// Compute determinant of Jacobian
9040
const double detJ = J_00*J_11 - J_01*J_10;
9042
// Compute inverse of Jacobian
9044
// Get coordinates and map to the reference (UFC) element
9045
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9046
element_coordinates[0][0]*element_coordinates[2][1] +\
9047
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9048
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9049
element_coordinates[1][0]*element_coordinates[0][1] -\
9050
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9052
// Map coordinates to the reference square
9053
if (std::abs(y - 1.0) < 1e-14)
9056
x = 2.0 *x/(1.0 - y) - 1.0;
9063
if (0 <= i && i <= 2)
9065
// Map degree of freedom to element degree of freedom
9066
const unsigned int dof = i;
9068
// Generate scalings
9069
const double scalings_y_0 = 1;
9070
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9072
// Compute psitilde_a
9073
const double psitilde_a_0 = 1;
9074
const double psitilde_a_1 = x;
9076
// Compute psitilde_bs
9077
const double psitilde_bs_0_0 = 1;
9078
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9079
const double psitilde_bs_1_0 = 1;
9081
// Compute basisvalues
9082
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9083
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9084
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9086
// Table(s) of coefficients
9087
static const double coefficients0[3][3] = \
9088
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9089
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9090
{0.471404520791032, 0, 0.333333333333333}};
9092
// Extract relevant coefficients
9093
const double coeff0_0 = coefficients0[dof][0];
9094
const double coeff0_1 = coefficients0[dof][1];
9095
const double coeff0_2 = coefficients0[dof][2];
9098
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9101
if (3 <= i && i <= 5)
9103
// Map degree of freedom to element degree of freedom
9104
const unsigned int dof = i - 3;
9106
// Generate scalings
9107
const double scalings_y_0 = 1;
9108
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9110
// Compute psitilde_a
9111
const double psitilde_a_0 = 1;
9112
const double psitilde_a_1 = x;
9114
// Compute psitilde_bs
9115
const double psitilde_bs_0_0 = 1;
9116
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9117
const double psitilde_bs_1_0 = 1;
9119
// Compute basisvalues
9120
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9121
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9122
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9124
// Table(s) of coefficients
9125
static const double coefficients0[3][3] = \
9126
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9127
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9128
{0.471404520791032, 0, 0.333333333333333}};
9130
// Extract relevant coefficients
9131
const double coeff0_0 = coefficients0[dof][0];
9132
const double coeff0_1 = coefficients0[dof][1];
9133
const double coeff0_2 = coefficients0[dof][2];
9136
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9141
/// Evaluate all basis functions at given point in cell
9142
void cahnhilliard2d_1_finite_element_0::evaluate_basis_all(double* values,
9143
const double* coordinates,
9144
const ufc::cell& c) const
9146
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9149
/// Evaluate order n derivatives of basis function i at given point in cell
9150
void cahnhilliard2d_1_finite_element_0::evaluate_basis_derivatives(unsigned int i,
9153
const double* coordinates,
9154
const ufc::cell& c) const
9156
// Extract vertex coordinates
9157
const double * const * element_coordinates = c.coordinates;
9159
// Compute Jacobian of affine map from reference cell
9160
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9161
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9162
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9163
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9165
// Compute determinant of Jacobian
9166
const double detJ = J_00*J_11 - J_01*J_10;
9168
// Compute inverse of Jacobian
9170
// Get coordinates and map to the reference (UFC) element
9171
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9172
element_coordinates[0][0]*element_coordinates[2][1] +\
9173
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9174
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9175
element_coordinates[1][0]*element_coordinates[0][1] -\
9176
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9178
// Map coordinates to the reference square
9179
if (std::abs(y - 1.0) < 1e-14)
9182
x = 2.0 *x/(1.0 - y) - 1.0;
9185
// Compute number of derivatives
9186
unsigned int num_derivatives = 1;
9188
for (unsigned int j = 0; j < n; j++)
9189
num_derivatives *= 2;
9192
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9193
unsigned int **combinations = new unsigned int *[num_derivatives];
9195
for (unsigned int j = 0; j < num_derivatives; j++)
9197
combinations[j] = new unsigned int [n];
9198
for (unsigned int k = 0; k < n; k++)
9199
combinations[j][k] = 0;
9202
// Generate combinations of derivatives
9203
for (unsigned int row = 1; row < num_derivatives; row++)
9205
for (unsigned int num = 0; num < row; num++)
9207
for (unsigned int col = n-1; col+1 > 0; col--)
9209
if (combinations[row][col] + 1 > 1)
9210
combinations[row][col] = 0;
9213
combinations[row][col] += 1;
9220
// Compute inverse of Jacobian
9221
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
9223
// Declare transformation matrix
9224
// Declare pointer to two dimensional array and initialise
9225
double **transform = new double *[num_derivatives];
9227
for (unsigned int j = 0; j < num_derivatives; j++)
9229
transform[j] = new double [num_derivatives];
9230
for (unsigned int k = 0; k < num_derivatives; k++)
9231
transform[j][k] = 1;
9234
// Construct transformation matrix
9235
for (unsigned int row = 0; row < num_derivatives; row++)
9237
for (unsigned int col = 0; col < num_derivatives; col++)
9239
for (unsigned int k = 0; k < n; k++)
9240
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
9245
for (unsigned int j = 0; j < 2*num_derivatives; j++)
9248
if (0 <= i && i <= 2)
9250
// Map degree of freedom to element degree of freedom
9251
const unsigned int dof = i;
9253
// Generate scalings
9254
const double scalings_y_0 = 1;
9255
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9257
// Compute psitilde_a
9258
const double psitilde_a_0 = 1;
9259
const double psitilde_a_1 = x;
9261
// Compute psitilde_bs
9262
const double psitilde_bs_0_0 = 1;
9263
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9264
const double psitilde_bs_1_0 = 1;
9266
// Compute basisvalues
9267
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9268
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9269
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9271
// Table(s) of coefficients
9272
static const double coefficients0[3][3] = \
9273
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9274
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9275
{0.471404520791032, 0, 0.333333333333333}};
9277
// Interesting (new) part
9278
// Tables of derivatives of the polynomial base (transpose)
9279
static const double dmats0[3][3] = \
9281
{4.89897948556636, 0, 0},
9284
static const double dmats1[3][3] = \
9286
{2.44948974278318, 0, 0},
9287
{4.24264068711928, 0, 0}};
9289
// Compute reference derivatives
9290
// Declare pointer to array of derivatives on FIAT element
9291
double *derivatives = new double [num_derivatives];
9293
// Declare coefficients
9294
double coeff0_0 = 0;
9295
double coeff0_1 = 0;
9296
double coeff0_2 = 0;
9298
// Declare new coefficients
9299
double new_coeff0_0 = 0;
9300
double new_coeff0_1 = 0;
9301
double new_coeff0_2 = 0;
9303
// Loop possible derivatives
9304
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9306
// Get values from coefficients array
9307
new_coeff0_0 = coefficients0[dof][0];
9308
new_coeff0_1 = coefficients0[dof][1];
9309
new_coeff0_2 = coefficients0[dof][2];
9311
// Loop derivative order
9312
for (unsigned int j = 0; j < n; j++)
9314
// Update old coefficients
9315
coeff0_0 = new_coeff0_0;
9316
coeff0_1 = new_coeff0_1;
9317
coeff0_2 = new_coeff0_2;
9319
if(combinations[deriv_num][j] == 0)
9321
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9322
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9323
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9325
if(combinations[deriv_num][j] == 1)
9327
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9328
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9329
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9333
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9334
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9337
// Transform derivatives back to physical element
9338
for (unsigned int row = 0; row < num_derivatives; row++)
9340
for (unsigned int col = 0; col < num_derivatives; col++)
9342
values[row] += transform[row][col]*derivatives[col];
9345
// Delete pointer to array of derivatives on FIAT element
9346
delete [] derivatives;
9348
// Delete pointer to array of combinations of derivatives and transform
9349
for (unsigned int row = 0; row < num_derivatives; row++)
9351
delete [] combinations[row];
9352
delete [] transform[row];
9355
delete [] combinations;
9356
delete [] transform;
9359
if (3 <= i && i <= 5)
9361
// Map degree of freedom to element degree of freedom
9362
const unsigned int dof = i - 3;
9364
// Generate scalings
9365
const double scalings_y_0 = 1;
9366
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9368
// Compute psitilde_a
9369
const double psitilde_a_0 = 1;
9370
const double psitilde_a_1 = x;
9372
// Compute psitilde_bs
9373
const double psitilde_bs_0_0 = 1;
9374
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9375
const double psitilde_bs_1_0 = 1;
9377
// Compute basisvalues
9378
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9379
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9380
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9382
// Table(s) of coefficients
9383
static const double coefficients0[3][3] = \
9384
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9385
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9386
{0.471404520791032, 0, 0.333333333333333}};
9388
// Interesting (new) part
9389
// Tables of derivatives of the polynomial base (transpose)
9390
static const double dmats0[3][3] = \
9392
{4.89897948556636, 0, 0},
9395
static const double dmats1[3][3] = \
9397
{2.44948974278318, 0, 0},
9398
{4.24264068711928, 0, 0}};
9400
// Compute reference derivatives
9401
// Declare pointer to array of derivatives on FIAT element
9402
double *derivatives = new double [num_derivatives];
9404
// Declare coefficients
9405
double coeff0_0 = 0;
9406
double coeff0_1 = 0;
9407
double coeff0_2 = 0;
9409
// Declare new coefficients
9410
double new_coeff0_0 = 0;
9411
double new_coeff0_1 = 0;
9412
double new_coeff0_2 = 0;
9414
// Loop possible derivatives
9415
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9417
// Get values from coefficients array
9418
new_coeff0_0 = coefficients0[dof][0];
9419
new_coeff0_1 = coefficients0[dof][1];
9420
new_coeff0_2 = coefficients0[dof][2];
9422
// Loop derivative order
9423
for (unsigned int j = 0; j < n; j++)
9425
// Update old coefficients
9426
coeff0_0 = new_coeff0_0;
9427
coeff0_1 = new_coeff0_1;
9428
coeff0_2 = new_coeff0_2;
9430
if(combinations[deriv_num][j] == 0)
9432
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9433
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9434
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9436
if(combinations[deriv_num][j] == 1)
9438
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9439
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9440
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9444
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9445
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9448
// Transform derivatives back to physical element
9449
for (unsigned int row = 0; row < num_derivatives; row++)
9451
for (unsigned int col = 0; col < num_derivatives; col++)
9453
values[num_derivatives + row] += transform[row][col]*derivatives[col];
9456
// Delete pointer to array of derivatives on FIAT element
9457
delete [] derivatives;
9459
// Delete pointer to array of combinations of derivatives and transform
9460
for (unsigned int row = 0; row < num_derivatives; row++)
9462
delete [] combinations[row];
9463
delete [] transform[row];
9466
delete [] combinations;
9467
delete [] transform;
9472
/// Evaluate order n derivatives of all basis functions at given point in cell
9473
void cahnhilliard2d_1_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
9475
const double* coordinates,
9476
const ufc::cell& c) const
9478
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9481
/// Evaluate linear functional for dof i on the function f
9482
double cahnhilliard2d_1_finite_element_0::evaluate_dof(unsigned int i,
9483
const ufc::function& f,
9484
const ufc::cell& c) const
9486
// The reference points, direction and weights:
9487
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
9488
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
9489
static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
9491
const double * const * x = c.coordinates;
9492
double result = 0.0;
9493
// Iterate over the points:
9494
// Evaluate basis functions for affine mapping
9495
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9496
const double w1 = X[i][0][0];
9497
const double w2 = X[i][0][1];
9499
// Compute affine mapping y = F(X)
9501
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9502
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9504
// Evaluate function at physical points
9506
f.evaluate(values, y, c);
9508
// Map function values using appropriate mapping
9509
// Affine map: Do nothing
9511
// Note that we do not map the weights (yet).
9513
// Take directional components
9514
for(int k = 0; k < 2; k++)
9515
result += values[k]*D[i][0][k];
9516
// Multiply by weights
9522
/// Evaluate linear functionals for all dofs on the function f
9523
void cahnhilliard2d_1_finite_element_0::evaluate_dofs(double* values,
9524
const ufc::function& f,
9525
const ufc::cell& c) const
9527
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9530
/// Interpolate vertex values from dof values
9531
void cahnhilliard2d_1_finite_element_0::interpolate_vertex_values(double* vertex_values,
9532
const double* dof_values,
9533
const ufc::cell& c) const
9535
// Evaluate at vertices and use affine mapping
9536
vertex_values[0] = dof_values[0];
9537
vertex_values[2] = dof_values[1];
9538
vertex_values[4] = dof_values[2];
9539
// Evaluate at vertices and use affine mapping
9540
vertex_values[1] = dof_values[3];
9541
vertex_values[3] = dof_values[4];
9542
vertex_values[5] = dof_values[5];
9545
/// Return the number of sub elements (for a mixed element)
9546
unsigned int cahnhilliard2d_1_finite_element_0::num_sub_elements() const
9551
/// Create a new finite element for sub element i (for a mixed element)
9552
ufc::finite_element* cahnhilliard2d_1_finite_element_0::create_sub_element(unsigned int i) const
9557
return new cahnhilliard2d_1_finite_element_0_0();
9560
return new cahnhilliard2d_1_finite_element_0_1();
9568
cahnhilliard2d_1_finite_element_1_0::cahnhilliard2d_1_finite_element_1_0() : ufc::finite_element()
9574
cahnhilliard2d_1_finite_element_1_0::~cahnhilliard2d_1_finite_element_1_0()
9579
/// Return a string identifying the finite element
9580
const char* cahnhilliard2d_1_finite_element_1_0::signature() const
9582
return "FiniteElement('Lagrange', 'triangle', 1)";
9585
/// Return the cell shape
9586
ufc::shape cahnhilliard2d_1_finite_element_1_0::cell_shape() const
9588
return ufc::triangle;
9591
/// Return the dimension of the finite element function space
9592
unsigned int cahnhilliard2d_1_finite_element_1_0::space_dimension() const
9597
/// Return the rank of the value space
9598
unsigned int cahnhilliard2d_1_finite_element_1_0::value_rank() const
9603
/// Return the dimension of the value space for axis i
9604
unsigned int cahnhilliard2d_1_finite_element_1_0::value_dimension(unsigned int i) const
9609
/// Evaluate basis function i at given point in cell
9610
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis(unsigned int i,
9612
const double* coordinates,
9613
const ufc::cell& c) const
9615
// Extract vertex coordinates
9616
const double * const * element_coordinates = c.coordinates;
9618
// Compute Jacobian of affine map from reference cell
9619
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9620
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9621
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9622
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9624
// Compute determinant of Jacobian
9625
const double detJ = J_00*J_11 - J_01*J_10;
9627
// Compute inverse of Jacobian
9629
// Get coordinates and map to the reference (UFC) element
9630
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9631
element_coordinates[0][0]*element_coordinates[2][1] +\
9632
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9633
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9634
element_coordinates[1][0]*element_coordinates[0][1] -\
9635
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9637
// Map coordinates to the reference square
9638
if (std::abs(y - 1.0) < 1e-14)
9641
x = 2.0 *x/(1.0 - y) - 1.0;
9647
// Map degree of freedom to element degree of freedom
9648
const unsigned int dof = i;
9650
// Generate scalings
9651
const double scalings_y_0 = 1;
9652
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9654
// Compute psitilde_a
9655
const double psitilde_a_0 = 1;
9656
const double psitilde_a_1 = x;
9658
// Compute psitilde_bs
9659
const double psitilde_bs_0_0 = 1;
9660
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9661
const double psitilde_bs_1_0 = 1;
9663
// Compute basisvalues
9664
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9665
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9666
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9668
// Table(s) of coefficients
9669
static const double coefficients0[3][3] = \
9670
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9671
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9672
{0.471404520791032, 0, 0.333333333333333}};
9674
// Extract relevant coefficients
9675
const double coeff0_0 = coefficients0[dof][0];
9676
const double coeff0_1 = coefficients0[dof][1];
9677
const double coeff0_2 = coefficients0[dof][2];
9680
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9683
/// Evaluate all basis functions at given point in cell
9684
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis_all(double* values,
9685
const double* coordinates,
9686
const ufc::cell& c) const
9688
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9691
/// Evaluate order n derivatives of basis function i at given point in cell
9692
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
9695
const double* coordinates,
9696
const ufc::cell& c) const
9698
// Extract vertex coordinates
9699
const double * const * element_coordinates = c.coordinates;
9701
// Compute Jacobian of affine map from reference cell
9702
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9703
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9704
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9705
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9707
// Compute determinant of Jacobian
9708
const double detJ = J_00*J_11 - J_01*J_10;
9710
// Compute inverse of Jacobian
9712
// Get coordinates and map to the reference (UFC) element
9713
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9714
element_coordinates[0][0]*element_coordinates[2][1] +\
9715
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9716
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9717
element_coordinates[1][0]*element_coordinates[0][1] -\
9718
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9720
// Map coordinates to the reference square
9721
if (std::abs(y - 1.0) < 1e-14)
9724
x = 2.0 *x/(1.0 - y) - 1.0;
9727
// Compute number of derivatives
9728
unsigned int num_derivatives = 1;
9730
for (unsigned int j = 0; j < n; j++)
9731
num_derivatives *= 2;
9734
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9735
unsigned int **combinations = new unsigned int *[num_derivatives];
9737
for (unsigned int j = 0; j < num_derivatives; j++)
9739
combinations[j] = new unsigned int [n];
9740
for (unsigned int k = 0; k < n; k++)
9741
combinations[j][k] = 0;
9744
// Generate combinations of derivatives
9745
for (unsigned int row = 1; row < num_derivatives; row++)
9747
for (unsigned int num = 0; num < row; num++)
9749
for (unsigned int col = n-1; col+1 > 0; col--)
9751
if (combinations[row][col] + 1 > 1)
9752
combinations[row][col] = 0;
9755
combinations[row][col] += 1;
9762
// Compute inverse of Jacobian
9763
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
9765
// Declare transformation matrix
9766
// Declare pointer to two dimensional array and initialise
9767
double **transform = new double *[num_derivatives];
9769
for (unsigned int j = 0; j < num_derivatives; j++)
9771
transform[j] = new double [num_derivatives];
9772
for (unsigned int k = 0; k < num_derivatives; k++)
9773
transform[j][k] = 1;
9776
// Construct transformation matrix
9777
for (unsigned int row = 0; row < num_derivatives; row++)
9779
for (unsigned int col = 0; col < num_derivatives; col++)
9781
for (unsigned int k = 0; k < n; k++)
9782
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
9787
for (unsigned int j = 0; j < 1*num_derivatives; j++)
9790
// Map degree of freedom to element degree of freedom
9791
const unsigned int dof = i;
9793
// Generate scalings
9794
const double scalings_y_0 = 1;
9795
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9797
// Compute psitilde_a
9798
const double psitilde_a_0 = 1;
9799
const double psitilde_a_1 = x;
9801
// Compute psitilde_bs
9802
const double psitilde_bs_0_0 = 1;
9803
const double psitilde_bs_0_1 = 1.5*y + 0.5;
9804
const double psitilde_bs_1_0 = 1;
9806
// Compute basisvalues
9807
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9808
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9809
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9811
// Table(s) of coefficients
9812
static const double coefficients0[3][3] = \
9813
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
9814
{0.471404520791032, 0.288675134594813, -0.166666666666667},
9815
{0.471404520791032, 0, 0.333333333333333}};
9817
// Interesting (new) part
9818
// Tables of derivatives of the polynomial base (transpose)
9819
static const double dmats0[3][3] = \
9821
{4.89897948556636, 0, 0},
9824
static const double dmats1[3][3] = \
9826
{2.44948974278318, 0, 0},
9827
{4.24264068711928, 0, 0}};
9829
// Compute reference derivatives
9830
// Declare pointer to array of derivatives on FIAT element
9831
double *derivatives = new double [num_derivatives];
9833
// Declare coefficients
9834
double coeff0_0 = 0;
9835
double coeff0_1 = 0;
9836
double coeff0_2 = 0;
9838
// Declare new coefficients
9839
double new_coeff0_0 = 0;
9840
double new_coeff0_1 = 0;
9841
double new_coeff0_2 = 0;
9843
// Loop possible derivatives
9844
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9846
// Get values from coefficients array
9847
new_coeff0_0 = coefficients0[dof][0];
9848
new_coeff0_1 = coefficients0[dof][1];
9849
new_coeff0_2 = coefficients0[dof][2];
9851
// Loop derivative order
9852
for (unsigned int j = 0; j < n; j++)
9854
// Update old coefficients
9855
coeff0_0 = new_coeff0_0;
9856
coeff0_1 = new_coeff0_1;
9857
coeff0_2 = new_coeff0_2;
9859
if(combinations[deriv_num][j] == 0)
9861
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9862
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9863
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9865
if(combinations[deriv_num][j] == 1)
9867
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9868
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9869
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9873
// Compute derivatives on reference element as dot product of coefficients and basisvalues
9874
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9877
// Transform derivatives back to physical element
9878
for (unsigned int row = 0; row < num_derivatives; row++)
9880
for (unsigned int col = 0; col < num_derivatives; col++)
9882
values[row] += transform[row][col]*derivatives[col];
9885
// Delete pointer to array of derivatives on FIAT element
9886
delete [] derivatives;
9888
// Delete pointer to array of combinations of derivatives and transform
9889
for (unsigned int row = 0; row < num_derivatives; row++)
9891
delete [] combinations[row];
9892
delete [] transform[row];
9895
delete [] combinations;
9896
delete [] transform;
9899
/// Evaluate order n derivatives of all basis functions at given point in cell
9900
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
9902
const double* coordinates,
9903
const ufc::cell& c) const
9905
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9908
/// Evaluate linear functional for dof i on the function f
9909
double cahnhilliard2d_1_finite_element_1_0::evaluate_dof(unsigned int i,
9910
const ufc::function& f,
9911
const ufc::cell& c) const
9913
// The reference points, direction and weights:
9914
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
9915
static const double W[3][1] = {{1}, {1}, {1}};
9916
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
9918
const double * const * x = c.coordinates;
9919
double result = 0.0;
9920
// Iterate over the points:
9921
// Evaluate basis functions for affine mapping
9922
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9923
const double w1 = X[i][0][0];
9924
const double w2 = X[i][0][1];
9926
// Compute affine mapping y = F(X)
9928
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9929
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9931
// Evaluate function at physical points
9933
f.evaluate(values, y, c);
9935
// Map function values using appropriate mapping
9936
// Affine map: Do nothing
9938
// Note that we do not map the weights (yet).
9940
// Take directional components
9941
for(int k = 0; k < 1; k++)
9942
result += values[k]*D[i][0][k];
9943
// Multiply by weights
9949
/// Evaluate linear functionals for all dofs on the function f
9950
void cahnhilliard2d_1_finite_element_1_0::evaluate_dofs(double* values,
9951
const ufc::function& f,
9952
const ufc::cell& c) const
9954
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9957
/// Interpolate vertex values from dof values
9958
void cahnhilliard2d_1_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
9959
const double* dof_values,
9960
const ufc::cell& c) const
9962
// Evaluate at vertices and use affine mapping
9963
vertex_values[0] = dof_values[0];
9964
vertex_values[1] = dof_values[1];
9965
vertex_values[2] = dof_values[2];
9968
/// Return the number of sub elements (for a mixed element)
9969
unsigned int cahnhilliard2d_1_finite_element_1_0::num_sub_elements() const
9974
/// Create a new finite element for sub element i (for a mixed element)
9975
ufc::finite_element* cahnhilliard2d_1_finite_element_1_0::create_sub_element(unsigned int i) const
9977
return new cahnhilliard2d_1_finite_element_1_0();
9982
cahnhilliard2d_1_finite_element_1_1::cahnhilliard2d_1_finite_element_1_1() : ufc::finite_element()
9988
cahnhilliard2d_1_finite_element_1_1::~cahnhilliard2d_1_finite_element_1_1()
9993
/// Return a string identifying the finite element
9994
const char* cahnhilliard2d_1_finite_element_1_1::signature() const
9996
return "FiniteElement('Lagrange', 'triangle', 1)";
9999
/// Return the cell shape
10000
ufc::shape cahnhilliard2d_1_finite_element_1_1::cell_shape() const
10002
return ufc::triangle;
10005
/// Return the dimension of the finite element function space
10006
unsigned int cahnhilliard2d_1_finite_element_1_1::space_dimension() const
10011
/// Return the rank of the value space
10012
unsigned int cahnhilliard2d_1_finite_element_1_1::value_rank() const
10017
/// Return the dimension of the value space for axis i
10018
unsigned int cahnhilliard2d_1_finite_element_1_1::value_dimension(unsigned int i) const
10023
/// Evaluate basis function i at given point in cell
10024
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis(unsigned int i,
10026
const double* coordinates,
10027
const ufc::cell& c) const
10029
// Extract vertex coordinates
10030
const double * const * element_coordinates = c.coordinates;
10032
// Compute Jacobian of affine map from reference cell
10033
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10034
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10035
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10036
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10038
// Compute determinant of Jacobian
10039
const double detJ = J_00*J_11 - J_01*J_10;
10041
// Compute inverse of Jacobian
10043
// Get coordinates and map to the reference (UFC) element
10044
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10045
element_coordinates[0][0]*element_coordinates[2][1] +\
10046
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10047
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10048
element_coordinates[1][0]*element_coordinates[0][1] -\
10049
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10051
// Map coordinates to the reference square
10052
if (std::abs(y - 1.0) < 1e-14)
10055
x = 2.0 *x/(1.0 - y) - 1.0;
10061
// Map degree of freedom to element degree of freedom
10062
const unsigned int dof = i;
10064
// Generate scalings
10065
const double scalings_y_0 = 1;
10066
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10068
// Compute psitilde_a
10069
const double psitilde_a_0 = 1;
10070
const double psitilde_a_1 = x;
10072
// Compute psitilde_bs
10073
const double psitilde_bs_0_0 = 1;
10074
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10075
const double psitilde_bs_1_0 = 1;
10077
// Compute basisvalues
10078
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10079
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10080
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10082
// Table(s) of coefficients
10083
static const double coefficients0[3][3] = \
10084
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10085
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10086
{0.471404520791032, 0, 0.333333333333333}};
10088
// Extract relevant coefficients
10089
const double coeff0_0 = coefficients0[dof][0];
10090
const double coeff0_1 = coefficients0[dof][1];
10091
const double coeff0_2 = coefficients0[dof][2];
10093
// Compute value(s)
10094
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10097
/// Evaluate all basis functions at given point in cell
10098
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis_all(double* values,
10099
const double* coordinates,
10100
const ufc::cell& c) const
10102
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
10105
/// Evaluate order n derivatives of basis function i at given point in cell
10106
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
10109
const double* coordinates,
10110
const ufc::cell& c) const
10112
// Extract vertex coordinates
10113
const double * const * element_coordinates = c.coordinates;
10115
// Compute Jacobian of affine map from reference cell
10116
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10117
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10118
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10119
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10121
// Compute determinant of Jacobian
10122
const double detJ = J_00*J_11 - J_01*J_10;
10124
// Compute inverse of Jacobian
10126
// Get coordinates and map to the reference (UFC) element
10127
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10128
element_coordinates[0][0]*element_coordinates[2][1] +\
10129
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10130
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10131
element_coordinates[1][0]*element_coordinates[0][1] -\
10132
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10134
// Map coordinates to the reference square
10135
if (std::abs(y - 1.0) < 1e-14)
10138
x = 2.0 *x/(1.0 - y) - 1.0;
10141
// Compute number of derivatives
10142
unsigned int num_derivatives = 1;
10144
for (unsigned int j = 0; j < n; j++)
10145
num_derivatives *= 2;
10148
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10149
unsigned int **combinations = new unsigned int *[num_derivatives];
10151
for (unsigned int j = 0; j < num_derivatives; j++)
10153
combinations[j] = new unsigned int [n];
10154
for (unsigned int k = 0; k < n; k++)
10155
combinations[j][k] = 0;
10158
// Generate combinations of derivatives
10159
for (unsigned int row = 1; row < num_derivatives; row++)
10161
for (unsigned int num = 0; num < row; num++)
10163
for (unsigned int col = n-1; col+1 > 0; col--)
10165
if (combinations[row][col] + 1 > 1)
10166
combinations[row][col] = 0;
10169
combinations[row][col] += 1;
10176
// Compute inverse of Jacobian
10177
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10179
// Declare transformation matrix
10180
// Declare pointer to two dimensional array and initialise
10181
double **transform = new double *[num_derivatives];
10183
for (unsigned int j = 0; j < num_derivatives; j++)
10185
transform[j] = new double [num_derivatives];
10186
for (unsigned int k = 0; k < num_derivatives; k++)
10187
transform[j][k] = 1;
10190
// Construct transformation matrix
10191
for (unsigned int row = 0; row < num_derivatives; row++)
10193
for (unsigned int col = 0; col < num_derivatives; col++)
10195
for (unsigned int k = 0; k < n; k++)
10196
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10201
for (unsigned int j = 0; j < 1*num_derivatives; j++)
10204
// Map degree of freedom to element degree of freedom
10205
const unsigned int dof = i;
10207
// Generate scalings
10208
const double scalings_y_0 = 1;
10209
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10211
// Compute psitilde_a
10212
const double psitilde_a_0 = 1;
10213
const double psitilde_a_1 = x;
10215
// Compute psitilde_bs
10216
const double psitilde_bs_0_0 = 1;
10217
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10218
const double psitilde_bs_1_0 = 1;
10220
// Compute basisvalues
10221
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10222
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10223
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10225
// Table(s) of coefficients
10226
static const double coefficients0[3][3] = \
10227
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10228
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10229
{0.471404520791032, 0, 0.333333333333333}};
10231
// Interesting (new) part
10232
// Tables of derivatives of the polynomial base (transpose)
10233
static const double dmats0[3][3] = \
10235
{4.89897948556636, 0, 0},
10238
static const double dmats1[3][3] = \
10240
{2.44948974278318, 0, 0},
10241
{4.24264068711928, 0, 0}};
10243
// Compute reference derivatives
10244
// Declare pointer to array of derivatives on FIAT element
10245
double *derivatives = new double [num_derivatives];
10247
// Declare coefficients
10248
double coeff0_0 = 0;
10249
double coeff0_1 = 0;
10250
double coeff0_2 = 0;
10252
// Declare new coefficients
10253
double new_coeff0_0 = 0;
10254
double new_coeff0_1 = 0;
10255
double new_coeff0_2 = 0;
10257
// Loop possible derivatives
10258
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10260
// Get values from coefficients array
10261
new_coeff0_0 = coefficients0[dof][0];
10262
new_coeff0_1 = coefficients0[dof][1];
10263
new_coeff0_2 = coefficients0[dof][2];
10265
// Loop derivative order
10266
for (unsigned int j = 0; j < n; j++)
10268
// Update old coefficients
10269
coeff0_0 = new_coeff0_0;
10270
coeff0_1 = new_coeff0_1;
10271
coeff0_2 = new_coeff0_2;
10273
if(combinations[deriv_num][j] == 0)
10275
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10276
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10277
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10279
if(combinations[deriv_num][j] == 1)
10281
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10282
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10283
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10287
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10288
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10291
// Transform derivatives back to physical element
10292
for (unsigned int row = 0; row < num_derivatives; row++)
10294
for (unsigned int col = 0; col < num_derivatives; col++)
10296
values[row] += transform[row][col]*derivatives[col];
10299
// Delete pointer to array of derivatives on FIAT element
10300
delete [] derivatives;
10302
// Delete pointer to array of combinations of derivatives and transform
10303
for (unsigned int row = 0; row < num_derivatives; row++)
10305
delete [] combinations[row];
10306
delete [] transform[row];
10309
delete [] combinations;
10310
delete [] transform;
10313
/// Evaluate order n derivatives of all basis functions at given point in cell
10314
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
10316
const double* coordinates,
10317
const ufc::cell& c) const
10319
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
10322
/// Evaluate linear functional for dof i on the function f
10323
double cahnhilliard2d_1_finite_element_1_1::evaluate_dof(unsigned int i,
10324
const ufc::function& f,
10325
const ufc::cell& c) const
10327
// The reference points, direction and weights:
10328
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
10329
static const double W[3][1] = {{1}, {1}, {1}};
10330
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
10332
const double * const * x = c.coordinates;
10333
double result = 0.0;
10334
// Iterate over the points:
10335
// Evaluate basis functions for affine mapping
10336
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
10337
const double w1 = X[i][0][0];
10338
const double w2 = X[i][0][1];
10340
// Compute affine mapping y = F(X)
10342
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
10343
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
10345
// Evaluate function at physical points
10347
f.evaluate(values, y, c);
10349
// Map function values using appropriate mapping
10350
// Affine map: Do nothing
10352
// Note that we do not map the weights (yet).
10354
// Take directional components
10355
for(int k = 0; k < 1; k++)
10356
result += values[k]*D[i][0][k];
10357
// Multiply by weights
10363
/// Evaluate linear functionals for all dofs on the function f
10364
void cahnhilliard2d_1_finite_element_1_1::evaluate_dofs(double* values,
10365
const ufc::function& f,
10366
const ufc::cell& c) const
10368
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10371
/// Interpolate vertex values from dof values
10372
void cahnhilliard2d_1_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
10373
const double* dof_values,
10374
const ufc::cell& c) const
10376
// Evaluate at vertices and use affine mapping
10377
vertex_values[0] = dof_values[0];
10378
vertex_values[1] = dof_values[1];
10379
vertex_values[2] = dof_values[2];
10382
/// Return the number of sub elements (for a mixed element)
10383
unsigned int cahnhilliard2d_1_finite_element_1_1::num_sub_elements() const
10388
/// Create a new finite element for sub element i (for a mixed element)
10389
ufc::finite_element* cahnhilliard2d_1_finite_element_1_1::create_sub_element(unsigned int i) const
10391
return new cahnhilliard2d_1_finite_element_1_1();
10396
cahnhilliard2d_1_finite_element_1::cahnhilliard2d_1_finite_element_1() : ufc::finite_element()
10402
cahnhilliard2d_1_finite_element_1::~cahnhilliard2d_1_finite_element_1()
10407
/// Return a string identifying the finite element
10408
const char* cahnhilliard2d_1_finite_element_1::signature() const
10410
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
10413
/// Return the cell shape
10414
ufc::shape cahnhilliard2d_1_finite_element_1::cell_shape() const
10416
return ufc::triangle;
10419
/// Return the dimension of the finite element function space
10420
unsigned int cahnhilliard2d_1_finite_element_1::space_dimension() const
10425
/// Return the rank of the value space
10426
unsigned int cahnhilliard2d_1_finite_element_1::value_rank() const
10431
/// Return the dimension of the value space for axis i
10432
unsigned int cahnhilliard2d_1_finite_element_1::value_dimension(unsigned int i) const
10437
/// Evaluate basis function i at given point in cell
10438
void cahnhilliard2d_1_finite_element_1::evaluate_basis(unsigned int i,
10440
const double* coordinates,
10441
const ufc::cell& c) const
10443
// Extract vertex coordinates
10444
const double * const * element_coordinates = c.coordinates;
10446
// Compute Jacobian of affine map from reference cell
10447
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10448
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10449
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10450
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10452
// Compute determinant of Jacobian
10453
const double detJ = J_00*J_11 - J_01*J_10;
10455
// Compute inverse of Jacobian
10457
// Get coordinates and map to the reference (UFC) element
10458
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10459
element_coordinates[0][0]*element_coordinates[2][1] +\
10460
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10461
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10462
element_coordinates[1][0]*element_coordinates[0][1] -\
10463
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10465
// Map coordinates to the reference square
10466
if (std::abs(y - 1.0) < 1e-14)
10469
x = 2.0 *x/(1.0 - y) - 1.0;
10476
if (0 <= i && i <= 2)
10478
// Map degree of freedom to element degree of freedom
10479
const unsigned int dof = i;
10481
// Generate scalings
10482
const double scalings_y_0 = 1;
10483
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10485
// Compute psitilde_a
10486
const double psitilde_a_0 = 1;
10487
const double psitilde_a_1 = x;
10489
// Compute psitilde_bs
10490
const double psitilde_bs_0_0 = 1;
10491
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10492
const double psitilde_bs_1_0 = 1;
10494
// Compute basisvalues
10495
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10496
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10497
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10499
// Table(s) of coefficients
10500
static const double coefficients0[3][3] = \
10501
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10502
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10503
{0.471404520791032, 0, 0.333333333333333}};
10505
// Extract relevant coefficients
10506
const double coeff0_0 = coefficients0[dof][0];
10507
const double coeff0_1 = coefficients0[dof][1];
10508
const double coeff0_2 = coefficients0[dof][2];
10510
// Compute value(s)
10511
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10514
if (3 <= i && i <= 5)
10516
// Map degree of freedom to element degree of freedom
10517
const unsigned int dof = i - 3;
10519
// Generate scalings
10520
const double scalings_y_0 = 1;
10521
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10523
// Compute psitilde_a
10524
const double psitilde_a_0 = 1;
10525
const double psitilde_a_1 = x;
10527
// Compute psitilde_bs
10528
const double psitilde_bs_0_0 = 1;
10529
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10530
const double psitilde_bs_1_0 = 1;
10532
// Compute basisvalues
10533
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10534
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10535
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10537
// Table(s) of coefficients
10538
static const double coefficients0[3][3] = \
10539
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10540
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10541
{0.471404520791032, 0, 0.333333333333333}};
10543
// Extract relevant coefficients
10544
const double coeff0_0 = coefficients0[dof][0];
10545
const double coeff0_1 = coefficients0[dof][1];
10546
const double coeff0_2 = coefficients0[dof][2];
10548
// Compute value(s)
10549
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10554
/// Evaluate all basis functions at given point in cell
10555
void cahnhilliard2d_1_finite_element_1::evaluate_basis_all(double* values,
10556
const double* coordinates,
10557
const ufc::cell& c) const
10559
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
10562
/// Evaluate order n derivatives of basis function i at given point in cell
10563
void cahnhilliard2d_1_finite_element_1::evaluate_basis_derivatives(unsigned int i,
10566
const double* coordinates,
10567
const ufc::cell& c) const
10569
// Extract vertex coordinates
10570
const double * const * element_coordinates = c.coordinates;
10572
// Compute Jacobian of affine map from reference cell
10573
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10574
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10575
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10576
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10578
// Compute determinant of Jacobian
10579
const double detJ = J_00*J_11 - J_01*J_10;
10581
// Compute inverse of Jacobian
10583
// Get coordinates and map to the reference (UFC) element
10584
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10585
element_coordinates[0][0]*element_coordinates[2][1] +\
10586
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10587
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10588
element_coordinates[1][0]*element_coordinates[0][1] -\
10589
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10591
// Map coordinates to the reference square
10592
if (std::abs(y - 1.0) < 1e-14)
10595
x = 2.0 *x/(1.0 - y) - 1.0;
10598
// Compute number of derivatives
10599
unsigned int num_derivatives = 1;
10601
for (unsigned int j = 0; j < n; j++)
10602
num_derivatives *= 2;
10605
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10606
unsigned int **combinations = new unsigned int *[num_derivatives];
10608
for (unsigned int j = 0; j < num_derivatives; j++)
10610
combinations[j] = new unsigned int [n];
10611
for (unsigned int k = 0; k < n; k++)
10612
combinations[j][k] = 0;
10615
// Generate combinations of derivatives
10616
for (unsigned int row = 1; row < num_derivatives; row++)
10618
for (unsigned int num = 0; num < row; num++)
10620
for (unsigned int col = n-1; col+1 > 0; col--)
10622
if (combinations[row][col] + 1 > 1)
10623
combinations[row][col] = 0;
10626
combinations[row][col] += 1;
10633
// Compute inverse of Jacobian
10634
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10636
// Declare transformation matrix
10637
// Declare pointer to two dimensional array and initialise
10638
double **transform = new double *[num_derivatives];
10640
for (unsigned int j = 0; j < num_derivatives; j++)
10642
transform[j] = new double [num_derivatives];
10643
for (unsigned int k = 0; k < num_derivatives; k++)
10644
transform[j][k] = 1;
10647
// Construct transformation matrix
10648
for (unsigned int row = 0; row < num_derivatives; row++)
10650
for (unsigned int col = 0; col < num_derivatives; col++)
10652
for (unsigned int k = 0; k < n; k++)
10653
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10658
for (unsigned int j = 0; j < 2*num_derivatives; j++)
10661
if (0 <= i && i <= 2)
10663
// Map degree of freedom to element degree of freedom
10664
const unsigned int dof = i;
10666
// Generate scalings
10667
const double scalings_y_0 = 1;
10668
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10670
// Compute psitilde_a
10671
const double psitilde_a_0 = 1;
10672
const double psitilde_a_1 = x;
10674
// Compute psitilde_bs
10675
const double psitilde_bs_0_0 = 1;
10676
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10677
const double psitilde_bs_1_0 = 1;
10679
// Compute basisvalues
10680
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10681
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10682
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10684
// Table(s) of coefficients
10685
static const double coefficients0[3][3] = \
10686
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10687
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10688
{0.471404520791032, 0, 0.333333333333333}};
10690
// Interesting (new) part
10691
// Tables of derivatives of the polynomial base (transpose)
10692
static const double dmats0[3][3] = \
10694
{4.89897948556636, 0, 0},
10697
static const double dmats1[3][3] = \
10699
{2.44948974278318, 0, 0},
10700
{4.24264068711928, 0, 0}};
10702
// Compute reference derivatives
10703
// Declare pointer to array of derivatives on FIAT element
10704
double *derivatives = new double [num_derivatives];
10706
// Declare coefficients
10707
double coeff0_0 = 0;
10708
double coeff0_1 = 0;
10709
double coeff0_2 = 0;
10711
// Declare new coefficients
10712
double new_coeff0_0 = 0;
10713
double new_coeff0_1 = 0;
10714
double new_coeff0_2 = 0;
10716
// Loop possible derivatives
10717
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10719
// Get values from coefficients array
10720
new_coeff0_0 = coefficients0[dof][0];
10721
new_coeff0_1 = coefficients0[dof][1];
10722
new_coeff0_2 = coefficients0[dof][2];
10724
// Loop derivative order
10725
for (unsigned int j = 0; j < n; j++)
10727
// Update old coefficients
10728
coeff0_0 = new_coeff0_0;
10729
coeff0_1 = new_coeff0_1;
10730
coeff0_2 = new_coeff0_2;
10732
if(combinations[deriv_num][j] == 0)
10734
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10735
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10736
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10738
if(combinations[deriv_num][j] == 1)
10740
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10741
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10742
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10746
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10747
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10750
// Transform derivatives back to physical element
10751
for (unsigned int row = 0; row < num_derivatives; row++)
10753
for (unsigned int col = 0; col < num_derivatives; col++)
10755
values[row] += transform[row][col]*derivatives[col];
10758
// Delete pointer to array of derivatives on FIAT element
10759
delete [] derivatives;
10761
// Delete pointer to array of combinations of derivatives and transform
10762
for (unsigned int row = 0; row < num_derivatives; row++)
10764
delete [] combinations[row];
10765
delete [] transform[row];
10768
delete [] combinations;
10769
delete [] transform;
10772
if (3 <= i && i <= 5)
10774
// Map degree of freedom to element degree of freedom
10775
const unsigned int dof = i - 3;
10777
// Generate scalings
10778
const double scalings_y_0 = 1;
10779
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10781
// Compute psitilde_a
10782
const double psitilde_a_0 = 1;
10783
const double psitilde_a_1 = x;
10785
// Compute psitilde_bs
10786
const double psitilde_bs_0_0 = 1;
10787
const double psitilde_bs_0_1 = 1.5*y + 0.5;
10788
const double psitilde_bs_1_0 = 1;
10790
// Compute basisvalues
10791
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10792
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10793
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10795
// Table(s) of coefficients
10796
static const double coefficients0[3][3] = \
10797
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
10798
{0.471404520791032, 0.288675134594813, -0.166666666666667},
10799
{0.471404520791032, 0, 0.333333333333333}};
10801
// Interesting (new) part
10802
// Tables of derivatives of the polynomial base (transpose)
10803
static const double dmats0[3][3] = \
10805
{4.89897948556636, 0, 0},
10808
static const double dmats1[3][3] = \
10810
{2.44948974278318, 0, 0},
10811
{4.24264068711928, 0, 0}};
10813
// Compute reference derivatives
10814
// Declare pointer to array of derivatives on FIAT element
10815
double *derivatives = new double [num_derivatives];
10817
// Declare coefficients
10818
double coeff0_0 = 0;
10819
double coeff0_1 = 0;
10820
double coeff0_2 = 0;
10822
// Declare new coefficients
10823
double new_coeff0_0 = 0;
10824
double new_coeff0_1 = 0;
10825
double new_coeff0_2 = 0;
10827
// Loop possible derivatives
10828
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10830
// Get values from coefficients array
10831
new_coeff0_0 = coefficients0[dof][0];
10832
new_coeff0_1 = coefficients0[dof][1];
10833
new_coeff0_2 = coefficients0[dof][2];
10835
// Loop derivative order
10836
for (unsigned int j = 0; j < n; j++)
10838
// Update old coefficients
10839
coeff0_0 = new_coeff0_0;
10840
coeff0_1 = new_coeff0_1;
10841
coeff0_2 = new_coeff0_2;
10843
if(combinations[deriv_num][j] == 0)
10845
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10846
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10847
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10849
if(combinations[deriv_num][j] == 1)
10851
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10852
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10853
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10857
// Compute derivatives on reference element as dot product of coefficients and basisvalues
10858
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10861
// Transform derivatives back to physical element
10862
for (unsigned int row = 0; row < num_derivatives; row++)
10864
for (unsigned int col = 0; col < num_derivatives; col++)
10866
values[num_derivatives + row] += transform[row][col]*derivatives[col];
10869
// Delete pointer to array of derivatives on FIAT element
10870
delete [] derivatives;
10872
// Delete pointer to array of combinations of derivatives and transform
10873
for (unsigned int row = 0; row < num_derivatives; row++)
10875
delete [] combinations[row];
10876
delete [] transform[row];
10879
delete [] combinations;
10880
delete [] transform;
10885
/// Evaluate order n derivatives of all basis functions at given point in cell
10886
void cahnhilliard2d_1_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
10888
const double* coordinates,
10889
const ufc::cell& c) const
10891
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
10894
/// Evaluate linear functional for dof i on the function f
10895
double cahnhilliard2d_1_finite_element_1::evaluate_dof(unsigned int i,
10896
const ufc::function& f,
10897
const ufc::cell& c) const
10899
// The reference points, direction and weights:
10900
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
10901
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
10902
static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
10904
const double * const * x = c.coordinates;
10905
double result = 0.0;
10906
// Iterate over the points:
10907
// Evaluate basis functions for affine mapping
10908
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
10909
const double w1 = X[i][0][0];
10910
const double w2 = X[i][0][1];
10912
// Compute affine mapping y = F(X)
10914
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
10915
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
10917
// Evaluate function at physical points
10919
f.evaluate(values, y, c);
10921
// Map function values using appropriate mapping
10922
// Affine map: Do nothing
10924
// Note that we do not map the weights (yet).
10926
// Take directional components
10927
for(int k = 0; k < 2; k++)
10928
result += values[k]*D[i][0][k];
10929
// Multiply by weights
10935
/// Evaluate linear functionals for all dofs on the function f
10936
void cahnhilliard2d_1_finite_element_1::evaluate_dofs(double* values,
10937
const ufc::function& f,
10938
const ufc::cell& c) const
10940
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10943
/// Interpolate vertex values from dof values
10944
void cahnhilliard2d_1_finite_element_1::interpolate_vertex_values(double* vertex_values,
10945
const double* dof_values,
10946
const ufc::cell& c) const
10948
// Evaluate at vertices and use affine mapping
10949
vertex_values[0] = dof_values[0];
10950
vertex_values[2] = dof_values[1];
10951
vertex_values[4] = dof_values[2];
10952
// Evaluate at vertices and use affine mapping
10953
vertex_values[1] = dof_values[3];
10954
vertex_values[3] = dof_values[4];
10955
vertex_values[5] = dof_values[5];
10958
/// Return the number of sub elements (for a mixed element)
10959
unsigned int cahnhilliard2d_1_finite_element_1::num_sub_elements() const
10964
/// Create a new finite element for sub element i (for a mixed element)
10965
ufc::finite_element* cahnhilliard2d_1_finite_element_1::create_sub_element(unsigned int i) const
10970
return new cahnhilliard2d_1_finite_element_1_0();
10973
return new cahnhilliard2d_1_finite_element_1_1();
10981
cahnhilliard2d_1_finite_element_2_0::cahnhilliard2d_1_finite_element_2_0() : ufc::finite_element()
10987
cahnhilliard2d_1_finite_element_2_0::~cahnhilliard2d_1_finite_element_2_0()
10992
/// Return a string identifying the finite element
10993
const char* cahnhilliard2d_1_finite_element_2_0::signature() const
10995
return "FiniteElement('Lagrange', 'triangle', 1)";
10998
/// Return the cell shape
10999
ufc::shape cahnhilliard2d_1_finite_element_2_0::cell_shape() const
11001
return ufc::triangle;
11004
/// Return the dimension of the finite element function space
11005
unsigned int cahnhilliard2d_1_finite_element_2_0::space_dimension() const
11010
/// Return the rank of the value space
11011
unsigned int cahnhilliard2d_1_finite_element_2_0::value_rank() const
11016
/// Return the dimension of the value space for axis i
11017
unsigned int cahnhilliard2d_1_finite_element_2_0::value_dimension(unsigned int i) const
11022
/// Evaluate basis function i at given point in cell
11023
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis(unsigned int i,
11025
const double* coordinates,
11026
const ufc::cell& c) const
11028
// Extract vertex coordinates
11029
const double * const * element_coordinates = c.coordinates;
11031
// Compute Jacobian of affine map from reference cell
11032
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11033
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11034
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11035
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11037
// Compute determinant of Jacobian
11038
const double detJ = J_00*J_11 - J_01*J_10;
11040
// Compute inverse of Jacobian
11042
// Get coordinates and map to the reference (UFC) element
11043
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11044
element_coordinates[0][0]*element_coordinates[2][1] +\
11045
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11046
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11047
element_coordinates[1][0]*element_coordinates[0][1] -\
11048
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11050
// Map coordinates to the reference square
11051
if (std::abs(y - 1.0) < 1e-14)
11054
x = 2.0 *x/(1.0 - y) - 1.0;
11060
// Map degree of freedom to element degree of freedom
11061
const unsigned int dof = i;
11063
// Generate scalings
11064
const double scalings_y_0 = 1;
11065
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11067
// Compute psitilde_a
11068
const double psitilde_a_0 = 1;
11069
const double psitilde_a_1 = x;
11071
// Compute psitilde_bs
11072
const double psitilde_bs_0_0 = 1;
11073
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11074
const double psitilde_bs_1_0 = 1;
11076
// Compute basisvalues
11077
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11078
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11079
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11081
// Table(s) of coefficients
11082
static const double coefficients0[3][3] = \
11083
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11084
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11085
{0.471404520791032, 0, 0.333333333333333}};
11087
// Extract relevant coefficients
11088
const double coeff0_0 = coefficients0[dof][0];
11089
const double coeff0_1 = coefficients0[dof][1];
11090
const double coeff0_2 = coefficients0[dof][2];
11092
// Compute value(s)
11093
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11096
/// Evaluate all basis functions at given point in cell
11097
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis_all(double* values,
11098
const double* coordinates,
11099
const ufc::cell& c) const
11101
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11104
/// Evaluate order n derivatives of basis function i at given point in cell
11105
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis_derivatives(unsigned int i,
11108
const double* coordinates,
11109
const ufc::cell& c) const
11111
// Extract vertex coordinates
11112
const double * const * element_coordinates = c.coordinates;
11114
// Compute Jacobian of affine map from reference cell
11115
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11116
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11117
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11118
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11120
// Compute determinant of Jacobian
11121
const double detJ = J_00*J_11 - J_01*J_10;
11123
// Compute inverse of Jacobian
11125
// Get coordinates and map to the reference (UFC) element
11126
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11127
element_coordinates[0][0]*element_coordinates[2][1] +\
11128
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11129
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11130
element_coordinates[1][0]*element_coordinates[0][1] -\
11131
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11133
// Map coordinates to the reference square
11134
if (std::abs(y - 1.0) < 1e-14)
11137
x = 2.0 *x/(1.0 - y) - 1.0;
11140
// Compute number of derivatives
11141
unsigned int num_derivatives = 1;
11143
for (unsigned int j = 0; j < n; j++)
11144
num_derivatives *= 2;
11147
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11148
unsigned int **combinations = new unsigned int *[num_derivatives];
11150
for (unsigned int j = 0; j < num_derivatives; j++)
11152
combinations[j] = new unsigned int [n];
11153
for (unsigned int k = 0; k < n; k++)
11154
combinations[j][k] = 0;
11157
// Generate combinations of derivatives
11158
for (unsigned int row = 1; row < num_derivatives; row++)
11160
for (unsigned int num = 0; num < row; num++)
11162
for (unsigned int col = n-1; col+1 > 0; col--)
11164
if (combinations[row][col] + 1 > 1)
11165
combinations[row][col] = 0;
11168
combinations[row][col] += 1;
11175
// Compute inverse of Jacobian
11176
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11178
// Declare transformation matrix
11179
// Declare pointer to two dimensional array and initialise
11180
double **transform = new double *[num_derivatives];
11182
for (unsigned int j = 0; j < num_derivatives; j++)
11184
transform[j] = new double [num_derivatives];
11185
for (unsigned int k = 0; k < num_derivatives; k++)
11186
transform[j][k] = 1;
11189
// Construct transformation matrix
11190
for (unsigned int row = 0; row < num_derivatives; row++)
11192
for (unsigned int col = 0; col < num_derivatives; col++)
11194
for (unsigned int k = 0; k < n; k++)
11195
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11200
for (unsigned int j = 0; j < 1*num_derivatives; j++)
11203
// Map degree of freedom to element degree of freedom
11204
const unsigned int dof = i;
11206
// Generate scalings
11207
const double scalings_y_0 = 1;
11208
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11210
// Compute psitilde_a
11211
const double psitilde_a_0 = 1;
11212
const double psitilde_a_1 = x;
11214
// Compute psitilde_bs
11215
const double psitilde_bs_0_0 = 1;
11216
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11217
const double psitilde_bs_1_0 = 1;
11219
// Compute basisvalues
11220
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11221
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11222
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11224
// Table(s) of coefficients
11225
static const double coefficients0[3][3] = \
11226
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11227
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11228
{0.471404520791032, 0, 0.333333333333333}};
11230
// Interesting (new) part
11231
// Tables of derivatives of the polynomial base (transpose)
11232
static const double dmats0[3][3] = \
11234
{4.89897948556636, 0, 0},
11237
static const double dmats1[3][3] = \
11239
{2.44948974278318, 0, 0},
11240
{4.24264068711928, 0, 0}};
11242
// Compute reference derivatives
11243
// Declare pointer to array of derivatives on FIAT element
11244
double *derivatives = new double [num_derivatives];
11246
// Declare coefficients
11247
double coeff0_0 = 0;
11248
double coeff0_1 = 0;
11249
double coeff0_2 = 0;
11251
// Declare new coefficients
11252
double new_coeff0_0 = 0;
11253
double new_coeff0_1 = 0;
11254
double new_coeff0_2 = 0;
11256
// Loop possible derivatives
11257
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11259
// Get values from coefficients array
11260
new_coeff0_0 = coefficients0[dof][0];
11261
new_coeff0_1 = coefficients0[dof][1];
11262
new_coeff0_2 = coefficients0[dof][2];
11264
// Loop derivative order
11265
for (unsigned int j = 0; j < n; j++)
11267
// Update old coefficients
11268
coeff0_0 = new_coeff0_0;
11269
coeff0_1 = new_coeff0_1;
11270
coeff0_2 = new_coeff0_2;
11272
if(combinations[deriv_num][j] == 0)
11274
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11275
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11276
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11278
if(combinations[deriv_num][j] == 1)
11280
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11281
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11282
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
11286
// Compute derivatives on reference element as dot product of coefficients and basisvalues
11287
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
11290
// Transform derivatives back to physical element
11291
for (unsigned int row = 0; row < num_derivatives; row++)
11293
for (unsigned int col = 0; col < num_derivatives; col++)
11295
values[row] += transform[row][col]*derivatives[col];
11298
// Delete pointer to array of derivatives on FIAT element
11299
delete [] derivatives;
11301
// Delete pointer to array of combinations of derivatives and transform
11302
for (unsigned int row = 0; row < num_derivatives; row++)
11304
delete [] combinations[row];
11305
delete [] transform[row];
11308
delete [] combinations;
11309
delete [] transform;
11312
/// Evaluate order n derivatives of all basis functions at given point in cell
11313
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
11315
const double* coordinates,
11316
const ufc::cell& c) const
11318
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11321
/// Evaluate linear functional for dof i on the function f
11322
double cahnhilliard2d_1_finite_element_2_0::evaluate_dof(unsigned int i,
11323
const ufc::function& f,
11324
const ufc::cell& c) const
11326
// The reference points, direction and weights:
11327
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
11328
static const double W[3][1] = {{1}, {1}, {1}};
11329
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
11331
const double * const * x = c.coordinates;
11332
double result = 0.0;
11333
// Iterate over the points:
11334
// Evaluate basis functions for affine mapping
11335
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11336
const double w1 = X[i][0][0];
11337
const double w2 = X[i][0][1];
11339
// Compute affine mapping y = F(X)
11341
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11342
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11344
// Evaluate function at physical points
11346
f.evaluate(values, y, c);
11348
// Map function values using appropriate mapping
11349
// Affine map: Do nothing
11351
// Note that we do not map the weights (yet).
11353
// Take directional components
11354
for(int k = 0; k < 1; k++)
11355
result += values[k]*D[i][0][k];
11356
// Multiply by weights
11362
/// Evaluate linear functionals for all dofs on the function f
11363
void cahnhilliard2d_1_finite_element_2_0::evaluate_dofs(double* values,
11364
const ufc::function& f,
11365
const ufc::cell& c) const
11367
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11370
/// Interpolate vertex values from dof values
11371
void cahnhilliard2d_1_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
11372
const double* dof_values,
11373
const ufc::cell& c) const
11375
// Evaluate at vertices and use affine mapping
11376
vertex_values[0] = dof_values[0];
11377
vertex_values[1] = dof_values[1];
11378
vertex_values[2] = dof_values[2];
11381
/// Return the number of sub elements (for a mixed element)
11382
unsigned int cahnhilliard2d_1_finite_element_2_0::num_sub_elements() const
11387
/// Create a new finite element for sub element i (for a mixed element)
11388
ufc::finite_element* cahnhilliard2d_1_finite_element_2_0::create_sub_element(unsigned int i) const
11390
return new cahnhilliard2d_1_finite_element_2_0();
11395
cahnhilliard2d_1_finite_element_2_1::cahnhilliard2d_1_finite_element_2_1() : ufc::finite_element()
11401
cahnhilliard2d_1_finite_element_2_1::~cahnhilliard2d_1_finite_element_2_1()
11406
/// Return a string identifying the finite element
11407
const char* cahnhilliard2d_1_finite_element_2_1::signature() const
11409
return "FiniteElement('Lagrange', 'triangle', 1)";
11412
/// Return the cell shape
11413
ufc::shape cahnhilliard2d_1_finite_element_2_1::cell_shape() const
11415
return ufc::triangle;
11418
/// Return the dimension of the finite element function space
11419
unsigned int cahnhilliard2d_1_finite_element_2_1::space_dimension() const
11424
/// Return the rank of the value space
11425
unsigned int cahnhilliard2d_1_finite_element_2_1::value_rank() const
11430
/// Return the dimension of the value space for axis i
11431
unsigned int cahnhilliard2d_1_finite_element_2_1::value_dimension(unsigned int i) const
11436
/// Evaluate basis function i at given point in cell
11437
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis(unsigned int i,
11439
const double* coordinates,
11440
const ufc::cell& c) const
11442
// Extract vertex coordinates
11443
const double * const * element_coordinates = c.coordinates;
11445
// Compute Jacobian of affine map from reference cell
11446
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11447
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11448
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11449
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11451
// Compute determinant of Jacobian
11452
const double detJ = J_00*J_11 - J_01*J_10;
11454
// Compute inverse of Jacobian
11456
// Get coordinates and map to the reference (UFC) element
11457
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11458
element_coordinates[0][0]*element_coordinates[2][1] +\
11459
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11460
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11461
element_coordinates[1][0]*element_coordinates[0][1] -\
11462
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11464
// Map coordinates to the reference square
11465
if (std::abs(y - 1.0) < 1e-14)
11468
x = 2.0 *x/(1.0 - y) - 1.0;
11474
// Map degree of freedom to element degree of freedom
11475
const unsigned int dof = i;
11477
// Generate scalings
11478
const double scalings_y_0 = 1;
11479
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11481
// Compute psitilde_a
11482
const double psitilde_a_0 = 1;
11483
const double psitilde_a_1 = x;
11485
// Compute psitilde_bs
11486
const double psitilde_bs_0_0 = 1;
11487
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11488
const double psitilde_bs_1_0 = 1;
11490
// Compute basisvalues
11491
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11492
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11493
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11495
// Table(s) of coefficients
11496
static const double coefficients0[3][3] = \
11497
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11498
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11499
{0.471404520791032, 0, 0.333333333333333}};
11501
// Extract relevant coefficients
11502
const double coeff0_0 = coefficients0[dof][0];
11503
const double coeff0_1 = coefficients0[dof][1];
11504
const double coeff0_2 = coefficients0[dof][2];
11506
// Compute value(s)
11507
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11510
/// Evaluate all basis functions at given point in cell
11511
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis_all(double* values,
11512
const double* coordinates,
11513
const ufc::cell& c) const
11515
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11518
/// Evaluate order n derivatives of basis function i at given point in cell
11519
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
11522
const double* coordinates,
11523
const ufc::cell& c) const
11525
// Extract vertex coordinates
11526
const double * const * element_coordinates = c.coordinates;
11528
// Compute Jacobian of affine map from reference cell
11529
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11530
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11531
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11532
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11534
// Compute determinant of Jacobian
11535
const double detJ = J_00*J_11 - J_01*J_10;
11537
// Compute inverse of Jacobian
11539
// Get coordinates and map to the reference (UFC) element
11540
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11541
element_coordinates[0][0]*element_coordinates[2][1] +\
11542
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11543
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11544
element_coordinates[1][0]*element_coordinates[0][1] -\
11545
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11547
// Map coordinates to the reference square
11548
if (std::abs(y - 1.0) < 1e-14)
11551
x = 2.0 *x/(1.0 - y) - 1.0;
11554
// Compute number of derivatives
11555
unsigned int num_derivatives = 1;
11557
for (unsigned int j = 0; j < n; j++)
11558
num_derivatives *= 2;
11561
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11562
unsigned int **combinations = new unsigned int *[num_derivatives];
11564
for (unsigned int j = 0; j < num_derivatives; j++)
11566
combinations[j] = new unsigned int [n];
11567
for (unsigned int k = 0; k < n; k++)
11568
combinations[j][k] = 0;
11571
// Generate combinations of derivatives
11572
for (unsigned int row = 1; row < num_derivatives; row++)
11574
for (unsigned int num = 0; num < row; num++)
11576
for (unsigned int col = n-1; col+1 > 0; col--)
11578
if (combinations[row][col] + 1 > 1)
11579
combinations[row][col] = 0;
11582
combinations[row][col] += 1;
11589
// Compute inverse of Jacobian
11590
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11592
// Declare transformation matrix
11593
// Declare pointer to two dimensional array and initialise
11594
double **transform = new double *[num_derivatives];
11596
for (unsigned int j = 0; j < num_derivatives; j++)
11598
transform[j] = new double [num_derivatives];
11599
for (unsigned int k = 0; k < num_derivatives; k++)
11600
transform[j][k] = 1;
11603
// Construct transformation matrix
11604
for (unsigned int row = 0; row < num_derivatives; row++)
11606
for (unsigned int col = 0; col < num_derivatives; col++)
11608
for (unsigned int k = 0; k < n; k++)
11609
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11614
for (unsigned int j = 0; j < 1*num_derivatives; j++)
11617
// Map degree of freedom to element degree of freedom
11618
const unsigned int dof = i;
11620
// Generate scalings
11621
const double scalings_y_0 = 1;
11622
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11624
// Compute psitilde_a
11625
const double psitilde_a_0 = 1;
11626
const double psitilde_a_1 = x;
11628
// Compute psitilde_bs
11629
const double psitilde_bs_0_0 = 1;
11630
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11631
const double psitilde_bs_1_0 = 1;
11633
// Compute basisvalues
11634
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11635
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11636
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11638
// Table(s) of coefficients
11639
static const double coefficients0[3][3] = \
11640
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11641
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11642
{0.471404520791032, 0, 0.333333333333333}};
11644
// Interesting (new) part
11645
// Tables of derivatives of the polynomial base (transpose)
11646
static const double dmats0[3][3] = \
11648
{4.89897948556636, 0, 0},
11651
static const double dmats1[3][3] = \
11653
{2.44948974278318, 0, 0},
11654
{4.24264068711928, 0, 0}};
11656
// Compute reference derivatives
11657
// Declare pointer to array of derivatives on FIAT element
11658
double *derivatives = new double [num_derivatives];
11660
// Declare coefficients
11661
double coeff0_0 = 0;
11662
double coeff0_1 = 0;
11663
double coeff0_2 = 0;
11665
// Declare new coefficients
11666
double new_coeff0_0 = 0;
11667
double new_coeff0_1 = 0;
11668
double new_coeff0_2 = 0;
11670
// Loop possible derivatives
11671
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11673
// Get values from coefficients array
11674
new_coeff0_0 = coefficients0[dof][0];
11675
new_coeff0_1 = coefficients0[dof][1];
11676
new_coeff0_2 = coefficients0[dof][2];
11678
// Loop derivative order
11679
for (unsigned int j = 0; j < n; j++)
11681
// Update old coefficients
11682
coeff0_0 = new_coeff0_0;
11683
coeff0_1 = new_coeff0_1;
11684
coeff0_2 = new_coeff0_2;
11686
if(combinations[deriv_num][j] == 0)
11688
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11689
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11690
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11692
if(combinations[deriv_num][j] == 1)
11694
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11695
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11696
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
11700
// Compute derivatives on reference element as dot product of coefficients and basisvalues
11701
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
11704
// Transform derivatives back to physical element
11705
for (unsigned int row = 0; row < num_derivatives; row++)
11707
for (unsigned int col = 0; col < num_derivatives; col++)
11709
values[row] += transform[row][col]*derivatives[col];
11712
// Delete pointer to array of derivatives on FIAT element
11713
delete [] derivatives;
11715
// Delete pointer to array of combinations of derivatives and transform
11716
for (unsigned int row = 0; row < num_derivatives; row++)
11718
delete [] combinations[row];
11719
delete [] transform[row];
11722
delete [] combinations;
11723
delete [] transform;
11726
/// Evaluate order n derivatives of all basis functions at given point in cell
11727
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
11729
const double* coordinates,
11730
const ufc::cell& c) const
11732
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11735
/// Evaluate linear functional for dof i on the function f
11736
double cahnhilliard2d_1_finite_element_2_1::evaluate_dof(unsigned int i,
11737
const ufc::function& f,
11738
const ufc::cell& c) const
11740
// The reference points, direction and weights:
11741
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
11742
static const double W[3][1] = {{1}, {1}, {1}};
11743
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
11745
const double * const * x = c.coordinates;
11746
double result = 0.0;
11747
// Iterate over the points:
11748
// Evaluate basis functions for affine mapping
11749
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11750
const double w1 = X[i][0][0];
11751
const double w2 = X[i][0][1];
11753
// Compute affine mapping y = F(X)
11755
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11756
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11758
// Evaluate function at physical points
11760
f.evaluate(values, y, c);
11762
// Map function values using appropriate mapping
11763
// Affine map: Do nothing
11765
// Note that we do not map the weights (yet).
11767
// Take directional components
11768
for(int k = 0; k < 1; k++)
11769
result += values[k]*D[i][0][k];
11770
// Multiply by weights
11776
/// Evaluate linear functionals for all dofs on the function f
11777
void cahnhilliard2d_1_finite_element_2_1::evaluate_dofs(double* values,
11778
const ufc::function& f,
11779
const ufc::cell& c) const
11781
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11784
/// Interpolate vertex values from dof values
11785
void cahnhilliard2d_1_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
11786
const double* dof_values,
11787
const ufc::cell& c) const
11789
// Evaluate at vertices and use affine mapping
11790
vertex_values[0] = dof_values[0];
11791
vertex_values[1] = dof_values[1];
11792
vertex_values[2] = dof_values[2];
11795
/// Return the number of sub elements (for a mixed element)
11796
unsigned int cahnhilliard2d_1_finite_element_2_1::num_sub_elements() const
11801
/// Create a new finite element for sub element i (for a mixed element)
11802
ufc::finite_element* cahnhilliard2d_1_finite_element_2_1::create_sub_element(unsigned int i) const
11804
return new cahnhilliard2d_1_finite_element_2_1();
11809
cahnhilliard2d_1_finite_element_2::cahnhilliard2d_1_finite_element_2() : ufc::finite_element()
11815
cahnhilliard2d_1_finite_element_2::~cahnhilliard2d_1_finite_element_2()
11820
/// Return a string identifying the finite element
11821
const char* cahnhilliard2d_1_finite_element_2::signature() const
11823
return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
11826
/// Return the cell shape
11827
ufc::shape cahnhilliard2d_1_finite_element_2::cell_shape() const
11829
return ufc::triangle;
11832
/// Return the dimension of the finite element function space
11833
unsigned int cahnhilliard2d_1_finite_element_2::space_dimension() const
11838
/// Return the rank of the value space
11839
unsigned int cahnhilliard2d_1_finite_element_2::value_rank() const
11844
/// Return the dimension of the value space for axis i
11845
unsigned int cahnhilliard2d_1_finite_element_2::value_dimension(unsigned int i) const
11850
/// Evaluate basis function i at given point in cell
11851
void cahnhilliard2d_1_finite_element_2::evaluate_basis(unsigned int i,
11853
const double* coordinates,
11854
const ufc::cell& c) const
11856
// Extract vertex coordinates
11857
const double * const * element_coordinates = c.coordinates;
11859
// Compute Jacobian of affine map from reference cell
11860
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11861
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11862
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11863
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11865
// Compute determinant of Jacobian
11866
const double detJ = J_00*J_11 - J_01*J_10;
11868
// Compute inverse of Jacobian
11870
// Get coordinates and map to the reference (UFC) element
11871
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11872
element_coordinates[0][0]*element_coordinates[2][1] +\
11873
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11874
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11875
element_coordinates[1][0]*element_coordinates[0][1] -\
11876
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11878
// Map coordinates to the reference square
11879
if (std::abs(y - 1.0) < 1e-14)
11882
x = 2.0 *x/(1.0 - y) - 1.0;
11889
if (0 <= i && i <= 2)
11891
// Map degree of freedom to element degree of freedom
11892
const unsigned int dof = i;
11894
// Generate scalings
11895
const double scalings_y_0 = 1;
11896
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11898
// Compute psitilde_a
11899
const double psitilde_a_0 = 1;
11900
const double psitilde_a_1 = x;
11902
// Compute psitilde_bs
11903
const double psitilde_bs_0_0 = 1;
11904
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11905
const double psitilde_bs_1_0 = 1;
11907
// Compute basisvalues
11908
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11909
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11910
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11912
// Table(s) of coefficients
11913
static const double coefficients0[3][3] = \
11914
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11915
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11916
{0.471404520791032, 0, 0.333333333333333}};
11918
// Extract relevant coefficients
11919
const double coeff0_0 = coefficients0[dof][0];
11920
const double coeff0_1 = coefficients0[dof][1];
11921
const double coeff0_2 = coefficients0[dof][2];
11923
// Compute value(s)
11924
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11927
if (3 <= i && i <= 5)
11929
// Map degree of freedom to element degree of freedom
11930
const unsigned int dof = i - 3;
11932
// Generate scalings
11933
const double scalings_y_0 = 1;
11934
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11936
// Compute psitilde_a
11937
const double psitilde_a_0 = 1;
11938
const double psitilde_a_1 = x;
11940
// Compute psitilde_bs
11941
const double psitilde_bs_0_0 = 1;
11942
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11943
const double psitilde_bs_1_0 = 1;
11945
// Compute basisvalues
11946
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11947
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11948
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11950
// Table(s) of coefficients
11951
static const double coefficients0[3][3] = \
11952
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
11953
{0.471404520791032, 0.288675134594813, -0.166666666666667},
11954
{0.471404520791032, 0, 0.333333333333333}};
11956
// Extract relevant coefficients
11957
const double coeff0_0 = coefficients0[dof][0];
11958
const double coeff0_1 = coefficients0[dof][1];
11959
const double coeff0_2 = coefficients0[dof][2];
11961
// Compute value(s)
11962
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11967
/// Evaluate all basis functions at given point in cell
11968
void cahnhilliard2d_1_finite_element_2::evaluate_basis_all(double* values,
11969
const double* coordinates,
11970
const ufc::cell& c) const
11972
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11975
/// Evaluate order n derivatives of basis function i at given point in cell
11976
void cahnhilliard2d_1_finite_element_2::evaluate_basis_derivatives(unsigned int i,
11979
const double* coordinates,
11980
const ufc::cell& c) const
11982
// Extract vertex coordinates
11983
const double * const * element_coordinates = c.coordinates;
11985
// Compute Jacobian of affine map from reference cell
11986
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11987
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11988
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11989
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11991
// Compute determinant of Jacobian
11992
const double detJ = J_00*J_11 - J_01*J_10;
11994
// Compute inverse of Jacobian
11996
// Get coordinates and map to the reference (UFC) element
11997
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11998
element_coordinates[0][0]*element_coordinates[2][1] +\
11999
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12000
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12001
element_coordinates[1][0]*element_coordinates[0][1] -\
12002
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12004
// Map coordinates to the reference square
12005
if (std::abs(y - 1.0) < 1e-14)
12008
x = 2.0 *x/(1.0 - y) - 1.0;
12011
// Compute number of derivatives
12012
unsigned int num_derivatives = 1;
12014
for (unsigned int j = 0; j < n; j++)
12015
num_derivatives *= 2;
12018
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12019
unsigned int **combinations = new unsigned int *[num_derivatives];
12021
for (unsigned int j = 0; j < num_derivatives; j++)
12023
combinations[j] = new unsigned int [n];
12024
for (unsigned int k = 0; k < n; k++)
12025
combinations[j][k] = 0;
12028
// Generate combinations of derivatives
12029
for (unsigned int row = 1; row < num_derivatives; row++)
12031
for (unsigned int num = 0; num < row; num++)
12033
for (unsigned int col = n-1; col+1 > 0; col--)
12035
if (combinations[row][col] + 1 > 1)
12036
combinations[row][col] = 0;
12039
combinations[row][col] += 1;
12046
// Compute inverse of Jacobian
12047
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12049
// Declare transformation matrix
12050
// Declare pointer to two dimensional array and initialise
12051
double **transform = new double *[num_derivatives];
12053
for (unsigned int j = 0; j < num_derivatives; j++)
12055
transform[j] = new double [num_derivatives];
12056
for (unsigned int k = 0; k < num_derivatives; k++)
12057
transform[j][k] = 1;
12060
// Construct transformation matrix
12061
for (unsigned int row = 0; row < num_derivatives; row++)
12063
for (unsigned int col = 0; col < num_derivatives; col++)
12065
for (unsigned int k = 0; k < n; k++)
12066
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12071
for (unsigned int j = 0; j < 2*num_derivatives; j++)
12074
if (0 <= i && i <= 2)
12076
// Map degree of freedom to element degree of freedom
12077
const unsigned int dof = i;
12079
// Generate scalings
12080
const double scalings_y_0 = 1;
12081
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12083
// Compute psitilde_a
12084
const double psitilde_a_0 = 1;
12085
const double psitilde_a_1 = x;
12087
// Compute psitilde_bs
12088
const double psitilde_bs_0_0 = 1;
12089
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12090
const double psitilde_bs_1_0 = 1;
12092
// Compute basisvalues
12093
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12094
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12095
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12097
// Table(s) of coefficients
12098
static const double coefficients0[3][3] = \
12099
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
12100
{0.471404520791032, 0.288675134594813, -0.166666666666667},
12101
{0.471404520791032, 0, 0.333333333333333}};
12103
// Interesting (new) part
12104
// Tables of derivatives of the polynomial base (transpose)
12105
static const double dmats0[3][3] = \
12107
{4.89897948556636, 0, 0},
12110
static const double dmats1[3][3] = \
12112
{2.44948974278318, 0, 0},
12113
{4.24264068711928, 0, 0}};
12115
// Compute reference derivatives
12116
// Declare pointer to array of derivatives on FIAT element
12117
double *derivatives = new double [num_derivatives];
12119
// Declare coefficients
12120
double coeff0_0 = 0;
12121
double coeff0_1 = 0;
12122
double coeff0_2 = 0;
12124
// Declare new coefficients
12125
double new_coeff0_0 = 0;
12126
double new_coeff0_1 = 0;
12127
double new_coeff0_2 = 0;
12129
// Loop possible derivatives
12130
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12132
// Get values from coefficients array
12133
new_coeff0_0 = coefficients0[dof][0];
12134
new_coeff0_1 = coefficients0[dof][1];
12135
new_coeff0_2 = coefficients0[dof][2];
12137
// Loop derivative order
12138
for (unsigned int j = 0; j < n; j++)
12140
// Update old coefficients
12141
coeff0_0 = new_coeff0_0;
12142
coeff0_1 = new_coeff0_1;
12143
coeff0_2 = new_coeff0_2;
12145
if(combinations[deriv_num][j] == 0)
12147
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
12148
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
12149
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
12151
if(combinations[deriv_num][j] == 1)
12153
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
12154
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
12155
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
12159
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12160
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
12163
// Transform derivatives back to physical element
12164
for (unsigned int row = 0; row < num_derivatives; row++)
12166
for (unsigned int col = 0; col < num_derivatives; col++)
12168
values[row] += transform[row][col]*derivatives[col];
12171
// Delete pointer to array of derivatives on FIAT element
12172
delete [] derivatives;
12174
// Delete pointer to array of combinations of derivatives and transform
12175
for (unsigned int row = 0; row < num_derivatives; row++)
12177
delete [] combinations[row];
12178
delete [] transform[row];
12181
delete [] combinations;
12182
delete [] transform;
12185
if (3 <= i && i <= 5)
12187
// Map degree of freedom to element degree of freedom
12188
const unsigned int dof = i - 3;
12190
// Generate scalings
12191
const double scalings_y_0 = 1;
12192
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12194
// Compute psitilde_a
12195
const double psitilde_a_0 = 1;
12196
const double psitilde_a_1 = x;
12198
// Compute psitilde_bs
12199
const double psitilde_bs_0_0 = 1;
12200
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12201
const double psitilde_bs_1_0 = 1;
12203
// Compute basisvalues
12204
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12205
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12206
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12208
// Table(s) of coefficients
12209
static const double coefficients0[3][3] = \
12210
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
12211
{0.471404520791032, 0.288675134594813, -0.166666666666667},
12212
{0.471404520791032, 0, 0.333333333333333}};
12214
// Interesting (new) part
12215
// Tables of derivatives of the polynomial base (transpose)
12216
static const double dmats0[3][3] = \
12218
{4.89897948556636, 0, 0},
12221
static const double dmats1[3][3] = \
12223
{2.44948974278318, 0, 0},
12224
{4.24264068711928, 0, 0}};
12226
// Compute reference derivatives
12227
// Declare pointer to array of derivatives on FIAT element
12228
double *derivatives = new double [num_derivatives];
12230
// Declare coefficients
12231
double coeff0_0 = 0;
12232
double coeff0_1 = 0;
12233
double coeff0_2 = 0;
12235
// Declare new coefficients
12236
double new_coeff0_0 = 0;
12237
double new_coeff0_1 = 0;
12238
double new_coeff0_2 = 0;
12240
// Loop possible derivatives
12241
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12243
// Get values from coefficients array
12244
new_coeff0_0 = coefficients0[dof][0];
12245
new_coeff0_1 = coefficients0[dof][1];
12246
new_coeff0_2 = coefficients0[dof][2];
12248
// Loop derivative order
12249
for (unsigned int j = 0; j < n; j++)
12251
// Update old coefficients
12252
coeff0_0 = new_coeff0_0;
12253
coeff0_1 = new_coeff0_1;
12254
coeff0_2 = new_coeff0_2;
12256
if(combinations[deriv_num][j] == 0)
12258
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
12259
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
12260
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
12262
if(combinations[deriv_num][j] == 1)
12264
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
12265
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
12266
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
12270
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12271
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
12274
// Transform derivatives back to physical element
12275
for (unsigned int row = 0; row < num_derivatives; row++)
12277
for (unsigned int col = 0; col < num_derivatives; col++)
12279
values[num_derivatives + row] += transform[row][col]*derivatives[col];
12282
// Delete pointer to array of derivatives on FIAT element
12283
delete [] derivatives;
12285
// Delete pointer to array of combinations of derivatives and transform
12286
for (unsigned int row = 0; row < num_derivatives; row++)
12288
delete [] combinations[row];
12289
delete [] transform[row];
12292
delete [] combinations;
12293
delete [] transform;
12298
/// Evaluate order n derivatives of all basis functions at given point in cell
12299
void cahnhilliard2d_1_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
12301
const double* coordinates,
12302
const ufc::cell& c) const
12304
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12307
/// Evaluate linear functional for dof i on the function f
12308
double cahnhilliard2d_1_finite_element_2::evaluate_dof(unsigned int i,
12309
const ufc::function& f,
12310
const ufc::cell& c) const
12312
// The reference points, direction and weights:
12313
static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
12314
static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
12315
static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
12317
const double * const * x = c.coordinates;
12318
double result = 0.0;
12319
// Iterate over the points:
12320
// Evaluate basis functions for affine mapping
12321
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12322
const double w1 = X[i][0][0];
12323
const double w2 = X[i][0][1];
12325
// Compute affine mapping y = F(X)
12327
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12328
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12330
// Evaluate function at physical points
12332
f.evaluate(values, y, c);
12334
// Map function values using appropriate mapping
12335
// Affine map: Do nothing
12337
// Note that we do not map the weights (yet).
12339
// Take directional components
12340
for(int k = 0; k < 2; k++)
12341
result += values[k]*D[i][0][k];
12342
// Multiply by weights
12348
/// Evaluate linear functionals for all dofs on the function f
12349
void cahnhilliard2d_1_finite_element_2::evaluate_dofs(double* values,
12350
const ufc::function& f,
12351
const ufc::cell& c) const
12353
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12356
/// Interpolate vertex values from dof values
12357
void cahnhilliard2d_1_finite_element_2::interpolate_vertex_values(double* vertex_values,
12358
const double* dof_values,
12359
const ufc::cell& c) const
12361
// Evaluate at vertices and use affine mapping
12362
vertex_values[0] = dof_values[0];
12363
vertex_values[2] = dof_values[1];
12364
vertex_values[4] = dof_values[2];
12365
// Evaluate at vertices and use affine mapping
12366
vertex_values[1] = dof_values[3];
12367
vertex_values[3] = dof_values[4];
12368
vertex_values[5] = dof_values[5];
12371
/// Return the number of sub elements (for a mixed element)
12372
unsigned int cahnhilliard2d_1_finite_element_2::num_sub_elements() const
12377
/// Create a new finite element for sub element i (for a mixed element)
12378
ufc::finite_element* cahnhilliard2d_1_finite_element_2::create_sub_element(unsigned int i) const
12383
return new cahnhilliard2d_1_finite_element_2_0();
12386
return new cahnhilliard2d_1_finite_element_2_1();
12394
cahnhilliard2d_1_finite_element_3::cahnhilliard2d_1_finite_element_3() : ufc::finite_element()
12400
cahnhilliard2d_1_finite_element_3::~cahnhilliard2d_1_finite_element_3()
12405
/// Return a string identifying the finite element
12406
const char* cahnhilliard2d_1_finite_element_3::signature() const
12408
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
12411
/// Return the cell shape
12412
ufc::shape cahnhilliard2d_1_finite_element_3::cell_shape() const
12414
return ufc::triangle;
12417
/// Return the dimension of the finite element function space
12418
unsigned int cahnhilliard2d_1_finite_element_3::space_dimension() const
12423
/// Return the rank of the value space
12424
unsigned int cahnhilliard2d_1_finite_element_3::value_rank() const
12429
/// Return the dimension of the value space for axis i
12430
unsigned int cahnhilliard2d_1_finite_element_3::value_dimension(unsigned int i) const
12435
/// Evaluate basis function i at given point in cell
12436
void cahnhilliard2d_1_finite_element_3::evaluate_basis(unsigned int i,
12438
const double* coordinates,
12439
const ufc::cell& c) const
12441
// Extract vertex coordinates
12442
const double * const * element_coordinates = c.coordinates;
12444
// Compute Jacobian of affine map from reference cell
12445
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12446
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12447
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12448
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12450
// Compute determinant of Jacobian
12451
const double detJ = J_00*J_11 - J_01*J_10;
12453
// Compute inverse of Jacobian
12455
// Get coordinates and map to the reference (UFC) element
12456
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12457
element_coordinates[0][0]*element_coordinates[2][1] +\
12458
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12459
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12460
element_coordinates[1][0]*element_coordinates[0][1] -\
12461
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12463
// Map coordinates to the reference square
12464
if (std::abs(y - 1.0) < 1e-14)
12467
x = 2.0 *x/(1.0 - y) - 1.0;
12473
// Map degree of freedom to element degree of freedom
12474
const unsigned int dof = i;
12476
// Generate scalings
12477
const double scalings_y_0 = 1;
12479
// Compute psitilde_a
12480
const double psitilde_a_0 = 1;
12482
// Compute psitilde_bs
12483
const double psitilde_bs_0_0 = 1;
12485
// Compute basisvalues
12486
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12488
// Table(s) of coefficients
12489
static const double coefficients0[1][1] = \
12490
{{1.41421356237309}};
12492
// Extract relevant coefficients
12493
const double coeff0_0 = coefficients0[dof][0];
12495
// Compute value(s)
12496
*values = coeff0_0*basisvalue0;
12499
/// Evaluate all basis functions at given point in cell
12500
void cahnhilliard2d_1_finite_element_3::evaluate_basis_all(double* values,
12501
const double* coordinates,
12502
const ufc::cell& c) const
12504
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12507
/// Evaluate order n derivatives of basis function i at given point in cell
12508
void cahnhilliard2d_1_finite_element_3::evaluate_basis_derivatives(unsigned int i,
12511
const double* coordinates,
12512
const ufc::cell& c) const
12514
// Extract vertex coordinates
12515
const double * const * element_coordinates = c.coordinates;
12517
// Compute Jacobian of affine map from reference cell
12518
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12519
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12520
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12521
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12523
// Compute determinant of Jacobian
12524
const double detJ = J_00*J_11 - J_01*J_10;
12526
// Compute inverse of Jacobian
12528
// Get coordinates and map to the reference (UFC) element
12529
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12530
element_coordinates[0][0]*element_coordinates[2][1] +\
12531
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12532
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12533
element_coordinates[1][0]*element_coordinates[0][1] -\
12534
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12536
// Map coordinates to the reference square
12537
if (std::abs(y - 1.0) < 1e-14)
12540
x = 2.0 *x/(1.0 - y) - 1.0;
12543
// Compute number of derivatives
12544
unsigned int num_derivatives = 1;
12546
for (unsigned int j = 0; j < n; j++)
12547
num_derivatives *= 2;
12550
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12551
unsigned int **combinations = new unsigned int *[num_derivatives];
12553
for (unsigned int j = 0; j < num_derivatives; j++)
12555
combinations[j] = new unsigned int [n];
12556
for (unsigned int k = 0; k < n; k++)
12557
combinations[j][k] = 0;
12560
// Generate combinations of derivatives
12561
for (unsigned int row = 1; row < num_derivatives; row++)
12563
for (unsigned int num = 0; num < row; num++)
12565
for (unsigned int col = n-1; col+1 > 0; col--)
12567
if (combinations[row][col] + 1 > 1)
12568
combinations[row][col] = 0;
12571
combinations[row][col] += 1;
12578
// Compute inverse of Jacobian
12579
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12581
// Declare transformation matrix
12582
// Declare pointer to two dimensional array and initialise
12583
double **transform = new double *[num_derivatives];
12585
for (unsigned int j = 0; j < num_derivatives; j++)
12587
transform[j] = new double [num_derivatives];
12588
for (unsigned int k = 0; k < num_derivatives; k++)
12589
transform[j][k] = 1;
12592
// Construct transformation matrix
12593
for (unsigned int row = 0; row < num_derivatives; row++)
12595
for (unsigned int col = 0; col < num_derivatives; col++)
12597
for (unsigned int k = 0; k < n; k++)
12598
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12603
for (unsigned int j = 0; j < 1*num_derivatives; j++)
12606
// Map degree of freedom to element degree of freedom
12607
const unsigned int dof = i;
12609
// Generate scalings
12610
const double scalings_y_0 = 1;
12612
// Compute psitilde_a
12613
const double psitilde_a_0 = 1;
12615
// Compute psitilde_bs
12616
const double psitilde_bs_0_0 = 1;
12618
// Compute basisvalues
12619
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12621
// Table(s) of coefficients
12622
static const double coefficients0[1][1] = \
12623
{{1.41421356237309}};
12625
// Interesting (new) part
12626
// Tables of derivatives of the polynomial base (transpose)
12627
static const double dmats0[1][1] = \
12630
static const double dmats1[1][1] = \
12633
// Compute reference derivatives
12634
// Declare pointer to array of derivatives on FIAT element
12635
double *derivatives = new double [num_derivatives];
12637
// Declare coefficients
12638
double coeff0_0 = 0;
12640
// Declare new coefficients
12641
double new_coeff0_0 = 0;
12643
// Loop possible derivatives
12644
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12646
// Get values from coefficients array
12647
new_coeff0_0 = coefficients0[dof][0];
12649
// Loop derivative order
12650
for (unsigned int j = 0; j < n; j++)
12652
// Update old coefficients
12653
coeff0_0 = new_coeff0_0;
12655
if(combinations[deriv_num][j] == 0)
12657
new_coeff0_0 = coeff0_0*dmats0[0][0];
12659
if(combinations[deriv_num][j] == 1)
12661
new_coeff0_0 = coeff0_0*dmats1[0][0];
12665
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12666
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
12669
// Transform derivatives back to physical element
12670
for (unsigned int row = 0; row < num_derivatives; row++)
12672
for (unsigned int col = 0; col < num_derivatives; col++)
12674
values[row] += transform[row][col]*derivatives[col];
12677
// Delete pointer to array of derivatives on FIAT element
12678
delete [] derivatives;
12680
// Delete pointer to array of combinations of derivatives and transform
12681
for (unsigned int row = 0; row < num_derivatives; row++)
12683
delete [] combinations[row];
12684
delete [] transform[row];
12687
delete [] combinations;
12688
delete [] transform;
12691
/// Evaluate order n derivatives of all basis functions at given point in cell
12692
void cahnhilliard2d_1_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
12694
const double* coordinates,
12695
const ufc::cell& c) const
12697
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12700
/// Evaluate linear functional for dof i on the function f
12701
double cahnhilliard2d_1_finite_element_3::evaluate_dof(unsigned int i,
12702
const ufc::function& f,
12703
const ufc::cell& c) const
12705
// The reference points, direction and weights:
12706
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
12707
static const double W[1][1] = {{1}};
12708
static const double D[1][1][1] = {{{1}}};
12710
const double * const * x = c.coordinates;
12711
double result = 0.0;
12712
// Iterate over the points:
12713
// Evaluate basis functions for affine mapping
12714
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12715
const double w1 = X[i][0][0];
12716
const double w2 = X[i][0][1];
12718
// Compute affine mapping y = F(X)
12720
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12721
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12723
// Evaluate function at physical points
12725
f.evaluate(values, y, c);
12727
// Map function values using appropriate mapping
12728
// Affine map: Do nothing
12730
// Note that we do not map the weights (yet).
12732
// Take directional components
12733
for(int k = 0; k < 1; k++)
12734
result += values[k]*D[i][0][k];
12735
// Multiply by weights
12741
/// Evaluate linear functionals for all dofs on the function f
12742
void cahnhilliard2d_1_finite_element_3::evaluate_dofs(double* values,
12743
const ufc::function& f,
12744
const ufc::cell& c) const
12746
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12749
/// Interpolate vertex values from dof values
12750
void cahnhilliard2d_1_finite_element_3::interpolate_vertex_values(double* vertex_values,
12751
const double* dof_values,
12752
const ufc::cell& c) const
12754
// Evaluate at vertices and use affine mapping
12755
vertex_values[0] = dof_values[0];
12756
vertex_values[1] = dof_values[0];
12757
vertex_values[2] = dof_values[0];
12760
/// Return the number of sub elements (for a mixed element)
12761
unsigned int cahnhilliard2d_1_finite_element_3::num_sub_elements() const
12766
/// Create a new finite element for sub element i (for a mixed element)
12767
ufc::finite_element* cahnhilliard2d_1_finite_element_3::create_sub_element(unsigned int i) const
12769
return new cahnhilliard2d_1_finite_element_3();
12774
cahnhilliard2d_1_finite_element_4::cahnhilliard2d_1_finite_element_4() : ufc::finite_element()
12780
cahnhilliard2d_1_finite_element_4::~cahnhilliard2d_1_finite_element_4()
12785
/// Return a string identifying the finite element
12786
const char* cahnhilliard2d_1_finite_element_4::signature() const
12788
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
12791
/// Return the cell shape
12792
ufc::shape cahnhilliard2d_1_finite_element_4::cell_shape() const
12794
return ufc::triangle;
12797
/// Return the dimension of the finite element function space
12798
unsigned int cahnhilliard2d_1_finite_element_4::space_dimension() const
12803
/// Return the rank of the value space
12804
unsigned int cahnhilliard2d_1_finite_element_4::value_rank() const
12809
/// Return the dimension of the value space for axis i
12810
unsigned int cahnhilliard2d_1_finite_element_4::value_dimension(unsigned int i) const
12815
/// Evaluate basis function i at given point in cell
12816
void cahnhilliard2d_1_finite_element_4::evaluate_basis(unsigned int i,
12818
const double* coordinates,
12819
const ufc::cell& c) const
12821
// Extract vertex coordinates
12822
const double * const * element_coordinates = c.coordinates;
12824
// Compute Jacobian of affine map from reference cell
12825
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12826
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12827
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12828
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12830
// Compute determinant of Jacobian
12831
const double detJ = J_00*J_11 - J_01*J_10;
12833
// Compute inverse of Jacobian
12835
// Get coordinates and map to the reference (UFC) element
12836
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12837
element_coordinates[0][0]*element_coordinates[2][1] +\
12838
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12839
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12840
element_coordinates[1][0]*element_coordinates[0][1] -\
12841
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12843
// Map coordinates to the reference square
12844
if (std::abs(y - 1.0) < 1e-14)
12847
x = 2.0 *x/(1.0 - y) - 1.0;
12853
// Map degree of freedom to element degree of freedom
12854
const unsigned int dof = i;
12856
// Generate scalings
12857
const double scalings_y_0 = 1;
12859
// Compute psitilde_a
12860
const double psitilde_a_0 = 1;
12862
// Compute psitilde_bs
12863
const double psitilde_bs_0_0 = 1;
12865
// Compute basisvalues
12866
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12868
// Table(s) of coefficients
12869
static const double coefficients0[1][1] = \
12870
{{1.41421356237309}};
12872
// Extract relevant coefficients
12873
const double coeff0_0 = coefficients0[dof][0];
12875
// Compute value(s)
12876
*values = coeff0_0*basisvalue0;
12879
/// Evaluate all basis functions at given point in cell
12880
void cahnhilliard2d_1_finite_element_4::evaluate_basis_all(double* values,
12881
const double* coordinates,
12882
const ufc::cell& c) const
12884
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12887
/// Evaluate order n derivatives of basis function i at given point in cell
12888
void cahnhilliard2d_1_finite_element_4::evaluate_basis_derivatives(unsigned int i,
12891
const double* coordinates,
12892
const ufc::cell& c) const
12894
// Extract vertex coordinates
12895
const double * const * element_coordinates = c.coordinates;
12897
// Compute Jacobian of affine map from reference cell
12898
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12899
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12900
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12901
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12903
// Compute determinant of Jacobian
12904
const double detJ = J_00*J_11 - J_01*J_10;
12906
// Compute inverse of Jacobian
12908
// Get coordinates and map to the reference (UFC) element
12909
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12910
element_coordinates[0][0]*element_coordinates[2][1] +\
12911
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12912
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12913
element_coordinates[1][0]*element_coordinates[0][1] -\
12914
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12916
// Map coordinates to the reference square
12917
if (std::abs(y - 1.0) < 1e-14)
12920
x = 2.0 *x/(1.0 - y) - 1.0;
12923
// Compute number of derivatives
12924
unsigned int num_derivatives = 1;
12926
for (unsigned int j = 0; j < n; j++)
12927
num_derivatives *= 2;
12930
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12931
unsigned int **combinations = new unsigned int *[num_derivatives];
12933
for (unsigned int j = 0; j < num_derivatives; j++)
12935
combinations[j] = new unsigned int [n];
12936
for (unsigned int k = 0; k < n; k++)
12937
combinations[j][k] = 0;
12940
// Generate combinations of derivatives
12941
for (unsigned int row = 1; row < num_derivatives; row++)
12943
for (unsigned int num = 0; num < row; num++)
12945
for (unsigned int col = n-1; col+1 > 0; col--)
12947
if (combinations[row][col] + 1 > 1)
12948
combinations[row][col] = 0;
12951
combinations[row][col] += 1;
12958
// Compute inverse of Jacobian
12959
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12961
// Declare transformation matrix
12962
// Declare pointer to two dimensional array and initialise
12963
double **transform = new double *[num_derivatives];
12965
for (unsigned int j = 0; j < num_derivatives; j++)
12967
transform[j] = new double [num_derivatives];
12968
for (unsigned int k = 0; k < num_derivatives; k++)
12969
transform[j][k] = 1;
12972
// Construct transformation matrix
12973
for (unsigned int row = 0; row < num_derivatives; row++)
12975
for (unsigned int col = 0; col < num_derivatives; col++)
12977
for (unsigned int k = 0; k < n; k++)
12978
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12983
for (unsigned int j = 0; j < 1*num_derivatives; j++)
12986
// Map degree of freedom to element degree of freedom
12987
const unsigned int dof = i;
12989
// Generate scalings
12990
const double scalings_y_0 = 1;
12992
// Compute psitilde_a
12993
const double psitilde_a_0 = 1;
12995
// Compute psitilde_bs
12996
const double psitilde_bs_0_0 = 1;
12998
// Compute basisvalues
12999
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13001
// Table(s) of coefficients
13002
static const double coefficients0[1][1] = \
13003
{{1.41421356237309}};
13005
// Interesting (new) part
13006
// Tables of derivatives of the polynomial base (transpose)
13007
static const double dmats0[1][1] = \
13010
static const double dmats1[1][1] = \
13013
// Compute reference derivatives
13014
// Declare pointer to array of derivatives on FIAT element
13015
double *derivatives = new double [num_derivatives];
13017
// Declare coefficients
13018
double coeff0_0 = 0;
13020
// Declare new coefficients
13021
double new_coeff0_0 = 0;
13023
// Loop possible derivatives
13024
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13026
// Get values from coefficients array
13027
new_coeff0_0 = coefficients0[dof][0];
13029
// Loop derivative order
13030
for (unsigned int j = 0; j < n; j++)
13032
// Update old coefficients
13033
coeff0_0 = new_coeff0_0;
13035
if(combinations[deriv_num][j] == 0)
13037
new_coeff0_0 = coeff0_0*dmats0[0][0];
13039
if(combinations[deriv_num][j] == 1)
13041
new_coeff0_0 = coeff0_0*dmats1[0][0];
13045
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13046
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
13049
// Transform derivatives back to physical element
13050
for (unsigned int row = 0; row < num_derivatives; row++)
13052
for (unsigned int col = 0; col < num_derivatives; col++)
13054
values[row] += transform[row][col]*derivatives[col];
13057
// Delete pointer to array of derivatives on FIAT element
13058
delete [] derivatives;
13060
// Delete pointer to array of combinations of derivatives and transform
13061
for (unsigned int row = 0; row < num_derivatives; row++)
13063
delete [] combinations[row];
13064
delete [] transform[row];
13067
delete [] combinations;
13068
delete [] transform;
13071
/// Evaluate order n derivatives of all basis functions at given point in cell
13072
void cahnhilliard2d_1_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
13074
const double* coordinates,
13075
const ufc::cell& c) const
13077
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13080
/// Evaluate linear functional for dof i on the function f
13081
double cahnhilliard2d_1_finite_element_4::evaluate_dof(unsigned int i,
13082
const ufc::function& f,
13083
const ufc::cell& c) const
13085
// The reference points, direction and weights:
13086
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
13087
static const double W[1][1] = {{1}};
13088
static const double D[1][1][1] = {{{1}}};
13090
const double * const * x = c.coordinates;
13091
double result = 0.0;
13092
// Iterate over the points:
13093
// Evaluate basis functions for affine mapping
13094
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
13095
const double w1 = X[i][0][0];
13096
const double w2 = X[i][0][1];
13098
// Compute affine mapping y = F(X)
13100
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
13101
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
13103
// Evaluate function at physical points
13105
f.evaluate(values, y, c);
13107
// Map function values using appropriate mapping
13108
// Affine map: Do nothing
13110
// Note that we do not map the weights (yet).
13112
// Take directional components
13113
for(int k = 0; k < 1; k++)
13114
result += values[k]*D[i][0][k];
13115
// Multiply by weights
13121
/// Evaluate linear functionals for all dofs on the function f
13122
void cahnhilliard2d_1_finite_element_4::evaluate_dofs(double* values,
13123
const ufc::function& f,
13124
const ufc::cell& c) const
13126
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13129
/// Interpolate vertex values from dof values
13130
void cahnhilliard2d_1_finite_element_4::interpolate_vertex_values(double* vertex_values,
13131
const double* dof_values,
13132
const ufc::cell& c) const
13134
// Evaluate at vertices and use affine mapping
13135
vertex_values[0] = dof_values[0];
13136
vertex_values[1] = dof_values[0];
13137
vertex_values[2] = dof_values[0];
13140
/// Return the number of sub elements (for a mixed element)
13141
unsigned int cahnhilliard2d_1_finite_element_4::num_sub_elements() const
13146
/// Create a new finite element for sub element i (for a mixed element)
13147
ufc::finite_element* cahnhilliard2d_1_finite_element_4::create_sub_element(unsigned int i) const
13149
return new cahnhilliard2d_1_finite_element_4();
13154
cahnhilliard2d_1_finite_element_5::cahnhilliard2d_1_finite_element_5() : ufc::finite_element()
13160
cahnhilliard2d_1_finite_element_5::~cahnhilliard2d_1_finite_element_5()
13165
/// Return a string identifying the finite element
13166
const char* cahnhilliard2d_1_finite_element_5::signature() const
13168
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
13171
/// Return the cell shape
13172
ufc::shape cahnhilliard2d_1_finite_element_5::cell_shape() const
13174
return ufc::triangle;
13177
/// Return the dimension of the finite element function space
13178
unsigned int cahnhilliard2d_1_finite_element_5::space_dimension() const
13183
/// Return the rank of the value space
13184
unsigned int cahnhilliard2d_1_finite_element_5::value_rank() const
13189
/// Return the dimension of the value space for axis i
13190
unsigned int cahnhilliard2d_1_finite_element_5::value_dimension(unsigned int i) const
13195
/// Evaluate basis function i at given point in cell
13196
void cahnhilliard2d_1_finite_element_5::evaluate_basis(unsigned int i,
13198
const double* coordinates,
13199
const ufc::cell& c) const
13201
// Extract vertex coordinates
13202
const double * const * element_coordinates = c.coordinates;
13204
// Compute Jacobian of affine map from reference cell
13205
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13206
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13207
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13208
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13210
// Compute determinant of Jacobian
13211
const double detJ = J_00*J_11 - J_01*J_10;
13213
// Compute inverse of Jacobian
13215
// Get coordinates and map to the reference (UFC) element
13216
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13217
element_coordinates[0][0]*element_coordinates[2][1] +\
13218
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13219
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13220
element_coordinates[1][0]*element_coordinates[0][1] -\
13221
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13223
// Map coordinates to the reference square
13224
if (std::abs(y - 1.0) < 1e-14)
13227
x = 2.0 *x/(1.0 - y) - 1.0;
13233
// Map degree of freedom to element degree of freedom
13234
const unsigned int dof = i;
13236
// Generate scalings
13237
const double scalings_y_0 = 1;
13239
// Compute psitilde_a
13240
const double psitilde_a_0 = 1;
13242
// Compute psitilde_bs
13243
const double psitilde_bs_0_0 = 1;
13245
// Compute basisvalues
13246
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13248
// Table(s) of coefficients
13249
static const double coefficients0[1][1] = \
13250
{{1.41421356237309}};
13252
// Extract relevant coefficients
13253
const double coeff0_0 = coefficients0[dof][0];
13255
// Compute value(s)
13256
*values = coeff0_0*basisvalue0;
13259
/// Evaluate all basis functions at given point in cell
13260
void cahnhilliard2d_1_finite_element_5::evaluate_basis_all(double* values,
13261
const double* coordinates,
13262
const ufc::cell& c) const
13264
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
13267
/// Evaluate order n derivatives of basis function i at given point in cell
13268
void cahnhilliard2d_1_finite_element_5::evaluate_basis_derivatives(unsigned int i,
13271
const double* coordinates,
13272
const ufc::cell& c) const
13274
// Extract vertex coordinates
13275
const double * const * element_coordinates = c.coordinates;
13277
// Compute Jacobian of affine map from reference cell
13278
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13279
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13280
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13281
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13283
// Compute determinant of Jacobian
13284
const double detJ = J_00*J_11 - J_01*J_10;
13286
// Compute inverse of Jacobian
13288
// Get coordinates and map to the reference (UFC) element
13289
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13290
element_coordinates[0][0]*element_coordinates[2][1] +\
13291
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13292
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13293
element_coordinates[1][0]*element_coordinates[0][1] -\
13294
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13296
// Map coordinates to the reference square
13297
if (std::abs(y - 1.0) < 1e-14)
13300
x = 2.0 *x/(1.0 - y) - 1.0;
13303
// Compute number of derivatives
13304
unsigned int num_derivatives = 1;
13306
for (unsigned int j = 0; j < n; j++)
13307
num_derivatives *= 2;
13310
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
13311
unsigned int **combinations = new unsigned int *[num_derivatives];
13313
for (unsigned int j = 0; j < num_derivatives; j++)
13315
combinations[j] = new unsigned int [n];
13316
for (unsigned int k = 0; k < n; k++)
13317
combinations[j][k] = 0;
13320
// Generate combinations of derivatives
13321
for (unsigned int row = 1; row < num_derivatives; row++)
13323
for (unsigned int num = 0; num < row; num++)
13325
for (unsigned int col = n-1; col+1 > 0; col--)
13327
if (combinations[row][col] + 1 > 1)
13328
combinations[row][col] = 0;
13331
combinations[row][col] += 1;
13338
// Compute inverse of Jacobian
13339
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
13341
// Declare transformation matrix
13342
// Declare pointer to two dimensional array and initialise
13343
double **transform = new double *[num_derivatives];
13345
for (unsigned int j = 0; j < num_derivatives; j++)
13347
transform[j] = new double [num_derivatives];
13348
for (unsigned int k = 0; k < num_derivatives; k++)
13349
transform[j][k] = 1;
13352
// Construct transformation matrix
13353
for (unsigned int row = 0; row < num_derivatives; row++)
13355
for (unsigned int col = 0; col < num_derivatives; col++)
13357
for (unsigned int k = 0; k < n; k++)
13358
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13363
for (unsigned int j = 0; j < 1*num_derivatives; j++)
13366
// Map degree of freedom to element degree of freedom
13367
const unsigned int dof = i;
13369
// Generate scalings
13370
const double scalings_y_0 = 1;
13372
// Compute psitilde_a
13373
const double psitilde_a_0 = 1;
13375
// Compute psitilde_bs
13376
const double psitilde_bs_0_0 = 1;
13378
// Compute basisvalues
13379
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13381
// Table(s) of coefficients
13382
static const double coefficients0[1][1] = \
13383
{{1.41421356237309}};
13385
// Interesting (new) part
13386
// Tables of derivatives of the polynomial base (transpose)
13387
static const double dmats0[1][1] = \
13390
static const double dmats1[1][1] = \
13393
// Compute reference derivatives
13394
// Declare pointer to array of derivatives on FIAT element
13395
double *derivatives = new double [num_derivatives];
13397
// Declare coefficients
13398
double coeff0_0 = 0;
13400
// Declare new coefficients
13401
double new_coeff0_0 = 0;
13403
// Loop possible derivatives
13404
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13406
// Get values from coefficients array
13407
new_coeff0_0 = coefficients0[dof][0];
13409
// Loop derivative order
13410
for (unsigned int j = 0; j < n; j++)
13412
// Update old coefficients
13413
coeff0_0 = new_coeff0_0;
13415
if(combinations[deriv_num][j] == 0)
13417
new_coeff0_0 = coeff0_0*dmats0[0][0];
13419
if(combinations[deriv_num][j] == 1)
13421
new_coeff0_0 = coeff0_0*dmats1[0][0];
13425
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13426
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
13429
// Transform derivatives back to physical element
13430
for (unsigned int row = 0; row < num_derivatives; row++)
13432
for (unsigned int col = 0; col < num_derivatives; col++)
13434
values[row] += transform[row][col]*derivatives[col];
13437
// Delete pointer to array of derivatives on FIAT element
13438
delete [] derivatives;
13440
// Delete pointer to array of combinations of derivatives and transform
13441
for (unsigned int row = 0; row < num_derivatives; row++)
13443
delete [] combinations[row];
13444
delete [] transform[row];
13447
delete [] combinations;
13448
delete [] transform;
13451
/// Evaluate order n derivatives of all basis functions at given point in cell
13452
void cahnhilliard2d_1_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
13454
const double* coordinates,
13455
const ufc::cell& c) const
13457
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13460
/// Evaluate linear functional for dof i on the function f
13461
double cahnhilliard2d_1_finite_element_5::evaluate_dof(unsigned int i,
13462
const ufc::function& f,
13463
const ufc::cell& c) const
13465
// The reference points, direction and weights:
13466
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
13467
static const double W[1][1] = {{1}};
13468
static const double D[1][1][1] = {{{1}}};
13470
const double * const * x = c.coordinates;
13471
double result = 0.0;
13472
// Iterate over the points:
13473
// Evaluate basis functions for affine mapping
13474
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
13475
const double w1 = X[i][0][0];
13476
const double w2 = X[i][0][1];
13478
// Compute affine mapping y = F(X)
13480
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
13481
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
13483
// Evaluate function at physical points
13485
f.evaluate(values, y, c);
13487
// Map function values using appropriate mapping
13488
// Affine map: Do nothing
13490
// Note that we do not map the weights (yet).
13492
// Take directional components
13493
for(int k = 0; k < 1; k++)
13494
result += values[k]*D[i][0][k];
13495
// Multiply by weights
13501
/// Evaluate linear functionals for all dofs on the function f
13502
void cahnhilliard2d_1_finite_element_5::evaluate_dofs(double* values,
13503
const ufc::function& f,
13504
const ufc::cell& c) const
13506
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13509
/// Interpolate vertex values from dof values
13510
void cahnhilliard2d_1_finite_element_5::interpolate_vertex_values(double* vertex_values,
13511
const double* dof_values,
13512
const ufc::cell& c) const
13514
// Evaluate at vertices and use affine mapping
13515
vertex_values[0] = dof_values[0];
13516
vertex_values[1] = dof_values[0];
13517
vertex_values[2] = dof_values[0];
13520
/// Return the number of sub elements (for a mixed element)
13521
unsigned int cahnhilliard2d_1_finite_element_5::num_sub_elements() const
13526
/// Create a new finite element for sub element i (for a mixed element)
13527
ufc::finite_element* cahnhilliard2d_1_finite_element_5::create_sub_element(unsigned int i) const
13529
return new cahnhilliard2d_1_finite_element_5();
13534
cahnhilliard2d_1_finite_element_6::cahnhilliard2d_1_finite_element_6() : ufc::finite_element()
13540
cahnhilliard2d_1_finite_element_6::~cahnhilliard2d_1_finite_element_6()
13545
/// Return a string identifying the finite element
13546
const char* cahnhilliard2d_1_finite_element_6::signature() const
13548
return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
13551
/// Return the cell shape
13552
ufc::shape cahnhilliard2d_1_finite_element_6::cell_shape() const
13554
return ufc::triangle;
13557
/// Return the dimension of the finite element function space
13558
unsigned int cahnhilliard2d_1_finite_element_6::space_dimension() const
13563
/// Return the rank of the value space
13564
unsigned int cahnhilliard2d_1_finite_element_6::value_rank() const
13569
/// Return the dimension of the value space for axis i
13570
unsigned int cahnhilliard2d_1_finite_element_6::value_dimension(unsigned int i) const
13575
/// Evaluate basis function i at given point in cell
13576
void cahnhilliard2d_1_finite_element_6::evaluate_basis(unsigned int i,
13578
const double* coordinates,
13579
const ufc::cell& c) const
13581
// Extract vertex coordinates
13582
const double * const * element_coordinates = c.coordinates;
13584
// Compute Jacobian of affine map from reference cell
13585
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13586
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13587
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13588
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13590
// Compute determinant of Jacobian
13591
const double detJ = J_00*J_11 - J_01*J_10;
13593
// Compute inverse of Jacobian
13595
// Get coordinates and map to the reference (UFC) element
13596
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13597
element_coordinates[0][0]*element_coordinates[2][1] +\
13598
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13599
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13600
element_coordinates[1][0]*element_coordinates[0][1] -\
13601
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13603
// Map coordinates to the reference square
13604
if (std::abs(y - 1.0) < 1e-14)
13607
x = 2.0 *x/(1.0 - y) - 1.0;
13613
// Map degree of freedom to element degree of freedom
13614
const unsigned int dof = i;
13616
// Generate scalings
13617
const double scalings_y_0 = 1;
13619
// Compute psitilde_a
13620
const double psitilde_a_0 = 1;
13622
// Compute psitilde_bs
13623
const double psitilde_bs_0_0 = 1;
13625
// Compute basisvalues
13626
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13628
// Table(s) of coefficients
13629
static const double coefficients0[1][1] = \
13630
{{1.41421356237309}};
13632
// Extract relevant coefficients
13633
const double coeff0_0 = coefficients0[dof][0];
13635
// Compute value(s)
13636
*values = coeff0_0*basisvalue0;
13639
/// Evaluate all basis functions at given point in cell
13640
void cahnhilliard2d_1_finite_element_6::evaluate_basis_all(double* values,
13641
const double* coordinates,
13642
const ufc::cell& c) const
13644
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
13647
/// Evaluate order n derivatives of basis function i at given point in cell
13648
void cahnhilliard2d_1_finite_element_6::evaluate_basis_derivatives(unsigned int i,
13651
const double* coordinates,
13652
const ufc::cell& c) const
13654
// Extract vertex coordinates
13655
const double * const * element_coordinates = c.coordinates;
13657
// Compute Jacobian of affine map from reference cell
13658
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13659
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13660
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13661
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13663
// Compute determinant of Jacobian
13664
const double detJ = J_00*J_11 - J_01*J_10;
13666
// Compute inverse of Jacobian
13668
// Get coordinates and map to the reference (UFC) element
13669
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13670
element_coordinates[0][0]*element_coordinates[2][1] +\
13671
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13672
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13673
element_coordinates[1][0]*element_coordinates[0][1] -\
13674
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13676
// Map coordinates to the reference square
13677
if (std::abs(y - 1.0) < 1e-14)
13680
x = 2.0 *x/(1.0 - y) - 1.0;
13683
// Compute number of derivatives
13684
unsigned int num_derivatives = 1;
13686
for (unsigned int j = 0; j < n; j++)
13687
num_derivatives *= 2;
13690
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
13691
unsigned int **combinations = new unsigned int *[num_derivatives];
13693
for (unsigned int j = 0; j < num_derivatives; j++)
13695
combinations[j] = new unsigned int [n];
13696
for (unsigned int k = 0; k < n; k++)
13697
combinations[j][k] = 0;
13700
// Generate combinations of derivatives
13701
for (unsigned int row = 1; row < num_derivatives; row++)
13703
for (unsigned int num = 0; num < row; num++)
13705
for (unsigned int col = n-1; col+1 > 0; col--)
13707
if (combinations[row][col] + 1 > 1)
13708
combinations[row][col] = 0;
13711
combinations[row][col] += 1;
13718
// Compute inverse of Jacobian
13719
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
13721
// Declare transformation matrix
13722
// Declare pointer to two dimensional array and initialise
13723
double **transform = new double *[num_derivatives];
13725
for (unsigned int j = 0; j < num_derivatives; j++)
13727
transform[j] = new double [num_derivatives];
13728
for (unsigned int k = 0; k < num_derivatives; k++)
13729
transform[j][k] = 1;
13732
// Construct transformation matrix
13733
for (unsigned int row = 0; row < num_derivatives; row++)
13735
for (unsigned int col = 0; col < num_derivatives; col++)
13737
for (unsigned int k = 0; k < n; k++)
13738
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13743
for (unsigned int j = 0; j < 1*num_derivatives; j++)
13746
// Map degree of freedom to element degree of freedom
13747
const unsigned int dof = i;
13749
// Generate scalings
13750
const double scalings_y_0 = 1;
13752
// Compute psitilde_a
13753
const double psitilde_a_0 = 1;
13755
// Compute psitilde_bs
13756
const double psitilde_bs_0_0 = 1;
13758
// Compute basisvalues
13759
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13761
// Table(s) of coefficients
13762
static const double coefficients0[1][1] = \
13763
{{1.41421356237309}};
13765
// Interesting (new) part
13766
// Tables of derivatives of the polynomial base (transpose)
13767
static const double dmats0[1][1] = \
13770
static const double dmats1[1][1] = \
13773
// Compute reference derivatives
13774
// Declare pointer to array of derivatives on FIAT element
13775
double *derivatives = new double [num_derivatives];
13777
// Declare coefficients
13778
double coeff0_0 = 0;
13780
// Declare new coefficients
13781
double new_coeff0_0 = 0;
13783
// Loop possible derivatives
13784
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13786
// Get values from coefficients array
13787
new_coeff0_0 = coefficients0[dof][0];
13789
// Loop derivative order
13790
for (unsigned int j = 0; j < n; j++)
13792
// Update old coefficients
13793
coeff0_0 = new_coeff0_0;
13795
if(combinations[deriv_num][j] == 0)
13797
new_coeff0_0 = coeff0_0*dmats0[0][0];
13799
if(combinations[deriv_num][j] == 1)
13801
new_coeff0_0 = coeff0_0*dmats1[0][0];
13805
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13806
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
13809
// Transform derivatives back to physical element
13810
for (unsigned int row = 0; row < num_derivatives; row++)
13812
for (unsigned int col = 0; col < num_derivatives; col++)
13814
values[row] += transform[row][col]*derivatives[col];
13817
// Delete pointer to array of derivatives on FIAT element
13818
delete [] derivatives;
13820
// Delete pointer to array of combinations of derivatives and transform
13821
for (unsigned int row = 0; row < num_derivatives; row++)
13823
delete [] combinations[row];
13824
delete [] transform[row];
13827
delete [] combinations;
13828
delete [] transform;
13831
/// Evaluate order n derivatives of all basis functions at given point in cell
13832
void cahnhilliard2d_1_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
13834
const double* coordinates,
13835
const ufc::cell& c) const
13837
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13840
/// Evaluate linear functional for dof i on the function f
13841
double cahnhilliard2d_1_finite_element_6::evaluate_dof(unsigned int i,
13842
const ufc::function& f,
13843
const ufc::cell& c) const
13845
// The reference points, direction and weights:
13846
static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
13847
static const double W[1][1] = {{1}};
13848
static const double D[1][1][1] = {{{1}}};
13850
const double * const * x = c.coordinates;
13851
double result = 0.0;
13852
// Iterate over the points:
13853
// Evaluate basis functions for affine mapping
13854
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
13855
const double w1 = X[i][0][0];
13856
const double w2 = X[i][0][1];
13858
// Compute affine mapping y = F(X)
13860
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
13861
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
13863
// Evaluate function at physical points
13865
f.evaluate(values, y, c);
13867
// Map function values using appropriate mapping
13868
// Affine map: Do nothing
13870
// Note that we do not map the weights (yet).
13872
// Take directional components
13873
for(int k = 0; k < 1; k++)
13874
result += values[k]*D[i][0][k];
13875
// Multiply by weights
13881
/// Evaluate linear functionals for all dofs on the function f
13882
void cahnhilliard2d_1_finite_element_6::evaluate_dofs(double* values,
13883
const ufc::function& f,
13884
const ufc::cell& c) const
13886
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13889
/// Interpolate vertex values from dof values
13890
void cahnhilliard2d_1_finite_element_6::interpolate_vertex_values(double* vertex_values,
13891
const double* dof_values,
13892
const ufc::cell& c) const
13894
// Evaluate at vertices and use affine mapping
13895
vertex_values[0] = dof_values[0];
13896
vertex_values[1] = dof_values[0];
13897
vertex_values[2] = dof_values[0];
13900
/// Return the number of sub elements (for a mixed element)
13901
unsigned int cahnhilliard2d_1_finite_element_6::num_sub_elements() const
13906
/// Create a new finite element for sub element i (for a mixed element)
13907
ufc::finite_element* cahnhilliard2d_1_finite_element_6::create_sub_element(unsigned int i) const
13909
return new cahnhilliard2d_1_finite_element_6();
13913
cahnhilliard2d_1_dof_map_0_0::cahnhilliard2d_1_dof_map_0_0() : ufc::dof_map()
13915
__global_dimension = 0;
13919
cahnhilliard2d_1_dof_map_0_0::~cahnhilliard2d_1_dof_map_0_0()
13924
/// Return a string identifying the dof map
13925
const char* cahnhilliard2d_1_dof_map_0_0::signature() const
13927
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
13930
/// Return true iff mesh entities of topological dimension d are needed
13931
bool cahnhilliard2d_1_dof_map_0_0::needs_mesh_entities(unsigned int d) const
13948
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13949
bool cahnhilliard2d_1_dof_map_0_0::init_mesh(const ufc::mesh& m)
13951
__global_dimension = m.num_entities[0];
13955
/// Initialize dof map for given cell
13956
void cahnhilliard2d_1_dof_map_0_0::init_cell(const ufc::mesh& m,
13957
const ufc::cell& c)
13962
/// Finish initialization of dof map for cells
13963
void cahnhilliard2d_1_dof_map_0_0::init_cell_finalize()
13968
/// Return the dimension of the global finite element function space
13969
unsigned int cahnhilliard2d_1_dof_map_0_0::global_dimension() const
13971
return __global_dimension;
13974
/// Return the dimension of the local finite element function space for a cell
13975
unsigned int cahnhilliard2d_1_dof_map_0_0::local_dimension(const ufc::cell& c) const
13980
/// Return the maximum dimension of the local finite element function space
13981
unsigned int cahnhilliard2d_1_dof_map_0_0::max_local_dimension() const
13986
// Return the geometric dimension of the coordinates this dof map provides
13987
unsigned int cahnhilliard2d_1_dof_map_0_0::geometric_dimension() const
13992
/// Return the number of dofs on each cell facet
13993
unsigned int cahnhilliard2d_1_dof_map_0_0::num_facet_dofs() const
13998
/// Return the number of dofs associated with each cell entity of dimension d
13999
unsigned int cahnhilliard2d_1_dof_map_0_0::num_entity_dofs(unsigned int d) const
14001
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14004
/// Tabulate the local-to-global mapping of dofs on a cell
14005
void cahnhilliard2d_1_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
14006
const ufc::mesh& m,
14007
const ufc::cell& c) const
14009
dofs[0] = c.entity_indices[0][0];
14010
dofs[1] = c.entity_indices[0][1];
14011
dofs[2] = c.entity_indices[0][2];
14014
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14015
void cahnhilliard2d_1_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
14016
unsigned int facet) const
14035
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14036
void cahnhilliard2d_1_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
14037
unsigned int d, unsigned int i) const
14039
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14042
/// Tabulate the coordinates of all dofs on a cell
14043
void cahnhilliard2d_1_dof_map_0_0::tabulate_coordinates(double** coordinates,
14044
const ufc::cell& c) const
14046
const double * const * x = c.coordinates;
14047
coordinates[0][0] = x[0][0];
14048
coordinates[0][1] = x[0][1];
14049
coordinates[1][0] = x[1][0];
14050
coordinates[1][1] = x[1][1];
14051
coordinates[2][0] = x[2][0];
14052
coordinates[2][1] = x[2][1];
14055
/// Return the number of sub dof maps (for a mixed element)
14056
unsigned int cahnhilliard2d_1_dof_map_0_0::num_sub_dof_maps() const
14061
/// Create a new dof_map for sub dof map i (for a mixed element)
14062
ufc::dof_map* cahnhilliard2d_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
14064
return new cahnhilliard2d_1_dof_map_0_0();
14069
cahnhilliard2d_1_dof_map_0_1::cahnhilliard2d_1_dof_map_0_1() : ufc::dof_map()
14071
__global_dimension = 0;
14075
cahnhilliard2d_1_dof_map_0_1::~cahnhilliard2d_1_dof_map_0_1()
14080
/// Return a string identifying the dof map
14081
const char* cahnhilliard2d_1_dof_map_0_1::signature() const
14083
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14086
/// Return true iff mesh entities of topological dimension d are needed
14087
bool cahnhilliard2d_1_dof_map_0_1::needs_mesh_entities(unsigned int d) const
14104
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14105
bool cahnhilliard2d_1_dof_map_0_1::init_mesh(const ufc::mesh& m)
14107
__global_dimension = m.num_entities[0];
14111
/// Initialize dof map for given cell
14112
void cahnhilliard2d_1_dof_map_0_1::init_cell(const ufc::mesh& m,
14113
const ufc::cell& c)
14118
/// Finish initialization of dof map for cells
14119
void cahnhilliard2d_1_dof_map_0_1::init_cell_finalize()
14124
/// Return the dimension of the global finite element function space
14125
unsigned int cahnhilliard2d_1_dof_map_0_1::global_dimension() const
14127
return __global_dimension;
14130
/// Return the dimension of the local finite element function space for a cell
14131
unsigned int cahnhilliard2d_1_dof_map_0_1::local_dimension(const ufc::cell& c) const
14136
/// Return the maximum dimension of the local finite element function space
14137
unsigned int cahnhilliard2d_1_dof_map_0_1::max_local_dimension() const
14142
// Return the geometric dimension of the coordinates this dof map provides
14143
unsigned int cahnhilliard2d_1_dof_map_0_1::geometric_dimension() const
14148
/// Return the number of dofs on each cell facet
14149
unsigned int cahnhilliard2d_1_dof_map_0_1::num_facet_dofs() const
14154
/// Return the number of dofs associated with each cell entity of dimension d
14155
unsigned int cahnhilliard2d_1_dof_map_0_1::num_entity_dofs(unsigned int d) const
14157
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14160
/// Tabulate the local-to-global mapping of dofs on a cell
14161
void cahnhilliard2d_1_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
14162
const ufc::mesh& m,
14163
const ufc::cell& c) const
14165
dofs[0] = c.entity_indices[0][0];
14166
dofs[1] = c.entity_indices[0][1];
14167
dofs[2] = c.entity_indices[0][2];
14170
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14171
void cahnhilliard2d_1_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
14172
unsigned int facet) const
14191
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14192
void cahnhilliard2d_1_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
14193
unsigned int d, unsigned int i) const
14195
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14198
/// Tabulate the coordinates of all dofs on a cell
14199
void cahnhilliard2d_1_dof_map_0_1::tabulate_coordinates(double** coordinates,
14200
const ufc::cell& c) const
14202
const double * const * x = c.coordinates;
14203
coordinates[0][0] = x[0][0];
14204
coordinates[0][1] = x[0][1];
14205
coordinates[1][0] = x[1][0];
14206
coordinates[1][1] = x[1][1];
14207
coordinates[2][0] = x[2][0];
14208
coordinates[2][1] = x[2][1];
14211
/// Return the number of sub dof maps (for a mixed element)
14212
unsigned int cahnhilliard2d_1_dof_map_0_1::num_sub_dof_maps() const
14217
/// Create a new dof_map for sub dof map i (for a mixed element)
14218
ufc::dof_map* cahnhilliard2d_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
14220
return new cahnhilliard2d_1_dof_map_0_1();
14225
cahnhilliard2d_1_dof_map_0::cahnhilliard2d_1_dof_map_0() : ufc::dof_map()
14227
__global_dimension = 0;
14231
cahnhilliard2d_1_dof_map_0::~cahnhilliard2d_1_dof_map_0()
14236
/// Return a string identifying the dof map
14237
const char* cahnhilliard2d_1_dof_map_0::signature() const
14239
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
14242
/// Return true iff mesh entities of topological dimension d are needed
14243
bool cahnhilliard2d_1_dof_map_0::needs_mesh_entities(unsigned int d) const
14260
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14261
bool cahnhilliard2d_1_dof_map_0::init_mesh(const ufc::mesh& m)
14263
__global_dimension = 2*m.num_entities[0];
14267
/// Initialize dof map for given cell
14268
void cahnhilliard2d_1_dof_map_0::init_cell(const ufc::mesh& m,
14269
const ufc::cell& c)
14274
/// Finish initialization of dof map for cells
14275
void cahnhilliard2d_1_dof_map_0::init_cell_finalize()
14280
/// Return the dimension of the global finite element function space
14281
unsigned int cahnhilliard2d_1_dof_map_0::global_dimension() const
14283
return __global_dimension;
14286
/// Return the dimension of the local finite element function space for a cell
14287
unsigned int cahnhilliard2d_1_dof_map_0::local_dimension(const ufc::cell& c) const
14292
/// Return the maximum dimension of the local finite element function space
14293
unsigned int cahnhilliard2d_1_dof_map_0::max_local_dimension() const
14298
// Return the geometric dimension of the coordinates this dof map provides
14299
unsigned int cahnhilliard2d_1_dof_map_0::geometric_dimension() const
14304
/// Return the number of dofs on each cell facet
14305
unsigned int cahnhilliard2d_1_dof_map_0::num_facet_dofs() const
14310
/// Return the number of dofs associated with each cell entity of dimension d
14311
unsigned int cahnhilliard2d_1_dof_map_0::num_entity_dofs(unsigned int d) const
14313
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14316
/// Tabulate the local-to-global mapping of dofs on a cell
14317
void cahnhilliard2d_1_dof_map_0::tabulate_dofs(unsigned int* dofs,
14318
const ufc::mesh& m,
14319
const ufc::cell& c) const
14321
dofs[0] = c.entity_indices[0][0];
14322
dofs[1] = c.entity_indices[0][1];
14323
dofs[2] = c.entity_indices[0][2];
14324
unsigned int offset = m.num_entities[0];
14325
dofs[3] = offset + c.entity_indices[0][0];
14326
dofs[4] = offset + c.entity_indices[0][1];
14327
dofs[5] = offset + c.entity_indices[0][2];
14330
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14331
void cahnhilliard2d_1_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
14332
unsigned int facet) const
14357
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14358
void cahnhilliard2d_1_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
14359
unsigned int d, unsigned int i) const
14361
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14364
/// Tabulate the coordinates of all dofs on a cell
14365
void cahnhilliard2d_1_dof_map_0::tabulate_coordinates(double** coordinates,
14366
const ufc::cell& c) const
14368
const double * const * x = c.coordinates;
14369
coordinates[0][0] = x[0][0];
14370
coordinates[0][1] = x[0][1];
14371
coordinates[1][0] = x[1][0];
14372
coordinates[1][1] = x[1][1];
14373
coordinates[2][0] = x[2][0];
14374
coordinates[2][1] = x[2][1];
14375
coordinates[3][0] = x[0][0];
14376
coordinates[3][1] = x[0][1];
14377
coordinates[4][0] = x[1][0];
14378
coordinates[4][1] = x[1][1];
14379
coordinates[5][0] = x[2][0];
14380
coordinates[5][1] = x[2][1];
14383
/// Return the number of sub dof maps (for a mixed element)
14384
unsigned int cahnhilliard2d_1_dof_map_0::num_sub_dof_maps() const
14389
/// Create a new dof_map for sub dof map i (for a mixed element)
14390
ufc::dof_map* cahnhilliard2d_1_dof_map_0::create_sub_dof_map(unsigned int i) const
14395
return new cahnhilliard2d_1_dof_map_0_0();
14398
return new cahnhilliard2d_1_dof_map_0_1();
14406
cahnhilliard2d_1_dof_map_1_0::cahnhilliard2d_1_dof_map_1_0() : ufc::dof_map()
14408
__global_dimension = 0;
14412
cahnhilliard2d_1_dof_map_1_0::~cahnhilliard2d_1_dof_map_1_0()
14417
/// Return a string identifying the dof map
14418
const char* cahnhilliard2d_1_dof_map_1_0::signature() const
14420
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14423
/// Return true iff mesh entities of topological dimension d are needed
14424
bool cahnhilliard2d_1_dof_map_1_0::needs_mesh_entities(unsigned int d) const
14441
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14442
bool cahnhilliard2d_1_dof_map_1_0::init_mesh(const ufc::mesh& m)
14444
__global_dimension = m.num_entities[0];
14448
/// Initialize dof map for given cell
14449
void cahnhilliard2d_1_dof_map_1_0::init_cell(const ufc::mesh& m,
14450
const ufc::cell& c)
14455
/// Finish initialization of dof map for cells
14456
void cahnhilliard2d_1_dof_map_1_0::init_cell_finalize()
14461
/// Return the dimension of the global finite element function space
14462
unsigned int cahnhilliard2d_1_dof_map_1_0::global_dimension() const
14464
return __global_dimension;
14467
/// Return the dimension of the local finite element function space for a cell
14468
unsigned int cahnhilliard2d_1_dof_map_1_0::local_dimension(const ufc::cell& c) const
14473
/// Return the maximum dimension of the local finite element function space
14474
unsigned int cahnhilliard2d_1_dof_map_1_0::max_local_dimension() const
14479
// Return the geometric dimension of the coordinates this dof map provides
14480
unsigned int cahnhilliard2d_1_dof_map_1_0::geometric_dimension() const
14485
/// Return the number of dofs on each cell facet
14486
unsigned int cahnhilliard2d_1_dof_map_1_0::num_facet_dofs() const
14491
/// Return the number of dofs associated with each cell entity of dimension d
14492
unsigned int cahnhilliard2d_1_dof_map_1_0::num_entity_dofs(unsigned int d) const
14494
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14497
/// Tabulate the local-to-global mapping of dofs on a cell
14498
void cahnhilliard2d_1_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
14499
const ufc::mesh& m,
14500
const ufc::cell& c) const
14502
dofs[0] = c.entity_indices[0][0];
14503
dofs[1] = c.entity_indices[0][1];
14504
dofs[2] = c.entity_indices[0][2];
14507
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14508
void cahnhilliard2d_1_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
14509
unsigned int facet) const
14528
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14529
void cahnhilliard2d_1_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
14530
unsigned int d, unsigned int i) const
14532
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14535
/// Tabulate the coordinates of all dofs on a cell
14536
void cahnhilliard2d_1_dof_map_1_0::tabulate_coordinates(double** coordinates,
14537
const ufc::cell& c) const
14539
const double * const * x = c.coordinates;
14540
coordinates[0][0] = x[0][0];
14541
coordinates[0][1] = x[0][1];
14542
coordinates[1][0] = x[1][0];
14543
coordinates[1][1] = x[1][1];
14544
coordinates[2][0] = x[2][0];
14545
coordinates[2][1] = x[2][1];
14548
/// Return the number of sub dof maps (for a mixed element)
14549
unsigned int cahnhilliard2d_1_dof_map_1_0::num_sub_dof_maps() const
14554
/// Create a new dof_map for sub dof map i (for a mixed element)
14555
ufc::dof_map* cahnhilliard2d_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
14557
return new cahnhilliard2d_1_dof_map_1_0();
14562
cahnhilliard2d_1_dof_map_1_1::cahnhilliard2d_1_dof_map_1_1() : ufc::dof_map()
14564
__global_dimension = 0;
14568
cahnhilliard2d_1_dof_map_1_1::~cahnhilliard2d_1_dof_map_1_1()
14573
/// Return a string identifying the dof map
14574
const char* cahnhilliard2d_1_dof_map_1_1::signature() const
14576
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14579
/// Return true iff mesh entities of topological dimension d are needed
14580
bool cahnhilliard2d_1_dof_map_1_1::needs_mesh_entities(unsigned int d) const
14597
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14598
bool cahnhilliard2d_1_dof_map_1_1::init_mesh(const ufc::mesh& m)
14600
__global_dimension = m.num_entities[0];
14604
/// Initialize dof map for given cell
14605
void cahnhilliard2d_1_dof_map_1_1::init_cell(const ufc::mesh& m,
14606
const ufc::cell& c)
14611
/// Finish initialization of dof map for cells
14612
void cahnhilliard2d_1_dof_map_1_1::init_cell_finalize()
14617
/// Return the dimension of the global finite element function space
14618
unsigned int cahnhilliard2d_1_dof_map_1_1::global_dimension() const
14620
return __global_dimension;
14623
/// Return the dimension of the local finite element function space for a cell
14624
unsigned int cahnhilliard2d_1_dof_map_1_1::local_dimension(const ufc::cell& c) const
14629
/// Return the maximum dimension of the local finite element function space
14630
unsigned int cahnhilliard2d_1_dof_map_1_1::max_local_dimension() const
14635
// Return the geometric dimension of the coordinates this dof map provides
14636
unsigned int cahnhilliard2d_1_dof_map_1_1::geometric_dimension() const
14641
/// Return the number of dofs on each cell facet
14642
unsigned int cahnhilliard2d_1_dof_map_1_1::num_facet_dofs() const
14647
/// Return the number of dofs associated with each cell entity of dimension d
14648
unsigned int cahnhilliard2d_1_dof_map_1_1::num_entity_dofs(unsigned int d) const
14650
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14653
/// Tabulate the local-to-global mapping of dofs on a cell
14654
void cahnhilliard2d_1_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
14655
const ufc::mesh& m,
14656
const ufc::cell& c) const
14658
dofs[0] = c.entity_indices[0][0];
14659
dofs[1] = c.entity_indices[0][1];
14660
dofs[2] = c.entity_indices[0][2];
14663
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14664
void cahnhilliard2d_1_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
14665
unsigned int facet) const
14684
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14685
void cahnhilliard2d_1_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
14686
unsigned int d, unsigned int i) const
14688
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14691
/// Tabulate the coordinates of all dofs on a cell
14692
void cahnhilliard2d_1_dof_map_1_1::tabulate_coordinates(double** coordinates,
14693
const ufc::cell& c) const
14695
const double * const * x = c.coordinates;
14696
coordinates[0][0] = x[0][0];
14697
coordinates[0][1] = x[0][1];
14698
coordinates[1][0] = x[1][0];
14699
coordinates[1][1] = x[1][1];
14700
coordinates[2][0] = x[2][0];
14701
coordinates[2][1] = x[2][1];
14704
/// Return the number of sub dof maps (for a mixed element)
14705
unsigned int cahnhilliard2d_1_dof_map_1_1::num_sub_dof_maps() const
14710
/// Create a new dof_map for sub dof map i (for a mixed element)
14711
ufc::dof_map* cahnhilliard2d_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
14713
return new cahnhilliard2d_1_dof_map_1_1();
14718
cahnhilliard2d_1_dof_map_1::cahnhilliard2d_1_dof_map_1() : ufc::dof_map()
14720
__global_dimension = 0;
14724
cahnhilliard2d_1_dof_map_1::~cahnhilliard2d_1_dof_map_1()
14729
/// Return a string identifying the dof map
14730
const char* cahnhilliard2d_1_dof_map_1::signature() const
14732
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
14735
/// Return true iff mesh entities of topological dimension d are needed
14736
bool cahnhilliard2d_1_dof_map_1::needs_mesh_entities(unsigned int d) const
14753
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14754
bool cahnhilliard2d_1_dof_map_1::init_mesh(const ufc::mesh& m)
14756
__global_dimension = 2*m.num_entities[0];
14760
/// Initialize dof map for given cell
14761
void cahnhilliard2d_1_dof_map_1::init_cell(const ufc::mesh& m,
14762
const ufc::cell& c)
14767
/// Finish initialization of dof map for cells
14768
void cahnhilliard2d_1_dof_map_1::init_cell_finalize()
14773
/// Return the dimension of the global finite element function space
14774
unsigned int cahnhilliard2d_1_dof_map_1::global_dimension() const
14776
return __global_dimension;
14779
/// Return the dimension of the local finite element function space for a cell
14780
unsigned int cahnhilliard2d_1_dof_map_1::local_dimension(const ufc::cell& c) const
14785
/// Return the maximum dimension of the local finite element function space
14786
unsigned int cahnhilliard2d_1_dof_map_1::max_local_dimension() const
14791
// Return the geometric dimension of the coordinates this dof map provides
14792
unsigned int cahnhilliard2d_1_dof_map_1::geometric_dimension() const
14797
/// Return the number of dofs on each cell facet
14798
unsigned int cahnhilliard2d_1_dof_map_1::num_facet_dofs() const
14803
/// Return the number of dofs associated with each cell entity of dimension d
14804
unsigned int cahnhilliard2d_1_dof_map_1::num_entity_dofs(unsigned int d) const
14806
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14809
/// Tabulate the local-to-global mapping of dofs on a cell
14810
void cahnhilliard2d_1_dof_map_1::tabulate_dofs(unsigned int* dofs,
14811
const ufc::mesh& m,
14812
const ufc::cell& c) const
14814
dofs[0] = c.entity_indices[0][0];
14815
dofs[1] = c.entity_indices[0][1];
14816
dofs[2] = c.entity_indices[0][2];
14817
unsigned int offset = m.num_entities[0];
14818
dofs[3] = offset + c.entity_indices[0][0];
14819
dofs[4] = offset + c.entity_indices[0][1];
14820
dofs[5] = offset + c.entity_indices[0][2];
14823
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14824
void cahnhilliard2d_1_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
14825
unsigned int facet) const
14850
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14851
void cahnhilliard2d_1_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
14852
unsigned int d, unsigned int i) const
14854
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14857
/// Tabulate the coordinates of all dofs on a cell
14858
void cahnhilliard2d_1_dof_map_1::tabulate_coordinates(double** coordinates,
14859
const ufc::cell& c) const
14861
const double * const * x = c.coordinates;
14862
coordinates[0][0] = x[0][0];
14863
coordinates[0][1] = x[0][1];
14864
coordinates[1][0] = x[1][0];
14865
coordinates[1][1] = x[1][1];
14866
coordinates[2][0] = x[2][0];
14867
coordinates[2][1] = x[2][1];
14868
coordinates[3][0] = x[0][0];
14869
coordinates[3][1] = x[0][1];
14870
coordinates[4][0] = x[1][0];
14871
coordinates[4][1] = x[1][1];
14872
coordinates[5][0] = x[2][0];
14873
coordinates[5][1] = x[2][1];
14876
/// Return the number of sub dof maps (for a mixed element)
14877
unsigned int cahnhilliard2d_1_dof_map_1::num_sub_dof_maps() const
14882
/// Create a new dof_map for sub dof map i (for a mixed element)
14883
ufc::dof_map* cahnhilliard2d_1_dof_map_1::create_sub_dof_map(unsigned int i) const
14888
return new cahnhilliard2d_1_dof_map_1_0();
14891
return new cahnhilliard2d_1_dof_map_1_1();
14899
cahnhilliard2d_1_dof_map_2_0::cahnhilliard2d_1_dof_map_2_0() : ufc::dof_map()
14901
__global_dimension = 0;
14905
cahnhilliard2d_1_dof_map_2_0::~cahnhilliard2d_1_dof_map_2_0()
14910
/// Return a string identifying the dof map
14911
const char* cahnhilliard2d_1_dof_map_2_0::signature() const
14913
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14916
/// Return true iff mesh entities of topological dimension d are needed
14917
bool cahnhilliard2d_1_dof_map_2_0::needs_mesh_entities(unsigned int d) const
14934
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14935
bool cahnhilliard2d_1_dof_map_2_0::init_mesh(const ufc::mesh& m)
14937
__global_dimension = m.num_entities[0];
14941
/// Initialize dof map for given cell
14942
void cahnhilliard2d_1_dof_map_2_0::init_cell(const ufc::mesh& m,
14943
const ufc::cell& c)
14948
/// Finish initialization of dof map for cells
14949
void cahnhilliard2d_1_dof_map_2_0::init_cell_finalize()
14954
/// Return the dimension of the global finite element function space
14955
unsigned int cahnhilliard2d_1_dof_map_2_0::global_dimension() const
14957
return __global_dimension;
14960
/// Return the dimension of the local finite element function space for a cell
14961
unsigned int cahnhilliard2d_1_dof_map_2_0::local_dimension(const ufc::cell& c) const
14966
/// Return the maximum dimension of the local finite element function space
14967
unsigned int cahnhilliard2d_1_dof_map_2_0::max_local_dimension() const
14972
// Return the geometric dimension of the coordinates this dof map provides
14973
unsigned int cahnhilliard2d_1_dof_map_2_0::geometric_dimension() const
14978
/// Return the number of dofs on each cell facet
14979
unsigned int cahnhilliard2d_1_dof_map_2_0::num_facet_dofs() const
14984
/// Return the number of dofs associated with each cell entity of dimension d
14985
unsigned int cahnhilliard2d_1_dof_map_2_0::num_entity_dofs(unsigned int d) const
14987
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14990
/// Tabulate the local-to-global mapping of dofs on a cell
14991
void cahnhilliard2d_1_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
14992
const ufc::mesh& m,
14993
const ufc::cell& c) const
14995
dofs[0] = c.entity_indices[0][0];
14996
dofs[1] = c.entity_indices[0][1];
14997
dofs[2] = c.entity_indices[0][2];
15000
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15001
void cahnhilliard2d_1_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
15002
unsigned int facet) const
15021
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15022
void cahnhilliard2d_1_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
15023
unsigned int d, unsigned int i) const
15025
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15028
/// Tabulate the coordinates of all dofs on a cell
15029
void cahnhilliard2d_1_dof_map_2_0::tabulate_coordinates(double** coordinates,
15030
const ufc::cell& c) const
15032
const double * const * x = c.coordinates;
15033
coordinates[0][0] = x[0][0];
15034
coordinates[0][1] = x[0][1];
15035
coordinates[1][0] = x[1][0];
15036
coordinates[1][1] = x[1][1];
15037
coordinates[2][0] = x[2][0];
15038
coordinates[2][1] = x[2][1];
15041
/// Return the number of sub dof maps (for a mixed element)
15042
unsigned int cahnhilliard2d_1_dof_map_2_0::num_sub_dof_maps() const
15047
/// Create a new dof_map for sub dof map i (for a mixed element)
15048
ufc::dof_map* cahnhilliard2d_1_dof_map_2_0::create_sub_dof_map(unsigned int i) const
15050
return new cahnhilliard2d_1_dof_map_2_0();
15055
cahnhilliard2d_1_dof_map_2_1::cahnhilliard2d_1_dof_map_2_1() : ufc::dof_map()
15057
__global_dimension = 0;
15061
cahnhilliard2d_1_dof_map_2_1::~cahnhilliard2d_1_dof_map_2_1()
15066
/// Return a string identifying the dof map
15067
const char* cahnhilliard2d_1_dof_map_2_1::signature() const
15069
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
15072
/// Return true iff mesh entities of topological dimension d are needed
15073
bool cahnhilliard2d_1_dof_map_2_1::needs_mesh_entities(unsigned int d) const
15090
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15091
bool cahnhilliard2d_1_dof_map_2_1::init_mesh(const ufc::mesh& m)
15093
__global_dimension = m.num_entities[0];
15097
/// Initialize dof map for given cell
15098
void cahnhilliard2d_1_dof_map_2_1::init_cell(const ufc::mesh& m,
15099
const ufc::cell& c)
15104
/// Finish initialization of dof map for cells
15105
void cahnhilliard2d_1_dof_map_2_1::init_cell_finalize()
15110
/// Return the dimension of the global finite element function space
15111
unsigned int cahnhilliard2d_1_dof_map_2_1::global_dimension() const
15113
return __global_dimension;
15116
/// Return the dimension of the local finite element function space for a cell
15117
unsigned int cahnhilliard2d_1_dof_map_2_1::local_dimension(const ufc::cell& c) const
15122
/// Return the maximum dimension of the local finite element function space
15123
unsigned int cahnhilliard2d_1_dof_map_2_1::max_local_dimension() const
15128
// Return the geometric dimension of the coordinates this dof map provides
15129
unsigned int cahnhilliard2d_1_dof_map_2_1::geometric_dimension() const
15134
/// Return the number of dofs on each cell facet
15135
unsigned int cahnhilliard2d_1_dof_map_2_1::num_facet_dofs() const
15140
/// Return the number of dofs associated with each cell entity of dimension d
15141
unsigned int cahnhilliard2d_1_dof_map_2_1::num_entity_dofs(unsigned int d) const
15143
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15146
/// Tabulate the local-to-global mapping of dofs on a cell
15147
void cahnhilliard2d_1_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
15148
const ufc::mesh& m,
15149
const ufc::cell& c) const
15151
dofs[0] = c.entity_indices[0][0];
15152
dofs[1] = c.entity_indices[0][1];
15153
dofs[2] = c.entity_indices[0][2];
15156
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15157
void cahnhilliard2d_1_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
15158
unsigned int facet) const
15177
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15178
void cahnhilliard2d_1_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
15179
unsigned int d, unsigned int i) const
15181
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15184
/// Tabulate the coordinates of all dofs on a cell
15185
void cahnhilliard2d_1_dof_map_2_1::tabulate_coordinates(double** coordinates,
15186
const ufc::cell& c) const
15188
const double * const * x = c.coordinates;
15189
coordinates[0][0] = x[0][0];
15190
coordinates[0][1] = x[0][1];
15191
coordinates[1][0] = x[1][0];
15192
coordinates[1][1] = x[1][1];
15193
coordinates[2][0] = x[2][0];
15194
coordinates[2][1] = x[2][1];
15197
/// Return the number of sub dof maps (for a mixed element)
15198
unsigned int cahnhilliard2d_1_dof_map_2_1::num_sub_dof_maps() const
15203
/// Create a new dof_map for sub dof map i (for a mixed element)
15204
ufc::dof_map* cahnhilliard2d_1_dof_map_2_1::create_sub_dof_map(unsigned int i) const
15206
return new cahnhilliard2d_1_dof_map_2_1();
15211
cahnhilliard2d_1_dof_map_2::cahnhilliard2d_1_dof_map_2() : ufc::dof_map()
15213
__global_dimension = 0;
15217
cahnhilliard2d_1_dof_map_2::~cahnhilliard2d_1_dof_map_2()
15222
/// Return a string identifying the dof map
15223
const char* cahnhilliard2d_1_dof_map_2::signature() const
15225
return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
15228
/// Return true iff mesh entities of topological dimension d are needed
15229
bool cahnhilliard2d_1_dof_map_2::needs_mesh_entities(unsigned int d) const
15246
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15247
bool cahnhilliard2d_1_dof_map_2::init_mesh(const ufc::mesh& m)
15249
__global_dimension = 2*m.num_entities[0];
15253
/// Initialize dof map for given cell
15254
void cahnhilliard2d_1_dof_map_2::init_cell(const ufc::mesh& m,
15255
const ufc::cell& c)
15260
/// Finish initialization of dof map for cells
15261
void cahnhilliard2d_1_dof_map_2::init_cell_finalize()
15266
/// Return the dimension of the global finite element function space
15267
unsigned int cahnhilliard2d_1_dof_map_2::global_dimension() const
15269
return __global_dimension;
15272
/// Return the dimension of the local finite element function space for a cell
15273
unsigned int cahnhilliard2d_1_dof_map_2::local_dimension(const ufc::cell& c) const
15278
/// Return the maximum dimension of the local finite element function space
15279
unsigned int cahnhilliard2d_1_dof_map_2::max_local_dimension() const
15284
// Return the geometric dimension of the coordinates this dof map provides
15285
unsigned int cahnhilliard2d_1_dof_map_2::geometric_dimension() const
15290
/// Return the number of dofs on each cell facet
15291
unsigned int cahnhilliard2d_1_dof_map_2::num_facet_dofs() const
15296
/// Return the number of dofs associated with each cell entity of dimension d
15297
unsigned int cahnhilliard2d_1_dof_map_2::num_entity_dofs(unsigned int d) const
15299
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15302
/// Tabulate the local-to-global mapping of dofs on a cell
15303
void cahnhilliard2d_1_dof_map_2::tabulate_dofs(unsigned int* dofs,
15304
const ufc::mesh& m,
15305
const ufc::cell& c) const
15307
dofs[0] = c.entity_indices[0][0];
15308
dofs[1] = c.entity_indices[0][1];
15309
dofs[2] = c.entity_indices[0][2];
15310
unsigned int offset = m.num_entities[0];
15311
dofs[3] = offset + c.entity_indices[0][0];
15312
dofs[4] = offset + c.entity_indices[0][1];
15313
dofs[5] = offset + c.entity_indices[0][2];
15316
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15317
void cahnhilliard2d_1_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
15318
unsigned int facet) const
15343
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15344
void cahnhilliard2d_1_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
15345
unsigned int d, unsigned int i) const
15347
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15350
/// Tabulate the coordinates of all dofs on a cell
15351
void cahnhilliard2d_1_dof_map_2::tabulate_coordinates(double** coordinates,
15352
const ufc::cell& c) const
15354
const double * const * x = c.coordinates;
15355
coordinates[0][0] = x[0][0];
15356
coordinates[0][1] = x[0][1];
15357
coordinates[1][0] = x[1][0];
15358
coordinates[1][1] = x[1][1];
15359
coordinates[2][0] = x[2][0];
15360
coordinates[2][1] = x[2][1];
15361
coordinates[3][0] = x[0][0];
15362
coordinates[3][1] = x[0][1];
15363
coordinates[4][0] = x[1][0];
15364
coordinates[4][1] = x[1][1];
15365
coordinates[5][0] = x[2][0];
15366
coordinates[5][1] = x[2][1];
15369
/// Return the number of sub dof maps (for a mixed element)
15370
unsigned int cahnhilliard2d_1_dof_map_2::num_sub_dof_maps() const
15375
/// Create a new dof_map for sub dof map i (for a mixed element)
15376
ufc::dof_map* cahnhilliard2d_1_dof_map_2::create_sub_dof_map(unsigned int i) const
15381
return new cahnhilliard2d_1_dof_map_2_0();
15384
return new cahnhilliard2d_1_dof_map_2_1();
15392
cahnhilliard2d_1_dof_map_3::cahnhilliard2d_1_dof_map_3() : ufc::dof_map()
15394
__global_dimension = 0;
15398
cahnhilliard2d_1_dof_map_3::~cahnhilliard2d_1_dof_map_3()
15403
/// Return a string identifying the dof map
15404
const char* cahnhilliard2d_1_dof_map_3::signature() const
15406
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15409
/// Return true iff mesh entities of topological dimension d are needed
15410
bool cahnhilliard2d_1_dof_map_3::needs_mesh_entities(unsigned int d) const
15427
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15428
bool cahnhilliard2d_1_dof_map_3::init_mesh(const ufc::mesh& m)
15430
__global_dimension = m.num_entities[2];
15434
/// Initialize dof map for given cell
15435
void cahnhilliard2d_1_dof_map_3::init_cell(const ufc::mesh& m,
15436
const ufc::cell& c)
15441
/// Finish initialization of dof map for cells
15442
void cahnhilliard2d_1_dof_map_3::init_cell_finalize()
15447
/// Return the dimension of the global finite element function space
15448
unsigned int cahnhilliard2d_1_dof_map_3::global_dimension() const
15450
return __global_dimension;
15453
/// Return the dimension of the local finite element function space for a cell
15454
unsigned int cahnhilliard2d_1_dof_map_3::local_dimension(const ufc::cell& c) const
15459
/// Return the maximum dimension of the local finite element function space
15460
unsigned int cahnhilliard2d_1_dof_map_3::max_local_dimension() const
15465
// Return the geometric dimension of the coordinates this dof map provides
15466
unsigned int cahnhilliard2d_1_dof_map_3::geometric_dimension() const
15471
/// Return the number of dofs on each cell facet
15472
unsigned int cahnhilliard2d_1_dof_map_3::num_facet_dofs() const
15477
/// Return the number of dofs associated with each cell entity of dimension d
15478
unsigned int cahnhilliard2d_1_dof_map_3::num_entity_dofs(unsigned int d) const
15480
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15483
/// Tabulate the local-to-global mapping of dofs on a cell
15484
void cahnhilliard2d_1_dof_map_3::tabulate_dofs(unsigned int* dofs,
15485
const ufc::mesh& m,
15486
const ufc::cell& c) const
15488
dofs[0] = c.entity_indices[2][0];
15491
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15492
void cahnhilliard2d_1_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
15493
unsigned int facet) const
15509
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15510
void cahnhilliard2d_1_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
15511
unsigned int d, unsigned int i) const
15513
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15516
/// Tabulate the coordinates of all dofs on a cell
15517
void cahnhilliard2d_1_dof_map_3::tabulate_coordinates(double** coordinates,
15518
const ufc::cell& c) const
15520
const double * const * x = c.coordinates;
15521
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15522
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15525
/// Return the number of sub dof maps (for a mixed element)
15526
unsigned int cahnhilliard2d_1_dof_map_3::num_sub_dof_maps() const
15531
/// Create a new dof_map for sub dof map i (for a mixed element)
15532
ufc::dof_map* cahnhilliard2d_1_dof_map_3::create_sub_dof_map(unsigned int i) const
15534
return new cahnhilliard2d_1_dof_map_3();
15539
cahnhilliard2d_1_dof_map_4::cahnhilliard2d_1_dof_map_4() : ufc::dof_map()
15541
__global_dimension = 0;
15545
cahnhilliard2d_1_dof_map_4::~cahnhilliard2d_1_dof_map_4()
15550
/// Return a string identifying the dof map
15551
const char* cahnhilliard2d_1_dof_map_4::signature() const
15553
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15556
/// Return true iff mesh entities of topological dimension d are needed
15557
bool cahnhilliard2d_1_dof_map_4::needs_mesh_entities(unsigned int d) const
15574
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15575
bool cahnhilliard2d_1_dof_map_4::init_mesh(const ufc::mesh& m)
15577
__global_dimension = m.num_entities[2];
15581
/// Initialize dof map for given cell
15582
void cahnhilliard2d_1_dof_map_4::init_cell(const ufc::mesh& m,
15583
const ufc::cell& c)
15588
/// Finish initialization of dof map for cells
15589
void cahnhilliard2d_1_dof_map_4::init_cell_finalize()
15594
/// Return the dimension of the global finite element function space
15595
unsigned int cahnhilliard2d_1_dof_map_4::global_dimension() const
15597
return __global_dimension;
15600
/// Return the dimension of the local finite element function space for a cell
15601
unsigned int cahnhilliard2d_1_dof_map_4::local_dimension(const ufc::cell& c) const
15606
/// Return the maximum dimension of the local finite element function space
15607
unsigned int cahnhilliard2d_1_dof_map_4::max_local_dimension() const
15612
// Return the geometric dimension of the coordinates this dof map provides
15613
unsigned int cahnhilliard2d_1_dof_map_4::geometric_dimension() const
15618
/// Return the number of dofs on each cell facet
15619
unsigned int cahnhilliard2d_1_dof_map_4::num_facet_dofs() const
15624
/// Return the number of dofs associated with each cell entity of dimension d
15625
unsigned int cahnhilliard2d_1_dof_map_4::num_entity_dofs(unsigned int d) const
15627
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15630
/// Tabulate the local-to-global mapping of dofs on a cell
15631
void cahnhilliard2d_1_dof_map_4::tabulate_dofs(unsigned int* dofs,
15632
const ufc::mesh& m,
15633
const ufc::cell& c) const
15635
dofs[0] = c.entity_indices[2][0];
15638
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15639
void cahnhilliard2d_1_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
15640
unsigned int facet) const
15656
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15657
void cahnhilliard2d_1_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
15658
unsigned int d, unsigned int i) const
15660
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15663
/// Tabulate the coordinates of all dofs on a cell
15664
void cahnhilliard2d_1_dof_map_4::tabulate_coordinates(double** coordinates,
15665
const ufc::cell& c) const
15667
const double * const * x = c.coordinates;
15668
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15669
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15672
/// Return the number of sub dof maps (for a mixed element)
15673
unsigned int cahnhilliard2d_1_dof_map_4::num_sub_dof_maps() const
15678
/// Create a new dof_map for sub dof map i (for a mixed element)
15679
ufc::dof_map* cahnhilliard2d_1_dof_map_4::create_sub_dof_map(unsigned int i) const
15681
return new cahnhilliard2d_1_dof_map_4();
15686
cahnhilliard2d_1_dof_map_5::cahnhilliard2d_1_dof_map_5() : ufc::dof_map()
15688
__global_dimension = 0;
15692
cahnhilliard2d_1_dof_map_5::~cahnhilliard2d_1_dof_map_5()
15697
/// Return a string identifying the dof map
15698
const char* cahnhilliard2d_1_dof_map_5::signature() const
15700
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15703
/// Return true iff mesh entities of topological dimension d are needed
15704
bool cahnhilliard2d_1_dof_map_5::needs_mesh_entities(unsigned int d) const
15721
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15722
bool cahnhilliard2d_1_dof_map_5::init_mesh(const ufc::mesh& m)
15724
__global_dimension = m.num_entities[2];
15728
/// Initialize dof map for given cell
15729
void cahnhilliard2d_1_dof_map_5::init_cell(const ufc::mesh& m,
15730
const ufc::cell& c)
15735
/// Finish initialization of dof map for cells
15736
void cahnhilliard2d_1_dof_map_5::init_cell_finalize()
15741
/// Return the dimension of the global finite element function space
15742
unsigned int cahnhilliard2d_1_dof_map_5::global_dimension() const
15744
return __global_dimension;
15747
/// Return the dimension of the local finite element function space for a cell
15748
unsigned int cahnhilliard2d_1_dof_map_5::local_dimension(const ufc::cell& c) const
15753
/// Return the maximum dimension of the local finite element function space
15754
unsigned int cahnhilliard2d_1_dof_map_5::max_local_dimension() const
15759
// Return the geometric dimension of the coordinates this dof map provides
15760
unsigned int cahnhilliard2d_1_dof_map_5::geometric_dimension() const
15765
/// Return the number of dofs on each cell facet
15766
unsigned int cahnhilliard2d_1_dof_map_5::num_facet_dofs() const
15771
/// Return the number of dofs associated with each cell entity of dimension d
15772
unsigned int cahnhilliard2d_1_dof_map_5::num_entity_dofs(unsigned int d) const
15774
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15777
/// Tabulate the local-to-global mapping of dofs on a cell
15778
void cahnhilliard2d_1_dof_map_5::tabulate_dofs(unsigned int* dofs,
15779
const ufc::mesh& m,
15780
const ufc::cell& c) const
15782
dofs[0] = c.entity_indices[2][0];
15785
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15786
void cahnhilliard2d_1_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
15787
unsigned int facet) const
15803
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15804
void cahnhilliard2d_1_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
15805
unsigned int d, unsigned int i) const
15807
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15810
/// Tabulate the coordinates of all dofs on a cell
15811
void cahnhilliard2d_1_dof_map_5::tabulate_coordinates(double** coordinates,
15812
const ufc::cell& c) const
15814
const double * const * x = c.coordinates;
15815
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15816
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15819
/// Return the number of sub dof maps (for a mixed element)
15820
unsigned int cahnhilliard2d_1_dof_map_5::num_sub_dof_maps() const
15825
/// Create a new dof_map for sub dof map i (for a mixed element)
15826
ufc::dof_map* cahnhilliard2d_1_dof_map_5::create_sub_dof_map(unsigned int i) const
15828
return new cahnhilliard2d_1_dof_map_5();
15833
cahnhilliard2d_1_dof_map_6::cahnhilliard2d_1_dof_map_6() : ufc::dof_map()
15835
__global_dimension = 0;
15839
cahnhilliard2d_1_dof_map_6::~cahnhilliard2d_1_dof_map_6()
15844
/// Return a string identifying the dof map
15845
const char* cahnhilliard2d_1_dof_map_6::signature() const
15847
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15850
/// Return true iff mesh entities of topological dimension d are needed
15851
bool cahnhilliard2d_1_dof_map_6::needs_mesh_entities(unsigned int d) const
15868
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15869
bool cahnhilliard2d_1_dof_map_6::init_mesh(const ufc::mesh& m)
15871
__global_dimension = m.num_entities[2];
15875
/// Initialize dof map for given cell
15876
void cahnhilliard2d_1_dof_map_6::init_cell(const ufc::mesh& m,
15877
const ufc::cell& c)
15882
/// Finish initialization of dof map for cells
15883
void cahnhilliard2d_1_dof_map_6::init_cell_finalize()
15888
/// Return the dimension of the global finite element function space
15889
unsigned int cahnhilliard2d_1_dof_map_6::global_dimension() const
15891
return __global_dimension;
15894
/// Return the dimension of the local finite element function space for a cell
15895
unsigned int cahnhilliard2d_1_dof_map_6::local_dimension(const ufc::cell& c) const
15900
/// Return the maximum dimension of the local finite element function space
15901
unsigned int cahnhilliard2d_1_dof_map_6::max_local_dimension() const
15906
// Return the geometric dimension of the coordinates this dof map provides
15907
unsigned int cahnhilliard2d_1_dof_map_6::geometric_dimension() const
15912
/// Return the number of dofs on each cell facet
15913
unsigned int cahnhilliard2d_1_dof_map_6::num_facet_dofs() const
15918
/// Return the number of dofs associated with each cell entity of dimension d
15919
unsigned int cahnhilliard2d_1_dof_map_6::num_entity_dofs(unsigned int d) const
15921
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15924
/// Tabulate the local-to-global mapping of dofs on a cell
15925
void cahnhilliard2d_1_dof_map_6::tabulate_dofs(unsigned int* dofs,
15926
const ufc::mesh& m,
15927
const ufc::cell& c) const
15929
dofs[0] = c.entity_indices[2][0];
15932
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15933
void cahnhilliard2d_1_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
15934
unsigned int facet) const
15950
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15951
void cahnhilliard2d_1_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
15952
unsigned int d, unsigned int i) const
15954
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15957
/// Tabulate the coordinates of all dofs on a cell
15958
void cahnhilliard2d_1_dof_map_6::tabulate_coordinates(double** coordinates,
15959
const ufc::cell& c) const
15961
const double * const * x = c.coordinates;
15962
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15963
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15966
/// Return the number of sub dof maps (for a mixed element)
15967
unsigned int cahnhilliard2d_1_dof_map_6::num_sub_dof_maps() const
15972
/// Create a new dof_map for sub dof map i (for a mixed element)
15973
ufc::dof_map* cahnhilliard2d_1_dof_map_6::create_sub_dof_map(unsigned int i) const
15975
return new cahnhilliard2d_1_dof_map_6();
15980
cahnhilliard2d_1_cell_integral_0_quadrature::cahnhilliard2d_1_cell_integral_0_quadrature() : ufc::cell_integral()
15986
cahnhilliard2d_1_cell_integral_0_quadrature::~cahnhilliard2d_1_cell_integral_0_quadrature()
15753
15988
// Do nothing
15756
15991
/// Tabulate the tensor for the contribution from a local cell
15757
void UFC_CahnHilliard2DLinearForm_cell_integral_0::tabulate_tensor(double* A,
15992
void cahnhilliard2d_1_cell_integral_0_quadrature::tabulate_tensor(double* A,
15758
15993
const double * const * w,
15759
15994
const ufc::cell& c) const