1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.7.0.
11
/// This class defines the interface for a finite element.
13
class equation_0_finite_element_0: public ufc::finite_element
18
equation_0_finite_element_0() : ufc::finite_element()
24
virtual ~equation_0_finite_element_0()
29
/// Return a string identifying the finite element
30
virtual const char* signature() const
32
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
35
/// Return the cell shape
36
virtual ufc::shape cell_shape() const
41
/// Return the dimension of the finite element function space
42
virtual unsigned int space_dimension() const
47
/// Return the rank of the value space
48
virtual unsigned int value_rank() const
53
/// Return the dimension of the value space for axis i
54
virtual unsigned int value_dimension(unsigned int i) const
59
/// Evaluate basis function i at given point in cell
60
virtual void evaluate_basis(unsigned int i,
62
const double* coordinates,
63
const ufc::cell& c) const
65
// Extract vertex coordinates
66
const double * const * element_coordinates = c.coordinates;
68
// Compute Jacobian of affine map from reference cell
69
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
70
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
71
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
72
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
74
// Compute determinant of Jacobian
75
const double detJ = J_00*J_11 - J_01*J_10;
77
// Compute inverse of Jacobian
79
// Get coordinates and map to the reference (UFC) element
80
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
81
element_coordinates[0][0]*element_coordinates[2][1] +\
82
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
83
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
84
element_coordinates[1][0]*element_coordinates[0][1] -\
85
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
87
// Map coordinates to the reference square
88
if (std::abs(y - 1.0) < 1e-08)
91
x = 2.0 *x/(1.0 - y) - 1.0;
97
// Map degree of freedom to element degree of freedom
98
const unsigned int dof = i;
101
const double scalings_y_0 = 1;
102
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
104
// Compute psitilde_a
105
const double psitilde_a_0 = 1;
106
const double psitilde_a_1 = x;
108
// Compute psitilde_bs
109
const double psitilde_bs_0_0 = 1;
110
const double psitilde_bs_0_1 = 1.5*y + 0.5;
111
const double psitilde_bs_1_0 = 1;
113
// Compute basisvalues
114
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
115
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
116
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
118
// Table(s) of coefficients
119
static const double coefficients0[3][3] = \
120
{{0.471404521, -0.288675135, -0.166666667},
121
{0.471404521, 0.288675135, -0.166666667},
122
{0.471404521, 0, 0.333333333}};
124
// Extract relevant coefficients
125
const double coeff0_0 = coefficients0[dof][0];
126
const double coeff0_1 = coefficients0[dof][1];
127
const double coeff0_2 = coefficients0[dof][2];
130
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
133
/// Evaluate all basis functions at given point in cell
134
virtual void evaluate_basis_all(double* values,
135
const double* coordinates,
136
const ufc::cell& c) const
138
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
141
/// Evaluate order n derivatives of basis function i at given point in cell
142
virtual void evaluate_basis_derivatives(unsigned int i,
145
const double* coordinates,
146
const ufc::cell& c) const
148
// Extract vertex coordinates
149
const double * const * element_coordinates = c.coordinates;
151
// Compute Jacobian of affine map from reference cell
152
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
153
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
154
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
155
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
157
// Compute determinant of Jacobian
158
const double detJ = J_00*J_11 - J_01*J_10;
160
// Compute inverse of Jacobian
162
// Get coordinates and map to the reference (UFC) element
163
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
164
element_coordinates[0][0]*element_coordinates[2][1] +\
165
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
166
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
167
element_coordinates[1][0]*element_coordinates[0][1] -\
168
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
170
// Map coordinates to the reference square
171
if (std::abs(y - 1.0) < 1e-08)
174
x = 2.0 *x/(1.0 - y) - 1.0;
177
// Compute number of derivatives
178
unsigned int num_derivatives = 1;
180
for (unsigned int j = 0; j < n; j++)
181
num_derivatives *= 2;
184
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
185
unsigned int **combinations = new unsigned int *[num_derivatives];
187
for (unsigned int j = 0; j < num_derivatives; j++)
189
combinations[j] = new unsigned int [n];
190
for (unsigned int k = 0; k < n; k++)
191
combinations[j][k] = 0;
194
// Generate combinations of derivatives
195
for (unsigned int row = 1; row < num_derivatives; row++)
197
for (unsigned int num = 0; num < row; num++)
199
for (unsigned int col = n-1; col+1 > 0; col--)
201
if (combinations[row][col] + 1 > 1)
202
combinations[row][col] = 0;
205
combinations[row][col] += 1;
212
// Compute inverse of Jacobian
213
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
215
// Declare transformation matrix
216
// Declare pointer to two dimensional array and initialise
217
double **transform = new double *[num_derivatives];
219
for (unsigned int j = 0; j < num_derivatives; j++)
221
transform[j] = new double [num_derivatives];
222
for (unsigned int k = 0; k < num_derivatives; k++)
226
// Construct transformation matrix
227
for (unsigned int row = 0; row < num_derivatives; row++)
229
for (unsigned int col = 0; col < num_derivatives; col++)
231
for (unsigned int k = 0; k < n; k++)
232
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
237
for (unsigned int j = 0; j < 1*num_derivatives; j++)
240
// Map degree of freedom to element degree of freedom
241
const unsigned int dof = i;
244
const double scalings_y_0 = 1;
245
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
247
// Compute psitilde_a
248
const double psitilde_a_0 = 1;
249
const double psitilde_a_1 = x;
251
// Compute psitilde_bs
252
const double psitilde_bs_0_0 = 1;
253
const double psitilde_bs_0_1 = 1.5*y + 0.5;
254
const double psitilde_bs_1_0 = 1;
256
// Compute basisvalues
257
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
258
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
259
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
261
// Table(s) of coefficients
262
static const double coefficients0[3][3] = \
263
{{0.471404521, -0.288675135, -0.166666667},
264
{0.471404521, 0.288675135, -0.166666667},
265
{0.471404521, 0, 0.333333333}};
267
// Interesting (new) part
268
// Tables of derivatives of the polynomial base (transpose)
269
static const double dmats0[3][3] = \
274
static const double dmats1[3][3] = \
279
// Compute reference derivatives
280
// Declare pointer to array of derivatives on FIAT element
281
double *derivatives = new double [num_derivatives];
283
// Declare coefficients
288
// Declare new coefficients
289
double new_coeff0_0 = 0;
290
double new_coeff0_1 = 0;
291
double new_coeff0_2 = 0;
293
// Loop possible derivatives
294
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
296
// Get values from coefficients array
297
new_coeff0_0 = coefficients0[dof][0];
298
new_coeff0_1 = coefficients0[dof][1];
299
new_coeff0_2 = coefficients0[dof][2];
301
// Loop derivative order
302
for (unsigned int j = 0; j < n; j++)
304
// Update old coefficients
305
coeff0_0 = new_coeff0_0;
306
coeff0_1 = new_coeff0_1;
307
coeff0_2 = new_coeff0_2;
309
if(combinations[deriv_num][j] == 0)
311
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
312
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
313
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
315
if(combinations[deriv_num][j] == 1)
317
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
318
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
319
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
323
// Compute derivatives on reference element as dot product of coefficients and basisvalues
324
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
327
// Transform derivatives back to physical element
328
for (unsigned int row = 0; row < num_derivatives; row++)
330
for (unsigned int col = 0; col < num_derivatives; col++)
332
values[row] += transform[row][col]*derivatives[col];
335
// Delete pointer to array of derivatives on FIAT element
336
delete [] derivatives;
338
// Delete pointer to array of combinations of derivatives and transform
339
for (unsigned int row = 0; row < num_derivatives; row++)
341
delete [] combinations[row];
342
delete [] transform[row];
345
delete [] combinations;
349
/// Evaluate order n derivatives of all basis functions at given point in cell
350
virtual void evaluate_basis_derivatives_all(unsigned int n,
352
const double* coordinates,
353
const ufc::cell& c) const
355
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
358
/// Evaluate linear functional for dof i on the function f
359
virtual double evaluate_dof(unsigned int i,
360
const ufc::function& f,
361
const ufc::cell& c) const
363
// The reference points, direction and weights:
364
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
365
static const double W[3][1] = {{1}, {1}, {1}};
366
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
368
const double * const * x = c.coordinates;
370
// Iterate over the points:
371
// Evaluate basis functions for affine mapping
372
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
373
const double w1 = X[i][0][0];
374
const double w2 = X[i][0][1];
376
// Compute affine mapping y = F(X)
378
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
379
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
381
// Evaluate function at physical points
383
f.evaluate(values, y, c);
385
// Map function values using appropriate mapping
386
// Affine map: Do nothing
388
// Note that we do not map the weights (yet).
390
// Take directional components
391
for(int k = 0; k < 1; k++)
392
result += values[k]*D[i][0][k];
393
// Multiply by weights
399
/// Evaluate linear functionals for all dofs on the function f
400
virtual void evaluate_dofs(double* values,
401
const ufc::function& f,
402
const ufc::cell& c) const
404
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
407
/// Interpolate vertex values from dof values
408
virtual void interpolate_vertex_values(double* vertex_values,
409
const double* dof_values,
410
const ufc::cell& c) const
412
// Evaluate at vertices and use affine mapping
413
vertex_values[0] = dof_values[0];
414
vertex_values[1] = dof_values[1];
415
vertex_values[2] = dof_values[2];
418
/// Return the number of sub elements (for a mixed element)
419
virtual unsigned int num_sub_elements() const
424
/// Create a new finite element for sub element i (for a mixed element)
425
virtual ufc::finite_element* create_sub_element(unsigned int i) const
427
return new equation_0_finite_element_0();
432
/// This class defines the interface for a finite element.
434
class equation_0_finite_element_1: public ufc::finite_element
439
equation_0_finite_element_1() : ufc::finite_element()
445
virtual ~equation_0_finite_element_1()
450
/// Return a string identifying the finite element
451
virtual const char* signature() const
453
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
456
/// Return the cell shape
457
virtual ufc::shape cell_shape() const
459
return ufc::triangle;
462
/// Return the dimension of the finite element function space
463
virtual unsigned int space_dimension() const
468
/// Return the rank of the value space
469
virtual unsigned int value_rank() const
474
/// Return the dimension of the value space for axis i
475
virtual unsigned int value_dimension(unsigned int i) const
480
/// Evaluate basis function i at given point in cell
481
virtual void evaluate_basis(unsigned int i,
483
const double* coordinates,
484
const ufc::cell& c) const
486
// Extract vertex coordinates
487
const double * const * element_coordinates = c.coordinates;
489
// Compute Jacobian of affine map from reference cell
490
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
491
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
492
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
493
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
495
// Compute determinant of Jacobian
496
const double detJ = J_00*J_11 - J_01*J_10;
498
// Compute inverse of Jacobian
500
// Get coordinates and map to the reference (UFC) element
501
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
502
element_coordinates[0][0]*element_coordinates[2][1] +\
503
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
504
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
505
element_coordinates[1][0]*element_coordinates[0][1] -\
506
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
508
// Map coordinates to the reference square
509
if (std::abs(y - 1.0) < 1e-08)
512
x = 2.0 *x/(1.0 - y) - 1.0;
518
// Map degree of freedom to element degree of freedom
519
const unsigned int dof = i;
522
const double scalings_y_0 = 1;
523
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
525
// Compute psitilde_a
526
const double psitilde_a_0 = 1;
527
const double psitilde_a_1 = x;
529
// Compute psitilde_bs
530
const double psitilde_bs_0_0 = 1;
531
const double psitilde_bs_0_1 = 1.5*y + 0.5;
532
const double psitilde_bs_1_0 = 1;
534
// Compute basisvalues
535
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
536
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
537
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
539
// Table(s) of coefficients
540
static const double coefficients0[3][3] = \
541
{{0.471404521, -0.288675135, -0.166666667},
542
{0.471404521, 0.288675135, -0.166666667},
543
{0.471404521, 0, 0.333333333}};
545
// Extract relevant coefficients
546
const double coeff0_0 = coefficients0[dof][0];
547
const double coeff0_1 = coefficients0[dof][1];
548
const double coeff0_2 = coefficients0[dof][2];
551
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
554
/// Evaluate all basis functions at given point in cell
555
virtual void evaluate_basis_all(double* values,
556
const double* coordinates,
557
const ufc::cell& c) const
559
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
562
/// Evaluate order n derivatives of basis function i at given point in cell
563
virtual void evaluate_basis_derivatives(unsigned int i,
566
const double* coordinates,
567
const ufc::cell& c) const
569
// Extract vertex coordinates
570
const double * const * element_coordinates = c.coordinates;
572
// Compute Jacobian of affine map from reference cell
573
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
574
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
575
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
576
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
578
// Compute determinant of Jacobian
579
const double detJ = J_00*J_11 - J_01*J_10;
581
// Compute inverse of Jacobian
583
// Get coordinates and map to the reference (UFC) element
584
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
585
element_coordinates[0][0]*element_coordinates[2][1] +\
586
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
587
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
588
element_coordinates[1][0]*element_coordinates[0][1] -\
589
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
591
// Map coordinates to the reference square
592
if (std::abs(y - 1.0) < 1e-08)
595
x = 2.0 *x/(1.0 - y) - 1.0;
598
// Compute number of derivatives
599
unsigned int num_derivatives = 1;
601
for (unsigned int j = 0; j < n; j++)
602
num_derivatives *= 2;
605
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
606
unsigned int **combinations = new unsigned int *[num_derivatives];
608
for (unsigned int j = 0; j < num_derivatives; j++)
610
combinations[j] = new unsigned int [n];
611
for (unsigned int k = 0; k < n; k++)
612
combinations[j][k] = 0;
615
// Generate combinations of derivatives
616
for (unsigned int row = 1; row < num_derivatives; row++)
618
for (unsigned int num = 0; num < row; num++)
620
for (unsigned int col = n-1; col+1 > 0; col--)
622
if (combinations[row][col] + 1 > 1)
623
combinations[row][col] = 0;
626
combinations[row][col] += 1;
633
// Compute inverse of Jacobian
634
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
636
// Declare transformation matrix
637
// Declare pointer to two dimensional array and initialise
638
double **transform = new double *[num_derivatives];
640
for (unsigned int j = 0; j < num_derivatives; j++)
642
transform[j] = new double [num_derivatives];
643
for (unsigned int k = 0; k < num_derivatives; k++)
647
// Construct transformation matrix
648
for (unsigned int row = 0; row < num_derivatives; row++)
650
for (unsigned int col = 0; col < num_derivatives; col++)
652
for (unsigned int k = 0; k < n; k++)
653
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
658
for (unsigned int j = 0; j < 1*num_derivatives; j++)
661
// Map degree of freedom to element degree of freedom
662
const unsigned int dof = i;
665
const double scalings_y_0 = 1;
666
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
668
// Compute psitilde_a
669
const double psitilde_a_0 = 1;
670
const double psitilde_a_1 = x;
672
// Compute psitilde_bs
673
const double psitilde_bs_0_0 = 1;
674
const double psitilde_bs_0_1 = 1.5*y + 0.5;
675
const double psitilde_bs_1_0 = 1;
677
// Compute basisvalues
678
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
679
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
680
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
682
// Table(s) of coefficients
683
static const double coefficients0[3][3] = \
684
{{0.471404521, -0.288675135, -0.166666667},
685
{0.471404521, 0.288675135, -0.166666667},
686
{0.471404521, 0, 0.333333333}};
688
// Interesting (new) part
689
// Tables of derivatives of the polynomial base (transpose)
690
static const double dmats0[3][3] = \
695
static const double dmats1[3][3] = \
700
// Compute reference derivatives
701
// Declare pointer to array of derivatives on FIAT element
702
double *derivatives = new double [num_derivatives];
704
// Declare coefficients
709
// Declare new coefficients
710
double new_coeff0_0 = 0;
711
double new_coeff0_1 = 0;
712
double new_coeff0_2 = 0;
714
// Loop possible derivatives
715
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
717
// Get values from coefficients array
718
new_coeff0_0 = coefficients0[dof][0];
719
new_coeff0_1 = coefficients0[dof][1];
720
new_coeff0_2 = coefficients0[dof][2];
722
// Loop derivative order
723
for (unsigned int j = 0; j < n; j++)
725
// Update old coefficients
726
coeff0_0 = new_coeff0_0;
727
coeff0_1 = new_coeff0_1;
728
coeff0_2 = new_coeff0_2;
730
if(combinations[deriv_num][j] == 0)
732
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
733
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
734
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
736
if(combinations[deriv_num][j] == 1)
738
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
739
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
740
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
744
// Compute derivatives on reference element as dot product of coefficients and basisvalues
745
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
748
// Transform derivatives back to physical element
749
for (unsigned int row = 0; row < num_derivatives; row++)
751
for (unsigned int col = 0; col < num_derivatives; col++)
753
values[row] += transform[row][col]*derivatives[col];
756
// Delete pointer to array of derivatives on FIAT element
757
delete [] derivatives;
759
// Delete pointer to array of combinations of derivatives and transform
760
for (unsigned int row = 0; row < num_derivatives; row++)
762
delete [] combinations[row];
763
delete [] transform[row];
766
delete [] combinations;
770
/// Evaluate order n derivatives of all basis functions at given point in cell
771
virtual void evaluate_basis_derivatives_all(unsigned int n,
773
const double* coordinates,
774
const ufc::cell& c) const
776
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
779
/// Evaluate linear functional for dof i on the function f
780
virtual double evaluate_dof(unsigned int i,
781
const ufc::function& f,
782
const ufc::cell& c) const
784
// The reference points, direction and weights:
785
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
786
static const double W[3][1] = {{1}, {1}, {1}};
787
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
789
const double * const * x = c.coordinates;
791
// Iterate over the points:
792
// Evaluate basis functions for affine mapping
793
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
794
const double w1 = X[i][0][0];
795
const double w2 = X[i][0][1];
797
// Compute affine mapping y = F(X)
799
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
800
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
802
// Evaluate function at physical points
804
f.evaluate(values, y, c);
806
// Map function values using appropriate mapping
807
// Affine map: Do nothing
809
// Note that we do not map the weights (yet).
811
// Take directional components
812
for(int k = 0; k < 1; k++)
813
result += values[k]*D[i][0][k];
814
// Multiply by weights
820
/// Evaluate linear functionals for all dofs on the function f
821
virtual void evaluate_dofs(double* values,
822
const ufc::function& f,
823
const ufc::cell& c) const
825
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
828
/// Interpolate vertex values from dof values
829
virtual void interpolate_vertex_values(double* vertex_values,
830
const double* dof_values,
831
const ufc::cell& c) const
833
// Evaluate at vertices and use affine mapping
834
vertex_values[0] = dof_values[0];
835
vertex_values[1] = dof_values[1];
836
vertex_values[2] = dof_values[2];
839
/// Return the number of sub elements (for a mixed element)
840
virtual unsigned int num_sub_elements() const
845
/// Create a new finite element for sub element i (for a mixed element)
846
virtual ufc::finite_element* create_sub_element(unsigned int i) const
848
return new equation_0_finite_element_1();
853
/// This class defines the interface for a local-to-global mapping of
854
/// degrees of freedom (dofs).
856
class equation_0_dof_map_0: public ufc::dof_map
860
unsigned int __global_dimension;
865
equation_0_dof_map_0() : ufc::dof_map()
867
__global_dimension = 0;
871
virtual ~equation_0_dof_map_0()
876
/// Return a string identifying the dof map
877
virtual const char* signature() const
879
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
882
/// Return true iff mesh entities of topological dimension d are needed
883
virtual bool needs_mesh_entities(unsigned int d) const
900
/// Initialize dof map for mesh (return true iff init_cell() is needed)
901
virtual bool init_mesh(const ufc::mesh& m)
903
__global_dimension = m.num_entities[0];
907
/// Initialize dof map for given cell
908
virtual void init_cell(const ufc::mesh& m,
914
/// Finish initialization of dof map for cells
915
virtual void init_cell_finalize()
920
/// Return the dimension of the global finite element function space
921
virtual unsigned int global_dimension() const
923
return __global_dimension;
926
/// Return the dimension of the local finite element function space for a cell
927
virtual unsigned int local_dimension(const ufc::cell& c) const
932
/// Return the maximum dimension of the local finite element function space
933
virtual unsigned int max_local_dimension() const
938
// Return the geometric dimension of the coordinates this dof map provides
939
virtual unsigned int geometric_dimension() const
944
/// Return the number of dofs on each cell facet
945
virtual unsigned int num_facet_dofs() const
950
/// Return the number of dofs associated with each cell entity of dimension d
951
virtual unsigned int num_entity_dofs(unsigned int d) const
953
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
956
/// Tabulate the local-to-global mapping of dofs on a cell
957
virtual void tabulate_dofs(unsigned int* dofs,
959
const ufc::cell& c) const
961
dofs[0] = c.entity_indices[0][0];
962
dofs[1] = c.entity_indices[0][1];
963
dofs[2] = c.entity_indices[0][2];
966
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
967
virtual void tabulate_facet_dofs(unsigned int* dofs,
968
unsigned int facet) const
987
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
988
virtual void tabulate_entity_dofs(unsigned int* dofs,
989
unsigned int d, unsigned int i) const
991
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
994
/// Tabulate the coordinates of all dofs on a cell
995
virtual void tabulate_coordinates(double** coordinates,
996
const ufc::cell& c) const
998
const double * const * x = c.coordinates;
999
coordinates[0][0] = x[0][0];
1000
coordinates[0][1] = x[0][1];
1001
coordinates[1][0] = x[1][0];
1002
coordinates[1][1] = x[1][1];
1003
coordinates[2][0] = x[2][0];
1004
coordinates[2][1] = x[2][1];
1007
/// Return the number of sub dof maps (for a mixed element)
1008
virtual unsigned int num_sub_dof_maps() const
1013
/// Create a new dof_map for sub dof map i (for a mixed element)
1014
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1016
return new equation_0_dof_map_0();
1021
/// This class defines the interface for a local-to-global mapping of
1022
/// degrees of freedom (dofs).
1024
class equation_0_dof_map_1: public ufc::dof_map
1028
unsigned int __global_dimension;
1033
equation_0_dof_map_1() : ufc::dof_map()
1035
__global_dimension = 0;
1039
virtual ~equation_0_dof_map_1()
1044
/// Return a string identifying the dof map
1045
virtual const char* signature() const
1047
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
1050
/// Return true iff mesh entities of topological dimension d are needed
1051
virtual bool needs_mesh_entities(unsigned int d) const
1068
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1069
virtual bool init_mesh(const ufc::mesh& m)
1071
__global_dimension = m.num_entities[0];
1075
/// Initialize dof map for given cell
1076
virtual void init_cell(const ufc::mesh& m,
1082
/// Finish initialization of dof map for cells
1083
virtual void init_cell_finalize()
1088
/// Return the dimension of the global finite element function space
1089
virtual unsigned int global_dimension() const
1091
return __global_dimension;
1094
/// Return the dimension of the local finite element function space for a cell
1095
virtual unsigned int local_dimension(const ufc::cell& c) const
1100
/// Return the maximum dimension of the local finite element function space
1101
virtual unsigned int max_local_dimension() const
1106
// Return the geometric dimension of the coordinates this dof map provides
1107
virtual unsigned int geometric_dimension() const
1112
/// Return the number of dofs on each cell facet
1113
virtual unsigned int num_facet_dofs() const
1118
/// Return the number of dofs associated with each cell entity of dimension d
1119
virtual unsigned int num_entity_dofs(unsigned int d) const
1121
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1124
/// Tabulate the local-to-global mapping of dofs on a cell
1125
virtual void tabulate_dofs(unsigned int* dofs,
1127
const ufc::cell& c) const
1129
dofs[0] = c.entity_indices[0][0];
1130
dofs[1] = c.entity_indices[0][1];
1131
dofs[2] = c.entity_indices[0][2];
1134
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1135
virtual void tabulate_facet_dofs(unsigned int* dofs,
1136
unsigned int facet) const
1155
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1156
virtual void tabulate_entity_dofs(unsigned int* dofs,
1157
unsigned int d, unsigned int i) const
1159
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1162
/// Tabulate the coordinates of all dofs on a cell
1163
virtual void tabulate_coordinates(double** coordinates,
1164
const ufc::cell& c) const
1166
const double * const * x = c.coordinates;
1167
coordinates[0][0] = x[0][0];
1168
coordinates[0][1] = x[0][1];
1169
coordinates[1][0] = x[1][0];
1170
coordinates[1][1] = x[1][1];
1171
coordinates[2][0] = x[2][0];
1172
coordinates[2][1] = x[2][1];
1175
/// Return the number of sub dof maps (for a mixed element)
1176
virtual unsigned int num_sub_dof_maps() const
1181
/// Create a new dof_map for sub dof map i (for a mixed element)
1182
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1184
return new equation_0_dof_map_1();
1189
/// This class defines the interface for the tabulation of the cell
1190
/// tensor corresponding to the local contribution to a form from
1191
/// the integral over a cell.
1193
class equation_0_cell_integral_0_quadrature: public ufc::cell_integral
1198
equation_0_cell_integral_0_quadrature() : ufc::cell_integral()
1204
virtual ~equation_0_cell_integral_0_quadrature()
1209
/// Tabulate the tensor for the contribution from a local cell
1210
virtual void tabulate_tensor(double* A,
1211
const double * const * w,
1212
const ufc::cell& c) const
1214
// Extract vertex coordinates
1215
const double * const * x = c.coordinates;
1217
// Compute Jacobian of affine map from reference cell
1218
const double J_00 = x[1][0] - x[0][0];
1219
const double J_01 = x[2][0] - x[0][0];
1220
const double J_10 = x[1][1] - x[0][1];
1221
const double J_11 = x[2][1] - x[0][1];
1223
// Compute determinant of Jacobian
1224
double detJ = J_00*J_11 - J_01*J_10;
1226
// Compute inverse of Jacobian
1227
const double Jinv_00 = J_11 / detJ;
1228
const double Jinv_01 = -J_01 / detJ;
1229
const double Jinv_10 = -J_10 / detJ;
1230
const double Jinv_11 = J_00 / detJ;
1233
const double det = std::abs(detJ);
1236
// Array of quadrature weights
1237
static const double W4[4] = {0.159020691, 0.0909793091, 0.159020691, 0.0909793091};
1238
// Quadrature points on the UFC reference element: (0.178558728, 0.155051026), (0.0750311102, 0.644948974), (0.666390246, 0.155051026), (0.280019915, 0.644948974)
1240
// Value of basis functions at quadrature points.
1241
static const double FE0[4][3] = \
1242
{{0.666390246, 0.178558728, 0.155051026},
1243
{0.280019915, 0.0750311102, 0.644948974},
1244
{0.178558728, 0.666390246, 0.155051026},
1245
{0.0750311102, 0.280019915, 0.644948974}};
1247
static const double FE0_D01[4][3] = \
1253
static const double FE0_D10[4][3] = \
1260
// Compute element tensor using UFL quadrature representation
1261
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
1262
// Total number of operations to compute element tensor: 828
1264
// Loop quadrature points for integral
1265
// Number of operations to compute element tensor for following IP loop = 828
1266
for (unsigned int ip = 0; ip < 4; ip++)
1269
// Number of operations for primary indices: 207
1270
for (unsigned int j = 0; j < 3; j++)
1272
for (unsigned int k = 0; k < 3; k++)
1274
// Number of operations to compute entry: 23
1275
A[j*3 + k] += (FE0[ip][j]*FE0[ip][k] + ((Jinv_00*FE0_D10[ip][k] + Jinv_10*FE0_D01[ip][k])*0.5*(Jinv_00*FE0_D10[ip][j] + Jinv_10*FE0_D01[ip][j]) + (Jinv_01*FE0_D10[ip][k] + Jinv_11*FE0_D01[ip][k])*0.5*(Jinv_01*FE0_D10[ip][j] + Jinv_11*FE0_D01[ip][j]))*0.1)*W4[ip]*det;
1276
}// end loop over 'k'
1277
}// end loop over 'j'
1278
}// end loop over 'ip'
1283
/// This class defines the interface for the tabulation of the cell
1284
/// tensor corresponding to the local contribution to a form from
1285
/// the integral over a cell.
1287
class equation_0_cell_integral_0: public ufc::cell_integral
1291
equation_0_cell_integral_0_quadrature integral_0_quadrature;
1296
equation_0_cell_integral_0() : ufc::cell_integral()
1302
virtual ~equation_0_cell_integral_0()
1307
/// Tabulate the tensor for the contribution from a local cell
1308
virtual void tabulate_tensor(double* A,
1309
const double * const * w,
1310
const ufc::cell& c) const
1312
// Reset values of the element tensor block
1313
for (unsigned int j = 0; j < 9; j++)
1316
// Add all contributions to element tensor
1317
integral_0_quadrature.tabulate_tensor(A, w, c);
1322
/// This class defines the interface for the assembly of the global
1323
/// tensor corresponding to a form with r + n arguments, that is, a
1326
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
1328
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
1329
/// global tensor A is defined by
1331
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
1333
/// where each argument Vj represents the application to the
1334
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
1335
/// fixed functions (coefficients).
1337
class equation_form_0: public ufc::form
1342
equation_form_0() : ufc::form()
1348
virtual ~equation_form_0()
1353
/// Return a string identifying the form
1354
virtual const char* signature() const
1356
return "Form([Integral(Sum(Product(BasisFunction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0), BasisFunction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 1)), Product(FloatValue(0.10000000000000001, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(Product(FloatValue(0.5, (), (), {}), SpatialDerivative(BasisFunction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 1), MultiIndex((Index(0),), {Index(0): 2}))), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2})))), Measure('cell', 0, None))])";
1359
/// Return the rank of the global tensor (r)
1360
virtual unsigned int rank() const
1365
/// Return the number of coefficients (n)
1366
virtual unsigned int num_coefficients() const
1371
/// Return the number of cell integrals
1372
virtual unsigned int num_cell_integrals() const
1377
/// Return the number of exterior facet integrals
1378
virtual unsigned int num_exterior_facet_integrals() const
1383
/// Return the number of interior facet integrals
1384
virtual unsigned int num_interior_facet_integrals() const
1389
/// Create a new finite element for argument function i
1390
virtual ufc::finite_element* create_finite_element(unsigned int i) const
1395
return new equation_0_finite_element_0();
1398
return new equation_0_finite_element_1();
1404
/// Create a new dof map for argument function i
1405
virtual ufc::dof_map* create_dof_map(unsigned int i) const
1410
return new equation_0_dof_map_0();
1413
return new equation_0_dof_map_1();
1419
/// Create a new cell integral on sub domain i
1420
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
1422
return new equation_0_cell_integral_0();
1425
/// Create a new exterior facet integral on sub domain i
1426
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
1431
/// Create a new interior facet integral on sub domain i
1432
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
1439
/// This class defines the interface for a finite element.
1441
class equation_1_finite_element_0: public ufc::finite_element
1446
equation_1_finite_element_0() : ufc::finite_element()
1452
virtual ~equation_1_finite_element_0()
1457
/// Return a string identifying the finite element
1458
virtual const char* signature() const
1460
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
1463
/// Return the cell shape
1464
virtual ufc::shape cell_shape() const
1466
return ufc::triangle;
1469
/// Return the dimension of the finite element function space
1470
virtual unsigned int space_dimension() const
1475
/// Return the rank of the value space
1476
virtual unsigned int value_rank() const
1481
/// Return the dimension of the value space for axis i
1482
virtual unsigned int value_dimension(unsigned int i) const
1487
/// Evaluate basis function i at given point in cell
1488
virtual void evaluate_basis(unsigned int i,
1490
const double* coordinates,
1491
const ufc::cell& c) const
1493
// Extract vertex coordinates
1494
const double * const * element_coordinates = c.coordinates;
1496
// Compute Jacobian of affine map from reference cell
1497
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1498
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1499
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1500
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1502
// Compute determinant of Jacobian
1503
const double detJ = J_00*J_11 - J_01*J_10;
1505
// Compute inverse of Jacobian
1507
// Get coordinates and map to the reference (UFC) element
1508
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1509
element_coordinates[0][0]*element_coordinates[2][1] +\
1510
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1511
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1512
element_coordinates[1][0]*element_coordinates[0][1] -\
1513
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1515
// Map coordinates to the reference square
1516
if (std::abs(y - 1.0) < 1e-08)
1519
x = 2.0 *x/(1.0 - y) - 1.0;
1525
// Map degree of freedom to element degree of freedom
1526
const unsigned int dof = i;
1528
// Generate scalings
1529
const double scalings_y_0 = 1;
1530
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1532
// Compute psitilde_a
1533
const double psitilde_a_0 = 1;
1534
const double psitilde_a_1 = x;
1536
// Compute psitilde_bs
1537
const double psitilde_bs_0_0 = 1;
1538
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1539
const double psitilde_bs_1_0 = 1;
1541
// Compute basisvalues
1542
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1543
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1544
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1546
// Table(s) of coefficients
1547
static const double coefficients0[3][3] = \
1548
{{0.471404521, -0.288675135, -0.166666667},
1549
{0.471404521, 0.288675135, -0.166666667},
1550
{0.471404521, 0, 0.333333333}};
1552
// Extract relevant coefficients
1553
const double coeff0_0 = coefficients0[dof][0];
1554
const double coeff0_1 = coefficients0[dof][1];
1555
const double coeff0_2 = coefficients0[dof][2];
1558
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1561
/// Evaluate all basis functions at given point in cell
1562
virtual void evaluate_basis_all(double* values,
1563
const double* coordinates,
1564
const ufc::cell& c) const
1566
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1569
/// Evaluate order n derivatives of basis function i at given point in cell
1570
virtual void evaluate_basis_derivatives(unsigned int i,
1573
const double* coordinates,
1574
const ufc::cell& c) const
1576
// Extract vertex coordinates
1577
const double * const * element_coordinates = c.coordinates;
1579
// Compute Jacobian of affine map from reference cell
1580
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1581
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1582
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1583
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1585
// Compute determinant of Jacobian
1586
const double detJ = J_00*J_11 - J_01*J_10;
1588
// Compute inverse of Jacobian
1590
// Get coordinates and map to the reference (UFC) element
1591
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1592
element_coordinates[0][0]*element_coordinates[2][1] +\
1593
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1594
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1595
element_coordinates[1][0]*element_coordinates[0][1] -\
1596
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1598
// Map coordinates to the reference square
1599
if (std::abs(y - 1.0) < 1e-08)
1602
x = 2.0 *x/(1.0 - y) - 1.0;
1605
// Compute number of derivatives
1606
unsigned int num_derivatives = 1;
1608
for (unsigned int j = 0; j < n; j++)
1609
num_derivatives *= 2;
1612
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1613
unsigned int **combinations = new unsigned int *[num_derivatives];
1615
for (unsigned int j = 0; j < num_derivatives; j++)
1617
combinations[j] = new unsigned int [n];
1618
for (unsigned int k = 0; k < n; k++)
1619
combinations[j][k] = 0;
1622
// Generate combinations of derivatives
1623
for (unsigned int row = 1; row < num_derivatives; row++)
1625
for (unsigned int num = 0; num < row; num++)
1627
for (unsigned int col = n-1; col+1 > 0; col--)
1629
if (combinations[row][col] + 1 > 1)
1630
combinations[row][col] = 0;
1633
combinations[row][col] += 1;
1640
// Compute inverse of Jacobian
1641
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1643
// Declare transformation matrix
1644
// Declare pointer to two dimensional array and initialise
1645
double **transform = new double *[num_derivatives];
1647
for (unsigned int j = 0; j < num_derivatives; j++)
1649
transform[j] = new double [num_derivatives];
1650
for (unsigned int k = 0; k < num_derivatives; k++)
1651
transform[j][k] = 1;
1654
// Construct transformation matrix
1655
for (unsigned int row = 0; row < num_derivatives; row++)
1657
for (unsigned int col = 0; col < num_derivatives; col++)
1659
for (unsigned int k = 0; k < n; k++)
1660
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1665
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1668
// Map degree of freedom to element degree of freedom
1669
const unsigned int dof = i;
1671
// Generate scalings
1672
const double scalings_y_0 = 1;
1673
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1675
// Compute psitilde_a
1676
const double psitilde_a_0 = 1;
1677
const double psitilde_a_1 = x;
1679
// Compute psitilde_bs
1680
const double psitilde_bs_0_0 = 1;
1681
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1682
const double psitilde_bs_1_0 = 1;
1684
// Compute basisvalues
1685
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1686
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1687
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1689
// Table(s) of coefficients
1690
static const double coefficients0[3][3] = \
1691
{{0.471404521, -0.288675135, -0.166666667},
1692
{0.471404521, 0.288675135, -0.166666667},
1693
{0.471404521, 0, 0.333333333}};
1695
// Interesting (new) part
1696
// Tables of derivatives of the polynomial base (transpose)
1697
static const double dmats0[3][3] = \
1702
static const double dmats1[3][3] = \
1705
{4.24264069, 0, 0}};
1707
// Compute reference derivatives
1708
// Declare pointer to array of derivatives on FIAT element
1709
double *derivatives = new double [num_derivatives];
1711
// Declare coefficients
1712
double coeff0_0 = 0;
1713
double coeff0_1 = 0;
1714
double coeff0_2 = 0;
1716
// Declare new coefficients
1717
double new_coeff0_0 = 0;
1718
double new_coeff0_1 = 0;
1719
double new_coeff0_2 = 0;
1721
// Loop possible derivatives
1722
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1724
// Get values from coefficients array
1725
new_coeff0_0 = coefficients0[dof][0];
1726
new_coeff0_1 = coefficients0[dof][1];
1727
new_coeff0_2 = coefficients0[dof][2];
1729
// Loop derivative order
1730
for (unsigned int j = 0; j < n; j++)
1732
// Update old coefficients
1733
coeff0_0 = new_coeff0_0;
1734
coeff0_1 = new_coeff0_1;
1735
coeff0_2 = new_coeff0_2;
1737
if(combinations[deriv_num][j] == 0)
1739
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1740
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1741
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1743
if(combinations[deriv_num][j] == 1)
1745
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1746
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1747
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1751
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1752
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1755
// Transform derivatives back to physical element
1756
for (unsigned int row = 0; row < num_derivatives; row++)
1758
for (unsigned int col = 0; col < num_derivatives; col++)
1760
values[row] += transform[row][col]*derivatives[col];
1763
// Delete pointer to array of derivatives on FIAT element
1764
delete [] derivatives;
1766
// Delete pointer to array of combinations of derivatives and transform
1767
for (unsigned int row = 0; row < num_derivatives; row++)
1769
delete [] combinations[row];
1770
delete [] transform[row];
1773
delete [] combinations;
1774
delete [] transform;
1777
/// Evaluate order n derivatives of all basis functions at given point in cell
1778
virtual void evaluate_basis_derivatives_all(unsigned int n,
1780
const double* coordinates,
1781
const ufc::cell& c) const
1783
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1786
/// Evaluate linear functional for dof i on the function f
1787
virtual double evaluate_dof(unsigned int i,
1788
const ufc::function& f,
1789
const ufc::cell& c) const
1791
// The reference points, direction and weights:
1792
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
1793
static const double W[3][1] = {{1}, {1}, {1}};
1794
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
1796
const double * const * x = c.coordinates;
1797
double result = 0.0;
1798
// Iterate over the points:
1799
// Evaluate basis functions for affine mapping
1800
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1801
const double w1 = X[i][0][0];
1802
const double w2 = X[i][0][1];
1804
// Compute affine mapping y = F(X)
1806
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1807
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1809
// Evaluate function at physical points
1811
f.evaluate(values, y, c);
1813
// Map function values using appropriate mapping
1814
// Affine map: Do nothing
1816
// Note that we do not map the weights (yet).
1818
// Take directional components
1819
for(int k = 0; k < 1; k++)
1820
result += values[k]*D[i][0][k];
1821
// Multiply by weights
1827
/// Evaluate linear functionals for all dofs on the function f
1828
virtual void evaluate_dofs(double* values,
1829
const ufc::function& f,
1830
const ufc::cell& c) const
1832
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1835
/// Interpolate vertex values from dof values
1836
virtual void interpolate_vertex_values(double* vertex_values,
1837
const double* dof_values,
1838
const ufc::cell& c) const
1840
// Evaluate at vertices and use affine mapping
1841
vertex_values[0] = dof_values[0];
1842
vertex_values[1] = dof_values[1];
1843
vertex_values[2] = dof_values[2];
1846
/// Return the number of sub elements (for a mixed element)
1847
virtual unsigned int num_sub_elements() const
1852
/// Create a new finite element for sub element i (for a mixed element)
1853
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1855
return new equation_1_finite_element_0();
1860
/// This class defines the interface for a finite element.
1862
class equation_1_finite_element_1: public ufc::finite_element
1867
equation_1_finite_element_1() : ufc::finite_element()
1873
virtual ~equation_1_finite_element_1()
1878
/// Return a string identifying the finite element
1879
virtual const char* signature() const
1881
return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
1884
/// Return the cell shape
1885
virtual ufc::shape cell_shape() const
1887
return ufc::triangle;
1890
/// Return the dimension of the finite element function space
1891
virtual unsigned int space_dimension() const
1896
/// Return the rank of the value space
1897
virtual unsigned int value_rank() const
1902
/// Return the dimension of the value space for axis i
1903
virtual unsigned int value_dimension(unsigned int i) const
1908
/// Evaluate basis function i at given point in cell
1909
virtual void evaluate_basis(unsigned int i,
1911
const double* coordinates,
1912
const ufc::cell& c) const
1914
// Extract vertex coordinates
1915
const double * const * element_coordinates = c.coordinates;
1917
// Compute Jacobian of affine map from reference cell
1918
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1919
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1920
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1921
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1923
// Compute determinant of Jacobian
1924
const double detJ = J_00*J_11 - J_01*J_10;
1926
// Compute inverse of Jacobian
1928
// Get coordinates and map to the reference (UFC) element
1929
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1930
element_coordinates[0][0]*element_coordinates[2][1] +\
1931
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1932
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1933
element_coordinates[1][0]*element_coordinates[0][1] -\
1934
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1936
// Map coordinates to the reference square
1937
if (std::abs(y - 1.0) < 1e-08)
1940
x = 2.0 *x/(1.0 - y) - 1.0;
1946
// Map degree of freedom to element degree of freedom
1947
const unsigned int dof = i;
1949
// Generate scalings
1950
const double scalings_y_0 = 1;
1951
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1953
// Compute psitilde_a
1954
const double psitilde_a_0 = 1;
1955
const double psitilde_a_1 = x;
1957
// Compute psitilde_bs
1958
const double psitilde_bs_0_0 = 1;
1959
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1960
const double psitilde_bs_1_0 = 1;
1962
// Compute basisvalues
1963
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1964
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1965
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1967
// Table(s) of coefficients
1968
static const double coefficients0[3][3] = \
1969
{{0.471404521, -0.288675135, -0.166666667},
1970
{0.471404521, 0.288675135, -0.166666667},
1971
{0.471404521, 0, 0.333333333}};
1973
// Extract relevant coefficients
1974
const double coeff0_0 = coefficients0[dof][0];
1975
const double coeff0_1 = coefficients0[dof][1];
1976
const double coeff0_2 = coefficients0[dof][2];
1979
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1982
/// Evaluate all basis functions at given point in cell
1983
virtual void evaluate_basis_all(double* values,
1984
const double* coordinates,
1985
const ufc::cell& c) const
1987
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1990
/// Evaluate order n derivatives of basis function i at given point in cell
1991
virtual void evaluate_basis_derivatives(unsigned int i,
1994
const double* coordinates,
1995
const ufc::cell& c) const
1997
// Extract vertex coordinates
1998
const double * const * element_coordinates = c.coordinates;
2000
// Compute Jacobian of affine map from reference cell
2001
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2002
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2003
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2004
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2006
// Compute determinant of Jacobian
2007
const double detJ = J_00*J_11 - J_01*J_10;
2009
// Compute inverse of Jacobian
2011
// Get coordinates and map to the reference (UFC) element
2012
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2013
element_coordinates[0][0]*element_coordinates[2][1] +\
2014
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2015
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2016
element_coordinates[1][0]*element_coordinates[0][1] -\
2017
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2019
// Map coordinates to the reference square
2020
if (std::abs(y - 1.0) < 1e-08)
2023
x = 2.0 *x/(1.0 - y) - 1.0;
2026
// Compute number of derivatives
2027
unsigned int num_derivatives = 1;
2029
for (unsigned int j = 0; j < n; j++)
2030
num_derivatives *= 2;
2033
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2034
unsigned int **combinations = new unsigned int *[num_derivatives];
2036
for (unsigned int j = 0; j < num_derivatives; j++)
2038
combinations[j] = new unsigned int [n];
2039
for (unsigned int k = 0; k < n; k++)
2040
combinations[j][k] = 0;
2043
// Generate combinations of derivatives
2044
for (unsigned int row = 1; row < num_derivatives; row++)
2046
for (unsigned int num = 0; num < row; num++)
2048
for (unsigned int col = n-1; col+1 > 0; col--)
2050
if (combinations[row][col] + 1 > 1)
2051
combinations[row][col] = 0;
2054
combinations[row][col] += 1;
2061
// Compute inverse of Jacobian
2062
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2064
// Declare transformation matrix
2065
// Declare pointer to two dimensional array and initialise
2066
double **transform = new double *[num_derivatives];
2068
for (unsigned int j = 0; j < num_derivatives; j++)
2070
transform[j] = new double [num_derivatives];
2071
for (unsigned int k = 0; k < num_derivatives; k++)
2072
transform[j][k] = 1;
2075
// Construct transformation matrix
2076
for (unsigned int row = 0; row < num_derivatives; row++)
2078
for (unsigned int col = 0; col < num_derivatives; col++)
2080
for (unsigned int k = 0; k < n; k++)
2081
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2086
for (unsigned int j = 0; j < 1*num_derivatives; j++)
2089
// Map degree of freedom to element degree of freedom
2090
const unsigned int dof = i;
2092
// Generate scalings
2093
const double scalings_y_0 = 1;
2094
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2096
// Compute psitilde_a
2097
const double psitilde_a_0 = 1;
2098
const double psitilde_a_1 = x;
2100
// Compute psitilde_bs
2101
const double psitilde_bs_0_0 = 1;
2102
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2103
const double psitilde_bs_1_0 = 1;
2105
// Compute basisvalues
2106
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2107
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2108
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2110
// Table(s) of coefficients
2111
static const double coefficients0[3][3] = \
2112
{{0.471404521, -0.288675135, -0.166666667},
2113
{0.471404521, 0.288675135, -0.166666667},
2114
{0.471404521, 0, 0.333333333}};
2116
// Interesting (new) part
2117
// Tables of derivatives of the polynomial base (transpose)
2118
static const double dmats0[3][3] = \
2123
static const double dmats1[3][3] = \
2126
{4.24264069, 0, 0}};
2128
// Compute reference derivatives
2129
// Declare pointer to array of derivatives on FIAT element
2130
double *derivatives = new double [num_derivatives];
2132
// Declare coefficients
2133
double coeff0_0 = 0;
2134
double coeff0_1 = 0;
2135
double coeff0_2 = 0;
2137
// Declare new coefficients
2138
double new_coeff0_0 = 0;
2139
double new_coeff0_1 = 0;
2140
double new_coeff0_2 = 0;
2142
// Loop possible derivatives
2143
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2145
// Get values from coefficients array
2146
new_coeff0_0 = coefficients0[dof][0];
2147
new_coeff0_1 = coefficients0[dof][1];
2148
new_coeff0_2 = coefficients0[dof][2];
2150
// Loop derivative order
2151
for (unsigned int j = 0; j < n; j++)
2153
// Update old coefficients
2154
coeff0_0 = new_coeff0_0;
2155
coeff0_1 = new_coeff0_1;
2156
coeff0_2 = new_coeff0_2;
2158
if(combinations[deriv_num][j] == 0)
2160
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2161
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2162
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2164
if(combinations[deriv_num][j] == 1)
2166
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2167
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2168
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2172
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2173
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2176
// Transform derivatives back to physical element
2177
for (unsigned int row = 0; row < num_derivatives; row++)
2179
for (unsigned int col = 0; col < num_derivatives; col++)
2181
values[row] += transform[row][col]*derivatives[col];
2184
// Delete pointer to array of derivatives on FIAT element
2185
delete [] derivatives;
2187
// Delete pointer to array of combinations of derivatives and transform
2188
for (unsigned int row = 0; row < num_derivatives; row++)
2190
delete [] combinations[row];
2191
delete [] transform[row];
2194
delete [] combinations;
2195
delete [] transform;
2198
/// Evaluate order n derivatives of all basis functions at given point in cell
2199
virtual void evaluate_basis_derivatives_all(unsigned int n,
2201
const double* coordinates,
2202
const ufc::cell& c) const
2204
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2207
/// Evaluate linear functional for dof i on the function f
2208
virtual double evaluate_dof(unsigned int i,
2209
const ufc::function& f,
2210
const ufc::cell& c) const
2212
// The reference points, direction and weights:
2213
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
2214
static const double W[3][1] = {{1}, {1}, {1}};
2215
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
2217
const double * const * x = c.coordinates;
2218
double result = 0.0;
2219
// Iterate over the points:
2220
// Evaluate basis functions for affine mapping
2221
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2222
const double w1 = X[i][0][0];
2223
const double w2 = X[i][0][1];
2225
// Compute affine mapping y = F(X)
2227
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2228
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2230
// Evaluate function at physical points
2232
f.evaluate(values, y, c);
2234
// Map function values using appropriate mapping
2235
// Affine map: Do nothing
2237
// Note that we do not map the weights (yet).
2239
// Take directional components
2240
for(int k = 0; k < 1; k++)
2241
result += values[k]*D[i][0][k];
2242
// Multiply by weights
2248
/// Evaluate linear functionals for all dofs on the function f
2249
virtual void evaluate_dofs(double* values,
2250
const ufc::function& f,
2251
const ufc::cell& c) const
2253
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2256
/// Interpolate vertex values from dof values
2257
virtual void interpolate_vertex_values(double* vertex_values,
2258
const double* dof_values,
2259
const ufc::cell& c) const
2261
// Evaluate at vertices and use affine mapping
2262
vertex_values[0] = dof_values[0];
2263
vertex_values[1] = dof_values[1];
2264
vertex_values[2] = dof_values[2];
2267
/// Return the number of sub elements (for a mixed element)
2268
virtual unsigned int num_sub_elements() const
2273
/// Create a new finite element for sub element i (for a mixed element)
2274
virtual ufc::finite_element* create_sub_element(unsigned int i) const
2276
return new equation_1_finite_element_1();
2281
/// This class defines the interface for a local-to-global mapping of
2282
/// degrees of freedom (dofs).
2284
class equation_1_dof_map_0: public ufc::dof_map
2288
unsigned int __global_dimension;
2293
equation_1_dof_map_0() : ufc::dof_map()
2295
__global_dimension = 0;
2299
virtual ~equation_1_dof_map_0()
2304
/// Return a string identifying the dof map
2305
virtual const char* signature() const
2307
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
2310
/// Return true iff mesh entities of topological dimension d are needed
2311
virtual bool needs_mesh_entities(unsigned int d) const
2328
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2329
virtual bool init_mesh(const ufc::mesh& m)
2331
__global_dimension = m.num_entities[0];
2335
/// Initialize dof map for given cell
2336
virtual void init_cell(const ufc::mesh& m,
2342
/// Finish initialization of dof map for cells
2343
virtual void init_cell_finalize()
2348
/// Return the dimension of the global finite element function space
2349
virtual unsigned int global_dimension() const
2351
return __global_dimension;
2354
/// Return the dimension of the local finite element function space for a cell
2355
virtual unsigned int local_dimension(const ufc::cell& c) const
2360
/// Return the maximum dimension of the local finite element function space
2361
virtual unsigned int max_local_dimension() const
2366
// Return the geometric dimension of the coordinates this dof map provides
2367
virtual unsigned int geometric_dimension() const
2372
/// Return the number of dofs on each cell facet
2373
virtual unsigned int num_facet_dofs() const
2378
/// Return the number of dofs associated with each cell entity of dimension d
2379
virtual unsigned int num_entity_dofs(unsigned int d) const
2381
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2384
/// Tabulate the local-to-global mapping of dofs on a cell
2385
virtual void tabulate_dofs(unsigned int* dofs,
2387
const ufc::cell& c) const
2389
dofs[0] = c.entity_indices[0][0];
2390
dofs[1] = c.entity_indices[0][1];
2391
dofs[2] = c.entity_indices[0][2];
2394
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2395
virtual void tabulate_facet_dofs(unsigned int* dofs,
2396
unsigned int facet) const
2415
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2416
virtual void tabulate_entity_dofs(unsigned int* dofs,
2417
unsigned int d, unsigned int i) const
2419
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2422
/// Tabulate the coordinates of all dofs on a cell
2423
virtual void tabulate_coordinates(double** coordinates,
2424
const ufc::cell& c) const
2426
const double * const * x = c.coordinates;
2427
coordinates[0][0] = x[0][0];
2428
coordinates[0][1] = x[0][1];
2429
coordinates[1][0] = x[1][0];
2430
coordinates[1][1] = x[1][1];
2431
coordinates[2][0] = x[2][0];
2432
coordinates[2][1] = x[2][1];
2435
/// Return the number of sub dof maps (for a mixed element)
2436
virtual unsigned int num_sub_dof_maps() const
2441
/// Create a new dof_map for sub dof map i (for a mixed element)
2442
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2444
return new equation_1_dof_map_0();
2449
/// This class defines the interface for a local-to-global mapping of
2450
/// degrees of freedom (dofs).
2452
class equation_1_dof_map_1: public ufc::dof_map
2456
unsigned int __global_dimension;
2461
equation_1_dof_map_1() : ufc::dof_map()
2463
__global_dimension = 0;
2467
virtual ~equation_1_dof_map_1()
2472
/// Return a string identifying the dof map
2473
virtual const char* signature() const
2475
return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
2478
/// Return true iff mesh entities of topological dimension d are needed
2479
virtual bool needs_mesh_entities(unsigned int d) const
2496
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2497
virtual bool init_mesh(const ufc::mesh& m)
2499
__global_dimension = m.num_entities[0];
2503
/// Initialize dof map for given cell
2504
virtual void init_cell(const ufc::mesh& m,
2510
/// Finish initialization of dof map for cells
2511
virtual void init_cell_finalize()
2516
/// Return the dimension of the global finite element function space
2517
virtual unsigned int global_dimension() const
2519
return __global_dimension;
2522
/// Return the dimension of the local finite element function space for a cell
2523
virtual unsigned int local_dimension(const ufc::cell& c) const
2528
/// Return the maximum dimension of the local finite element function space
2529
virtual unsigned int max_local_dimension() const
2534
// Return the geometric dimension of the coordinates this dof map provides
2535
virtual unsigned int geometric_dimension() const
2540
/// Return the number of dofs on each cell facet
2541
virtual unsigned int num_facet_dofs() const
2546
/// Return the number of dofs associated with each cell entity of dimension d
2547
virtual unsigned int num_entity_dofs(unsigned int d) const
2549
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2552
/// Tabulate the local-to-global mapping of dofs on a cell
2553
virtual void tabulate_dofs(unsigned int* dofs,
2555
const ufc::cell& c) const
2557
dofs[0] = c.entity_indices[0][0];
2558
dofs[1] = c.entity_indices[0][1];
2559
dofs[2] = c.entity_indices[0][2];
2562
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2563
virtual void tabulate_facet_dofs(unsigned int* dofs,
2564
unsigned int facet) const
2583
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2584
virtual void tabulate_entity_dofs(unsigned int* dofs,
2585
unsigned int d, unsigned int i) const
2587
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2590
/// Tabulate the coordinates of all dofs on a cell
2591
virtual void tabulate_coordinates(double** coordinates,
2592
const ufc::cell& c) const
2594
const double * const * x = c.coordinates;
2595
coordinates[0][0] = x[0][0];
2596
coordinates[0][1] = x[0][1];
2597
coordinates[1][0] = x[1][0];
2598
coordinates[1][1] = x[1][1];
2599
coordinates[2][0] = x[2][0];
2600
coordinates[2][1] = x[2][1];
2603
/// Return the number of sub dof maps (for a mixed element)
2604
virtual unsigned int num_sub_dof_maps() const
2609
/// Create a new dof_map for sub dof map i (for a mixed element)
2610
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2612
return new equation_1_dof_map_1();
2617
/// This class defines the interface for the tabulation of the cell
2618
/// tensor corresponding to the local contribution to a form from
2619
/// the integral over a cell.
2621
class equation_1_cell_integral_0_quadrature: public ufc::cell_integral
2626
equation_1_cell_integral_0_quadrature() : ufc::cell_integral()
2632
virtual ~equation_1_cell_integral_0_quadrature()
2637
/// Tabulate the tensor for the contribution from a local cell
2638
virtual void tabulate_tensor(double* A,
2639
const double * const * w,
2640
const ufc::cell& c) const
2642
// Extract vertex coordinates
2643
const double * const * x = c.coordinates;
2645
// Compute Jacobian of affine map from reference cell
2646
const double J_00 = x[1][0] - x[0][0];
2647
const double J_01 = x[2][0] - x[0][0];
2648
const double J_10 = x[1][1] - x[0][1];
2649
const double J_11 = x[2][1] - x[0][1];
2651
// Compute determinant of Jacobian
2652
double detJ = J_00*J_11 - J_01*J_10;
2654
// Compute inverse of Jacobian
2655
const double Jinv_00 = J_11 / detJ;
2656
const double Jinv_01 = -J_01 / detJ;
2657
const double Jinv_10 = -J_10 / detJ;
2658
const double Jinv_11 = J_00 / detJ;
2661
const double det = std::abs(detJ);
2664
// Array of quadrature weights
2665
static const double W4[4] = {0.159020691, 0.0909793091, 0.159020691, 0.0909793091};
2666
// Quadrature points on the UFC reference element: (0.178558728, 0.155051026), (0.0750311102, 0.644948974), (0.666390246, 0.155051026), (0.280019915, 0.644948974)
2668
// Value of basis functions at quadrature points.
2669
static const double FE0[4][3] = \
2670
{{0.666390246, 0.178558728, 0.155051026},
2671
{0.280019915, 0.0750311102, 0.644948974},
2672
{0.178558728, 0.666390246, 0.155051026},
2673
{0.0750311102, 0.280019915, 0.644948974}};
2675
static const double FE0_D01[4][3] = \
2681
static const double FE0_D10[4][3] = \
2688
// Compute element tensor using UFL quadrature representation
2689
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
2690
// Total number of operations to compute element tensor: 372
2692
// Loop quadrature points for integral
2693
// Number of operations to compute element tensor for following IP loop = 372
2694
for (unsigned int ip = 0; ip < 4; ip++)
2697
// Function declarations
2702
// Total number of operations to compute function values = 18
2703
for (unsigned int r = 0; r < 3; r++)
2705
F0 += FE0[ip][r]*w[0][r];
2706
F1 += FE0_D10[ip][r]*w[0][r];
2707
F2 += FE0_D01[ip][r]*w[0][r];
2708
}// end loop over 'r'
2710
// Number of operations for primary indices: 75
2711
for (unsigned int j = 0; j < 3; j++)
2713
// Number of operations to compute entry: 25
2714
A[j] += (FE0[ip][j]*-1*F0 + ((Jinv_00*FE0_D10[ip][j] + Jinv_10*FE0_D01[ip][j])*0.5*(Jinv_00*F1 + Jinv_10*F2) + (Jinv_01*FE0_D10[ip][j] + Jinv_11*FE0_D01[ip][j])*0.5*(Jinv_01*F1 + Jinv_11*F2))*0.1)*-1*W4[ip]*det;
2715
}// end loop over 'j'
2716
}// end loop over 'ip'
2721
/// This class defines the interface for the tabulation of the cell
2722
/// tensor corresponding to the local contribution to a form from
2723
/// the integral over a cell.
2725
class equation_1_cell_integral_0: public ufc::cell_integral
2729
equation_1_cell_integral_0_quadrature integral_0_quadrature;
2734
equation_1_cell_integral_0() : ufc::cell_integral()
2740
virtual ~equation_1_cell_integral_0()
2745
/// Tabulate the tensor for the contribution from a local cell
2746
virtual void tabulate_tensor(double* A,
2747
const double * const * w,
2748
const ufc::cell& c) const
2750
// Reset values of the element tensor block
2751
for (unsigned int j = 0; j < 3; j++)
2754
// Add all contributions to element tensor
2755
integral_0_quadrature.tabulate_tensor(A, w, c);
2760
/// This class defines the interface for the assembly of the global
2761
/// tensor corresponding to a form with r + n arguments, that is, a
2764
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2766
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2767
/// global tensor A is defined by
2769
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2771
/// where each argument Vj represents the application to the
2772
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2773
/// fixed functions (coefficients).
2775
class equation_form_1: public ufc::form
2780
equation_form_1() : ufc::form()
2786
virtual ~equation_form_1()
2791
/// Return a string identifying the form
2792
virtual const char* signature() const
2794
return "Form([Integral(Product(IntValue(-1, (), (), {}), Sum(Product(BasisFunction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0), Product(IntValue(-1, (), (), {}), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0))), Product(FloatValue(0.10000000000000001, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(Product(FloatValue(0.5, (), (), {}), SpatialDerivative(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(0),), {Index(0): 2}))), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2}))))), Measure('cell', 0, None))])";
2797
/// Return the rank of the global tensor (r)
2798
virtual unsigned int rank() const
2803
/// Return the number of coefficients (n)
2804
virtual unsigned int num_coefficients() const
2809
/// Return the number of cell integrals
2810
virtual unsigned int num_cell_integrals() const
2815
/// Return the number of exterior facet integrals
2816
virtual unsigned int num_exterior_facet_integrals() const
2821
/// Return the number of interior facet integrals
2822
virtual unsigned int num_interior_facet_integrals() const
2827
/// Create a new finite element for argument function i
2828
virtual ufc::finite_element* create_finite_element(unsigned int i) const
2833
return new equation_1_finite_element_0();
2836
return new equation_1_finite_element_1();
2842
/// Create a new dof map for argument function i
2843
virtual ufc::dof_map* create_dof_map(unsigned int i) const
2848
return new equation_1_dof_map_0();
2851
return new equation_1_dof_map_1();
2857
/// Create a new cell integral on sub domain i
2858
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
2860
return new equation_1_cell_integral_0();
2863
/// Create a new exterior facet integral on sub domain i
2864
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
2869
/// Create a new interior facet integral on sub domain i
2870
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const