1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.4.3.
4
// Warning: This code was generated with the option '-l dolfin'
5
// and contains DOLFIN-specific wrappers that depend on DOLFIN.
15
/// This class defines the interface for a finite element.
17
class UFC_LiftFunctional_finite_element_0: public ufc::finite_element
22
UFC_LiftFunctional_finite_element_0() : ufc::finite_element()
28
virtual ~UFC_LiftFunctional_finite_element_0()
33
/// Return a string identifying the finite element
34
virtual const char* signature() const
36
return "Lagrange finite element of degree 1 on a triangle";
39
/// Return the cell shape
40
virtual ufc::shape cell_shape() const
45
/// Return the dimension of the finite element function space
46
virtual unsigned int space_dimension() const
51
/// Return the rank of the value space
52
virtual unsigned int value_rank() const
57
/// Return the dimension of the value space for axis i
58
virtual unsigned int value_dimension(unsigned int i) const
63
/// Evaluate basis function i at given point in cell
64
virtual void evaluate_basis(unsigned int i,
66
const double* coordinates,
67
const ufc::cell& c) const
69
// Extract vertex coordinates
70
const double * const * element_coordinates = c.coordinates;
72
// Compute Jacobian of affine map from reference cell
73
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
74
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
75
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
76
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
78
// Compute determinant of Jacobian
79
const double detJ = J_00*J_11 - J_01*J_10;
81
// Compute inverse of Jacobian
83
// Get coordinates and map to the reference (UFC) element
84
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
85
element_coordinates[0][0]*element_coordinates[2][1] +\
86
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
87
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
88
element_coordinates[1][0]*element_coordinates[0][1] -\
89
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
91
// Map coordinates to the reference square
92
if (std::abs(y - 1.0) < 1e-14)
95
x = 2.0 *x/(1.0 - y) - 1.0;
101
// Map degree of freedom to element degree of freedom
102
const unsigned int dof = i;
105
const double scalings_y_0 = 1;
106
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
108
// Compute psitilde_a
109
const double psitilde_a_0 = 1;
110
const double psitilde_a_1 = x;
112
// Compute psitilde_bs
113
const double psitilde_bs_0_0 = 1;
114
const double psitilde_bs_0_1 = 1.5*y + 0.5;
115
const double psitilde_bs_1_0 = 1;
117
// Compute basisvalues
118
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
119
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
120
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
122
// Table(s) of coefficients
123
const static double coefficients0[3][3] = \
124
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
125
{0.471404520791032, 0.288675134594813, -0.166666666666667},
126
{0.471404520791032, 0, 0.333333333333333}};
128
// Extract relevant coefficients
129
const double coeff0_0 = coefficients0[dof][0];
130
const double coeff0_1 = coefficients0[dof][1];
131
const double coeff0_2 = coefficients0[dof][2];
134
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
137
/// Evaluate all basis functions at given point in cell
138
virtual void evaluate_basis_all(double* values,
139
const double* coordinates,
140
const ufc::cell& c) const
142
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
145
/// Evaluate order n derivatives of basis function i at given point in cell
146
virtual void evaluate_basis_derivatives(unsigned int i,
149
const double* coordinates,
150
const ufc::cell& c) const
152
// Extract vertex coordinates
153
const double * const * element_coordinates = c.coordinates;
155
// Compute Jacobian of affine map from reference cell
156
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
157
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
158
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
159
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
161
// Compute determinant of Jacobian
162
const double detJ = J_00*J_11 - J_01*J_10;
164
// Compute inverse of Jacobian
166
// Get coordinates and map to the reference (UFC) element
167
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
168
element_coordinates[0][0]*element_coordinates[2][1] +\
169
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
170
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
171
element_coordinates[1][0]*element_coordinates[0][1] -\
172
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
174
// Map coordinates to the reference square
175
if (std::abs(y - 1.0) < 1e-14)
178
x = 2.0 *x/(1.0 - y) - 1.0;
181
// Compute number of derivatives
182
unsigned int num_derivatives = 1;
184
for (unsigned int j = 0; j < n; j++)
185
num_derivatives *= 2;
188
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
189
unsigned int **combinations = new unsigned int *[num_derivatives];
191
for (unsigned int j = 0; j < num_derivatives; j++)
193
combinations[j] = new unsigned int [n];
194
for (unsigned int k = 0; k < n; k++)
195
combinations[j][k] = 0;
198
// Generate combinations of derivatives
199
for (unsigned int row = 1; row < num_derivatives; row++)
201
for (unsigned int num = 0; num < row; num++)
203
for (unsigned int col = n-1; col+1 > 0; col--)
205
if (combinations[row][col] + 1 > 1)
206
combinations[row][col] = 0;
209
combinations[row][col] += 1;
216
// Compute inverse of Jacobian
217
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
219
// Declare transformation matrix
220
// Declare pointer to two dimensional array and initialise
221
double **transform = new double *[num_derivatives];
223
for (unsigned int j = 0; j < num_derivatives; j++)
225
transform[j] = new double [num_derivatives];
226
for (unsigned int k = 0; k < num_derivatives; k++)
230
// Construct transformation matrix
231
for (unsigned int row = 0; row < num_derivatives; row++)
233
for (unsigned int col = 0; col < num_derivatives; col++)
235
for (unsigned int k = 0; k < n; k++)
236
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
241
for (unsigned int j = 0; j < 1*num_derivatives; j++)
244
// Map degree of freedom to element degree of freedom
245
const unsigned int dof = i;
248
const double scalings_y_0 = 1;
249
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
251
// Compute psitilde_a
252
const double psitilde_a_0 = 1;
253
const double psitilde_a_1 = x;
255
// Compute psitilde_bs
256
const double psitilde_bs_0_0 = 1;
257
const double psitilde_bs_0_1 = 1.5*y + 0.5;
258
const double psitilde_bs_1_0 = 1;
260
// Compute basisvalues
261
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
262
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
263
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
265
// Table(s) of coefficients
266
const static double coefficients0[3][3] = \
267
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
268
{0.471404520791032, 0.288675134594813, -0.166666666666667},
269
{0.471404520791032, 0, 0.333333333333333}};
271
// Interesting (new) part
272
// Tables of derivatives of the polynomial base (transpose)
273
const static double dmats0[3][3] = \
275
{4.89897948556636, 0, 0},
278
const static double dmats1[3][3] = \
280
{2.44948974278318, 0, 0},
281
{4.24264068711928, 0, 0}};
283
// Compute reference derivatives
284
// Declare pointer to array of derivatives on FIAT element
285
double *derivatives = new double [num_derivatives];
287
// Declare coefficients
292
// Declare new coefficients
293
double new_coeff0_0 = 0;
294
double new_coeff0_1 = 0;
295
double new_coeff0_2 = 0;
297
// Loop possible derivatives
298
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
300
// Get values from coefficients array
301
new_coeff0_0 = coefficients0[dof][0];
302
new_coeff0_1 = coefficients0[dof][1];
303
new_coeff0_2 = coefficients0[dof][2];
305
// Loop derivative order
306
for (unsigned int j = 0; j < n; j++)
308
// Update old coefficients
309
coeff0_0 = new_coeff0_0;
310
coeff0_1 = new_coeff0_1;
311
coeff0_2 = new_coeff0_2;
313
if(combinations[deriv_num][j] == 0)
315
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
316
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
317
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
319
if(combinations[deriv_num][j] == 1)
321
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
322
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
323
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
327
// Compute derivatives on reference element as dot product of coefficients and basisvalues
328
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
331
// Transform derivatives back to physical element
332
for (unsigned int row = 0; row < num_derivatives; row++)
334
for (unsigned int col = 0; col < num_derivatives; col++)
336
values[row] += transform[row][col]*derivatives[col];
339
// Delete pointer to array of derivatives on FIAT element
340
delete [] derivatives;
342
// Delete pointer to array of combinations of derivatives and transform
343
for (unsigned int row = 0; row < num_derivatives; row++)
345
delete [] combinations[row];
346
delete [] transform[row];
349
delete [] combinations;
353
/// Evaluate order n derivatives of all basis functions at given point in cell
354
virtual void evaluate_basis_derivatives_all(unsigned int n,
356
const double* coordinates,
357
const ufc::cell& c) const
359
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
362
/// Evaluate linear functional for dof i on the function f
363
virtual double evaluate_dof(unsigned int i,
364
const ufc::function& f,
365
const ufc::cell& c) const
367
// The reference points, direction and weights:
368
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
369
const static double W[3][1] = {{1}, {1}, {1}};
370
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
372
const double * const * x = c.coordinates;
374
// Iterate over the points:
375
// Evaluate basis functions for affine mapping
376
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
377
const double w1 = X[i][0][0];
378
const double w2 = X[i][0][1];
380
// Compute affine mapping y = F(X)
382
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
383
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
385
// Evaluate function at physical points
387
f.evaluate(values, y, c);
389
// Map function values using appropriate mapping
390
// Affine map: Do nothing
392
// Note that we do not map the weights (yet).
394
// Take directional components
395
for(int k = 0; k < 1; k++)
396
result += values[k]*D[i][0][k];
397
// Multiply by weights
403
/// Evaluate linear functionals for all dofs on the function f
404
virtual void evaluate_dofs(double* values,
405
const ufc::function& f,
406
const ufc::cell& c) const
408
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
411
/// Interpolate vertex values from dof values
412
virtual void interpolate_vertex_values(double* vertex_values,
413
const double* dof_values,
414
const ufc::cell& c) const
416
// Evaluate at vertices and use affine mapping
417
vertex_values[0] = dof_values[0];
418
vertex_values[1] = dof_values[1];
419
vertex_values[2] = dof_values[2];
422
/// Return the number of sub elements (for a mixed element)
423
virtual unsigned int num_sub_elements() const
428
/// Create a new finite element for sub element i (for a mixed element)
429
virtual ufc::finite_element* create_sub_element(unsigned int i) const
431
return new UFC_LiftFunctional_finite_element_0();
436
/// This class defines the interface for a finite element.
438
class UFC_LiftFunctional_finite_element_1_0: public ufc::finite_element
443
UFC_LiftFunctional_finite_element_1_0() : ufc::finite_element()
449
virtual ~UFC_LiftFunctional_finite_element_1_0()
454
/// Return a string identifying the finite element
455
virtual const char* signature() const
457
return "Discontinuous Lagrange finite element of degree 0 on a triangle";
460
/// Return the cell shape
461
virtual ufc::shape cell_shape() const
463
return ufc::triangle;
466
/// Return the dimension of the finite element function space
467
virtual unsigned int space_dimension() const
472
/// Return the rank of the value space
473
virtual unsigned int value_rank() const
478
/// Return the dimension of the value space for axis i
479
virtual unsigned int value_dimension(unsigned int i) const
484
/// Evaluate basis function i at given point in cell
485
virtual void evaluate_basis(unsigned int i,
487
const double* coordinates,
488
const ufc::cell& c) const
490
// Extract vertex coordinates
491
const double * const * element_coordinates = c.coordinates;
493
// Compute Jacobian of affine map from reference cell
494
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
495
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
496
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
497
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
499
// Compute determinant of Jacobian
500
const double detJ = J_00*J_11 - J_01*J_10;
502
// Compute inverse of Jacobian
504
// Get coordinates and map to the reference (UFC) element
505
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
506
element_coordinates[0][0]*element_coordinates[2][1] +\
507
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
508
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
509
element_coordinates[1][0]*element_coordinates[0][1] -\
510
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
512
// Map coordinates to the reference square
513
if (std::abs(y - 1.0) < 1e-14)
516
x = 2.0 *x/(1.0 - y) - 1.0;
522
// Map degree of freedom to element degree of freedom
523
const unsigned int dof = i;
526
const double scalings_y_0 = 1;
528
// Compute psitilde_a
529
const double psitilde_a_0 = 1;
531
// Compute psitilde_bs
532
const double psitilde_bs_0_0 = 1;
534
// Compute basisvalues
535
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
537
// Table(s) of coefficients
538
const static double coefficients0[1][1] = \
539
{{1.41421356237309}};
541
// Extract relevant coefficients
542
const double coeff0_0 = coefficients0[dof][0];
545
*values = coeff0_0*basisvalue0;
548
/// Evaluate all basis functions at given point in cell
549
virtual void evaluate_basis_all(double* values,
550
const double* coordinates,
551
const ufc::cell& c) const
553
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
556
/// Evaluate order n derivatives of basis function i at given point in cell
557
virtual void evaluate_basis_derivatives(unsigned int i,
560
const double* coordinates,
561
const ufc::cell& c) const
563
// Extract vertex coordinates
564
const double * const * element_coordinates = c.coordinates;
566
// Compute Jacobian of affine map from reference cell
567
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
568
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
569
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
570
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
572
// Compute determinant of Jacobian
573
const double detJ = J_00*J_11 - J_01*J_10;
575
// Compute inverse of Jacobian
577
// Get coordinates and map to the reference (UFC) element
578
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
579
element_coordinates[0][0]*element_coordinates[2][1] +\
580
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
581
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
582
element_coordinates[1][0]*element_coordinates[0][1] -\
583
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
585
// Map coordinates to the reference square
586
if (std::abs(y - 1.0) < 1e-14)
589
x = 2.0 *x/(1.0 - y) - 1.0;
592
// Compute number of derivatives
593
unsigned int num_derivatives = 1;
595
for (unsigned int j = 0; j < n; j++)
596
num_derivatives *= 2;
599
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
600
unsigned int **combinations = new unsigned int *[num_derivatives];
602
for (unsigned int j = 0; j < num_derivatives; j++)
604
combinations[j] = new unsigned int [n];
605
for (unsigned int k = 0; k < n; k++)
606
combinations[j][k] = 0;
609
// Generate combinations of derivatives
610
for (unsigned int row = 1; row < num_derivatives; row++)
612
for (unsigned int num = 0; num < row; num++)
614
for (unsigned int col = n-1; col+1 > 0; col--)
616
if (combinations[row][col] + 1 > 1)
617
combinations[row][col] = 0;
620
combinations[row][col] += 1;
627
// Compute inverse of Jacobian
628
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
630
// Declare transformation matrix
631
// Declare pointer to two dimensional array and initialise
632
double **transform = new double *[num_derivatives];
634
for (unsigned int j = 0; j < num_derivatives; j++)
636
transform[j] = new double [num_derivatives];
637
for (unsigned int k = 0; k < num_derivatives; k++)
641
// Construct transformation matrix
642
for (unsigned int row = 0; row < num_derivatives; row++)
644
for (unsigned int col = 0; col < num_derivatives; col++)
646
for (unsigned int k = 0; k < n; k++)
647
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
652
for (unsigned int j = 0; j < 1*num_derivatives; j++)
655
// Map degree of freedom to element degree of freedom
656
const unsigned int dof = i;
659
const double scalings_y_0 = 1;
661
// Compute psitilde_a
662
const double psitilde_a_0 = 1;
664
// Compute psitilde_bs
665
const double psitilde_bs_0_0 = 1;
667
// Compute basisvalues
668
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
670
// Table(s) of coefficients
671
const static double coefficients0[1][1] = \
672
{{1.41421356237309}};
674
// Interesting (new) part
675
// Tables of derivatives of the polynomial base (transpose)
676
const static double dmats0[1][1] = \
679
const static double dmats1[1][1] = \
682
// Compute reference derivatives
683
// Declare pointer to array of derivatives on FIAT element
684
double *derivatives = new double [num_derivatives];
686
// Declare coefficients
689
// Declare new coefficients
690
double new_coeff0_0 = 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];
698
// Loop derivative order
699
for (unsigned int j = 0; j < n; j++)
701
// Update old coefficients
702
coeff0_0 = new_coeff0_0;
704
if(combinations[deriv_num][j] == 0)
706
new_coeff0_0 = coeff0_0*dmats0[0][0];
708
if(combinations[deriv_num][j] == 1)
710
new_coeff0_0 = coeff0_0*dmats1[0][0];
714
// Compute derivatives on reference element as dot product of coefficients and basisvalues
715
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
718
// Transform derivatives back to physical element
719
for (unsigned int row = 0; row < num_derivatives; row++)
721
for (unsigned int col = 0; col < num_derivatives; col++)
723
values[row] += transform[row][col]*derivatives[col];
726
// Delete pointer to array of derivatives on FIAT element
727
delete [] derivatives;
729
// Delete pointer to array of combinations of derivatives and transform
730
for (unsigned int row = 0; row < num_derivatives; row++)
732
delete [] combinations[row];
733
delete [] transform[row];
736
delete [] combinations;
740
/// Evaluate order n derivatives of all basis functions at given point in cell
741
virtual void evaluate_basis_derivatives_all(unsigned int n,
743
const double* coordinates,
744
const ufc::cell& c) const
746
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
749
/// Evaluate linear functional for dof i on the function f
750
virtual double evaluate_dof(unsigned int i,
751
const ufc::function& f,
752
const ufc::cell& c) const
754
// The reference points, direction and weights:
755
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
756
const static double W[1][1] = {{1}};
757
const static double D[1][1][1] = {{{1}}};
759
const double * const * x = c.coordinates;
761
// Iterate over the points:
762
// Evaluate basis functions for affine mapping
763
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
764
const double w1 = X[i][0][0];
765
const double w2 = X[i][0][1];
767
// Compute affine mapping y = F(X)
769
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
770
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
772
// Evaluate function at physical points
774
f.evaluate(values, y, c);
776
// Map function values using appropriate mapping
777
// Affine map: Do nothing
779
// Note that we do not map the weights (yet).
781
// Take directional components
782
for(int k = 0; k < 1; k++)
783
result += values[k]*D[i][0][k];
784
// Multiply by weights
790
/// Evaluate linear functionals for all dofs on the function f
791
virtual void evaluate_dofs(double* values,
792
const ufc::function& f,
793
const ufc::cell& c) const
795
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
798
/// Interpolate vertex values from dof values
799
virtual void interpolate_vertex_values(double* vertex_values,
800
const double* dof_values,
801
const ufc::cell& c) const
803
// Evaluate at vertices and use affine mapping
804
vertex_values[0] = dof_values[0];
805
vertex_values[1] = dof_values[0];
806
vertex_values[2] = dof_values[0];
809
/// Return the number of sub elements (for a mixed element)
810
virtual unsigned int num_sub_elements() const
815
/// Create a new finite element for sub element i (for a mixed element)
816
virtual ufc::finite_element* create_sub_element(unsigned int i) const
818
return new UFC_LiftFunctional_finite_element_1_0();
823
/// This class defines the interface for a finite element.
825
class UFC_LiftFunctional_finite_element_1_1: public ufc::finite_element
830
UFC_LiftFunctional_finite_element_1_1() : ufc::finite_element()
836
virtual ~UFC_LiftFunctional_finite_element_1_1()
841
/// Return a string identifying the finite element
842
virtual const char* signature() const
844
return "Discontinuous Lagrange finite element of degree 0 on a triangle";
847
/// Return the cell shape
848
virtual ufc::shape cell_shape() const
850
return ufc::triangle;
853
/// Return the dimension of the finite element function space
854
virtual unsigned int space_dimension() const
859
/// Return the rank of the value space
860
virtual unsigned int value_rank() const
865
/// Return the dimension of the value space for axis i
866
virtual unsigned int value_dimension(unsigned int i) const
871
/// Evaluate basis function i at given point in cell
872
virtual void evaluate_basis(unsigned int i,
874
const double* coordinates,
875
const ufc::cell& c) const
877
// Extract vertex coordinates
878
const double * const * element_coordinates = c.coordinates;
880
// Compute Jacobian of affine map from reference cell
881
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
882
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
883
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
884
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
886
// Compute determinant of Jacobian
887
const double detJ = J_00*J_11 - J_01*J_10;
889
// Compute inverse of Jacobian
891
// Get coordinates and map to the reference (UFC) element
892
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
893
element_coordinates[0][0]*element_coordinates[2][1] +\
894
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
895
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
896
element_coordinates[1][0]*element_coordinates[0][1] -\
897
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
899
// Map coordinates to the reference square
900
if (std::abs(y - 1.0) < 1e-14)
903
x = 2.0 *x/(1.0 - y) - 1.0;
909
// Map degree of freedom to element degree of freedom
910
const unsigned int dof = i;
913
const double scalings_y_0 = 1;
915
// Compute psitilde_a
916
const double psitilde_a_0 = 1;
918
// Compute psitilde_bs
919
const double psitilde_bs_0_0 = 1;
921
// Compute basisvalues
922
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
924
// Table(s) of coefficients
925
const static double coefficients0[1][1] = \
926
{{1.41421356237309}};
928
// Extract relevant coefficients
929
const double coeff0_0 = coefficients0[dof][0];
932
*values = coeff0_0*basisvalue0;
935
/// Evaluate all basis functions at given point in cell
936
virtual void evaluate_basis_all(double* values,
937
const double* coordinates,
938
const ufc::cell& c) const
940
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
943
/// Evaluate order n derivatives of basis function i at given point in cell
944
virtual void evaluate_basis_derivatives(unsigned int i,
947
const double* coordinates,
948
const ufc::cell& c) const
950
// Extract vertex coordinates
951
const double * const * element_coordinates = c.coordinates;
953
// Compute Jacobian of affine map from reference cell
954
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
955
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
956
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
957
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
959
// Compute determinant of Jacobian
960
const double detJ = J_00*J_11 - J_01*J_10;
962
// Compute inverse of Jacobian
964
// Get coordinates and map to the reference (UFC) element
965
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
966
element_coordinates[0][0]*element_coordinates[2][1] +\
967
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
968
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
969
element_coordinates[1][0]*element_coordinates[0][1] -\
970
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
972
// Map coordinates to the reference square
973
if (std::abs(y - 1.0) < 1e-14)
976
x = 2.0 *x/(1.0 - y) - 1.0;
979
// Compute number of derivatives
980
unsigned int num_derivatives = 1;
982
for (unsigned int j = 0; j < n; j++)
983
num_derivatives *= 2;
986
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
987
unsigned int **combinations = new unsigned int *[num_derivatives];
989
for (unsigned int j = 0; j < num_derivatives; j++)
991
combinations[j] = new unsigned int [n];
992
for (unsigned int k = 0; k < n; k++)
993
combinations[j][k] = 0;
996
// Generate combinations of derivatives
997
for (unsigned int row = 1; row < num_derivatives; row++)
999
for (unsigned int num = 0; num < row; num++)
1001
for (unsigned int col = n-1; col+1 > 0; col--)
1003
if (combinations[row][col] + 1 > 1)
1004
combinations[row][col] = 0;
1007
combinations[row][col] += 1;
1014
// Compute inverse of Jacobian
1015
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1017
// Declare transformation matrix
1018
// Declare pointer to two dimensional array and initialise
1019
double **transform = new double *[num_derivatives];
1021
for (unsigned int j = 0; j < num_derivatives; j++)
1023
transform[j] = new double [num_derivatives];
1024
for (unsigned int k = 0; k < num_derivatives; k++)
1025
transform[j][k] = 1;
1028
// Construct transformation matrix
1029
for (unsigned int row = 0; row < num_derivatives; row++)
1031
for (unsigned int col = 0; col < num_derivatives; col++)
1033
for (unsigned int k = 0; k < n; k++)
1034
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1039
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1042
// Map degree of freedom to element degree of freedom
1043
const unsigned int dof = i;
1045
// Generate scalings
1046
const double scalings_y_0 = 1;
1048
// Compute psitilde_a
1049
const double psitilde_a_0 = 1;
1051
// Compute psitilde_bs
1052
const double psitilde_bs_0_0 = 1;
1054
// Compute basisvalues
1055
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1057
// Table(s) of coefficients
1058
const static double coefficients0[1][1] = \
1059
{{1.41421356237309}};
1061
// Interesting (new) part
1062
// Tables of derivatives of the polynomial base (transpose)
1063
const static double dmats0[1][1] = \
1066
const static double dmats1[1][1] = \
1069
// Compute reference derivatives
1070
// Declare pointer to array of derivatives on FIAT element
1071
double *derivatives = new double [num_derivatives];
1073
// Declare coefficients
1074
double coeff0_0 = 0;
1076
// Declare new coefficients
1077
double new_coeff0_0 = 0;
1079
// Loop possible derivatives
1080
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1082
// Get values from coefficients array
1083
new_coeff0_0 = coefficients0[dof][0];
1085
// Loop derivative order
1086
for (unsigned int j = 0; j < n; j++)
1088
// Update old coefficients
1089
coeff0_0 = new_coeff0_0;
1091
if(combinations[deriv_num][j] == 0)
1093
new_coeff0_0 = coeff0_0*dmats0[0][0];
1095
if(combinations[deriv_num][j] == 1)
1097
new_coeff0_0 = coeff0_0*dmats1[0][0];
1101
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1102
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
1105
// Transform derivatives back to physical element
1106
for (unsigned int row = 0; row < num_derivatives; row++)
1108
for (unsigned int col = 0; col < num_derivatives; col++)
1110
values[row] += transform[row][col]*derivatives[col];
1113
// Delete pointer to array of derivatives on FIAT element
1114
delete [] derivatives;
1116
// Delete pointer to array of combinations of derivatives and transform
1117
for (unsigned int row = 0; row < num_derivatives; row++)
1119
delete [] combinations[row];
1120
delete [] transform[row];
1123
delete [] combinations;
1124
delete [] transform;
1127
/// Evaluate order n derivatives of all basis functions at given point in cell
1128
virtual void evaluate_basis_derivatives_all(unsigned int n,
1130
const double* coordinates,
1131
const ufc::cell& c) const
1133
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1136
/// Evaluate linear functional for dof i on the function f
1137
virtual double evaluate_dof(unsigned int i,
1138
const ufc::function& f,
1139
const ufc::cell& c) const
1141
// The reference points, direction and weights:
1142
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
1143
const static double W[1][1] = {{1}};
1144
const static double D[1][1][1] = {{{1}}};
1146
const double * const * x = c.coordinates;
1147
double result = 0.0;
1148
// Iterate over the points:
1149
// Evaluate basis functions for affine mapping
1150
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1151
const double w1 = X[i][0][0];
1152
const double w2 = X[i][0][1];
1154
// Compute affine mapping y = F(X)
1156
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1157
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1159
// Evaluate function at physical points
1161
f.evaluate(values, y, c);
1163
// Map function values using appropriate mapping
1164
// Affine map: Do nothing
1166
// Note that we do not map the weights (yet).
1168
// Take directional components
1169
for(int k = 0; k < 1; k++)
1170
result += values[k]*D[i][0][k];
1171
// Multiply by weights
1177
/// Evaluate linear functionals for all dofs on the function f
1178
virtual void evaluate_dofs(double* values,
1179
const ufc::function& f,
1180
const ufc::cell& c) const
1182
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1185
/// Interpolate vertex values from dof values
1186
virtual void interpolate_vertex_values(double* vertex_values,
1187
const double* dof_values,
1188
const ufc::cell& c) const
1190
// Evaluate at vertices and use affine mapping
1191
vertex_values[0] = dof_values[0];
1192
vertex_values[1] = dof_values[0];
1193
vertex_values[2] = dof_values[0];
1196
/// Return the number of sub elements (for a mixed element)
1197
virtual unsigned int num_sub_elements() const
1202
/// Create a new finite element for sub element i (for a mixed element)
1203
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1205
return new UFC_LiftFunctional_finite_element_1_1();
1210
/// This class defines the interface for a finite element.
1212
class UFC_LiftFunctional_finite_element_1: public ufc::finite_element
1217
UFC_LiftFunctional_finite_element_1() : ufc::finite_element()
1223
virtual ~UFC_LiftFunctional_finite_element_1()
1228
/// Return a string identifying the finite element
1229
virtual const char* signature() const
1231
return "Mixed finite element: [Discontinuous Lagrange finite element of degree 0 on a triangle, Discontinuous Lagrange finite element of degree 0 on a triangle]";
1234
/// Return the cell shape
1235
virtual ufc::shape cell_shape() const
1237
return ufc::triangle;
1240
/// Return the dimension of the finite element function space
1241
virtual unsigned int space_dimension() const
1246
/// Return the rank of the value space
1247
virtual unsigned int value_rank() const
1252
/// Return the dimension of the value space for axis i
1253
virtual unsigned int value_dimension(unsigned int i) const
1258
/// Evaluate basis function i at given point in cell
1259
virtual void evaluate_basis(unsigned int i,
1261
const double* coordinates,
1262
const ufc::cell& c) const
1264
// Extract vertex coordinates
1265
const double * const * element_coordinates = c.coordinates;
1267
// Compute Jacobian of affine map from reference cell
1268
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1269
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1270
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1271
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1273
// Compute determinant of Jacobian
1274
const double detJ = J_00*J_11 - J_01*J_10;
1276
// Compute inverse of Jacobian
1278
// Get coordinates and map to the reference (UFC) element
1279
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1280
element_coordinates[0][0]*element_coordinates[2][1] +\
1281
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1282
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1283
element_coordinates[1][0]*element_coordinates[0][1] -\
1284
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1286
// Map coordinates to the reference square
1287
if (std::abs(y - 1.0) < 1e-14)
1290
x = 2.0 *x/(1.0 - y) - 1.0;
1297
if (0 <= i && i <= 0)
1299
// Map degree of freedom to element degree of freedom
1300
const unsigned int dof = i;
1302
// Generate scalings
1303
const double scalings_y_0 = 1;
1305
// Compute psitilde_a
1306
const double psitilde_a_0 = 1;
1308
// Compute psitilde_bs
1309
const double psitilde_bs_0_0 = 1;
1311
// Compute basisvalues
1312
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1314
// Table(s) of coefficients
1315
const static double coefficients0[1][1] = \
1316
{{1.41421356237309}};
1318
// Extract relevant coefficients
1319
const double coeff0_0 = coefficients0[dof][0];
1322
values[0] = coeff0_0*basisvalue0;
1325
if (1 <= i && i <= 1)
1327
// Map degree of freedom to element degree of freedom
1328
const unsigned int dof = i - 1;
1330
// Generate scalings
1331
const double scalings_y_0 = 1;
1333
// Compute psitilde_a
1334
const double psitilde_a_0 = 1;
1336
// Compute psitilde_bs
1337
const double psitilde_bs_0_0 = 1;
1339
// Compute basisvalues
1340
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1342
// Table(s) of coefficients
1343
const static double coefficients0[1][1] = \
1344
{{1.41421356237309}};
1346
// Extract relevant coefficients
1347
const double coeff0_0 = coefficients0[dof][0];
1350
values[1] = coeff0_0*basisvalue0;
1355
/// Evaluate all basis functions at given point in cell
1356
virtual void evaluate_basis_all(double* values,
1357
const double* coordinates,
1358
const ufc::cell& c) const
1360
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1363
/// Evaluate order n derivatives of basis function i at given point in cell
1364
virtual void evaluate_basis_derivatives(unsigned int i,
1367
const double* coordinates,
1368
const ufc::cell& c) const
1370
// Extract vertex coordinates
1371
const double * const * element_coordinates = c.coordinates;
1373
// Compute Jacobian of affine map from reference cell
1374
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1375
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1376
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1377
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1379
// Compute determinant of Jacobian
1380
const double detJ = J_00*J_11 - J_01*J_10;
1382
// Compute inverse of Jacobian
1384
// Get coordinates and map to the reference (UFC) element
1385
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1386
element_coordinates[0][0]*element_coordinates[2][1] +\
1387
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1388
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1389
element_coordinates[1][0]*element_coordinates[0][1] -\
1390
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1392
// Map coordinates to the reference square
1393
if (std::abs(y - 1.0) < 1e-14)
1396
x = 2.0 *x/(1.0 - y) - 1.0;
1399
// Compute number of derivatives
1400
unsigned int num_derivatives = 1;
1402
for (unsigned int j = 0; j < n; j++)
1403
num_derivatives *= 2;
1406
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1407
unsigned int **combinations = new unsigned int *[num_derivatives];
1409
for (unsigned int j = 0; j < num_derivatives; j++)
1411
combinations[j] = new unsigned int [n];
1412
for (unsigned int k = 0; k < n; k++)
1413
combinations[j][k] = 0;
1416
// Generate combinations of derivatives
1417
for (unsigned int row = 1; row < num_derivatives; row++)
1419
for (unsigned int num = 0; num < row; num++)
1421
for (unsigned int col = n-1; col+1 > 0; col--)
1423
if (combinations[row][col] + 1 > 1)
1424
combinations[row][col] = 0;
1427
combinations[row][col] += 1;
1434
// Compute inverse of Jacobian
1435
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1437
// Declare transformation matrix
1438
// Declare pointer to two dimensional array and initialise
1439
double **transform = new double *[num_derivatives];
1441
for (unsigned int j = 0; j < num_derivatives; j++)
1443
transform[j] = new double [num_derivatives];
1444
for (unsigned int k = 0; k < num_derivatives; k++)
1445
transform[j][k] = 1;
1448
// Construct transformation matrix
1449
for (unsigned int row = 0; row < num_derivatives; row++)
1451
for (unsigned int col = 0; col < num_derivatives; col++)
1453
for (unsigned int k = 0; k < n; k++)
1454
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1459
for (unsigned int j = 0; j < 2*num_derivatives; j++)
1462
if (0 <= i && i <= 0)
1464
// Map degree of freedom to element degree of freedom
1465
const unsigned int dof = i;
1467
// Generate scalings
1468
const double scalings_y_0 = 1;
1470
// Compute psitilde_a
1471
const double psitilde_a_0 = 1;
1473
// Compute psitilde_bs
1474
const double psitilde_bs_0_0 = 1;
1476
// Compute basisvalues
1477
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1479
// Table(s) of coefficients
1480
const static double coefficients0[1][1] = \
1481
{{1.41421356237309}};
1483
// Interesting (new) part
1484
// Tables of derivatives of the polynomial base (transpose)
1485
const static double dmats0[1][1] = \
1488
const static double dmats1[1][1] = \
1491
// Compute reference derivatives
1492
// Declare pointer to array of derivatives on FIAT element
1493
double *derivatives = new double [num_derivatives];
1495
// Declare coefficients
1496
double coeff0_0 = 0;
1498
// Declare new coefficients
1499
double new_coeff0_0 = 0;
1501
// Loop possible derivatives
1502
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1504
// Get values from coefficients array
1505
new_coeff0_0 = coefficients0[dof][0];
1507
// Loop derivative order
1508
for (unsigned int j = 0; j < n; j++)
1510
// Update old coefficients
1511
coeff0_0 = new_coeff0_0;
1513
if(combinations[deriv_num][j] == 0)
1515
new_coeff0_0 = coeff0_0*dmats0[0][0];
1517
if(combinations[deriv_num][j] == 1)
1519
new_coeff0_0 = coeff0_0*dmats1[0][0];
1523
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1524
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
1527
// Transform derivatives back to physical element
1528
for (unsigned int row = 0; row < num_derivatives; row++)
1530
for (unsigned int col = 0; col < num_derivatives; col++)
1532
values[row] += transform[row][col]*derivatives[col];
1535
// Delete pointer to array of derivatives on FIAT element
1536
delete [] derivatives;
1538
// Delete pointer to array of combinations of derivatives and transform
1539
for (unsigned int row = 0; row < num_derivatives; row++)
1541
delete [] combinations[row];
1542
delete [] transform[row];
1545
delete [] combinations;
1546
delete [] transform;
1549
if (1 <= i && i <= 1)
1551
// Map degree of freedom to element degree of freedom
1552
const unsigned int dof = i - 1;
1554
// Generate scalings
1555
const double scalings_y_0 = 1;
1557
// Compute psitilde_a
1558
const double psitilde_a_0 = 1;
1560
// Compute psitilde_bs
1561
const double psitilde_bs_0_0 = 1;
1563
// Compute basisvalues
1564
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1566
// Table(s) of coefficients
1567
const static double coefficients0[1][1] = \
1568
{{1.41421356237309}};
1570
// Interesting (new) part
1571
// Tables of derivatives of the polynomial base (transpose)
1572
const static double dmats0[1][1] = \
1575
const static double dmats1[1][1] = \
1578
// Compute reference derivatives
1579
// Declare pointer to array of derivatives on FIAT element
1580
double *derivatives = new double [num_derivatives];
1582
// Declare coefficients
1583
double coeff0_0 = 0;
1585
// Declare new coefficients
1586
double new_coeff0_0 = 0;
1588
// Loop possible derivatives
1589
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1591
// Get values from coefficients array
1592
new_coeff0_0 = coefficients0[dof][0];
1594
// Loop derivative order
1595
for (unsigned int j = 0; j < n; j++)
1597
// Update old coefficients
1598
coeff0_0 = new_coeff0_0;
1600
if(combinations[deriv_num][j] == 0)
1602
new_coeff0_0 = coeff0_0*dmats0[0][0];
1604
if(combinations[deriv_num][j] == 1)
1606
new_coeff0_0 = coeff0_0*dmats1[0][0];
1610
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1611
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
1614
// Transform derivatives back to physical element
1615
for (unsigned int row = 0; row < num_derivatives; row++)
1617
for (unsigned int col = 0; col < num_derivatives; col++)
1619
values[num_derivatives + row] += transform[row][col]*derivatives[col];
1622
// Delete pointer to array of derivatives on FIAT element
1623
delete [] derivatives;
1625
// Delete pointer to array of combinations of derivatives and transform
1626
for (unsigned int row = 0; row < num_derivatives; row++)
1628
delete [] combinations[row];
1629
delete [] transform[row];
1632
delete [] combinations;
1633
delete [] transform;
1638
/// Evaluate order n derivatives of all basis functions at given point in cell
1639
virtual void evaluate_basis_derivatives_all(unsigned int n,
1641
const double* coordinates,
1642
const ufc::cell& c) const
1644
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1647
/// Evaluate linear functional for dof i on the function f
1648
virtual double evaluate_dof(unsigned int i,
1649
const ufc::function& f,
1650
const ufc::cell& c) const
1652
// The reference points, direction and weights:
1653
const static double X[2][1][2] = {{{0.333333333333333, 0.333333333333333}}, {{0.333333333333333, 0.333333333333333}}};
1654
const static double W[2][1] = {{1}, {1}};
1655
const static double D[2][1][2] = {{{1, 0}}, {{0, 1}}};
1657
const double * const * x = c.coordinates;
1658
double result = 0.0;
1659
// Iterate over the points:
1660
// Evaluate basis functions for affine mapping
1661
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1662
const double w1 = X[i][0][0];
1663
const double w2 = X[i][0][1];
1665
// Compute affine mapping y = F(X)
1667
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1668
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1670
// Evaluate function at physical points
1672
f.evaluate(values, y, c);
1674
// Map function values using appropriate mapping
1675
// Affine map: Do nothing
1677
// Note that we do not map the weights (yet).
1679
// Take directional components
1680
for(int k = 0; k < 2; k++)
1681
result += values[k]*D[i][0][k];
1682
// Multiply by weights
1688
/// Evaluate linear functionals for all dofs on the function f
1689
virtual void evaluate_dofs(double* values,
1690
const ufc::function& f,
1691
const ufc::cell& c) const
1693
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1696
/// Interpolate vertex values from dof values
1697
virtual void interpolate_vertex_values(double* vertex_values,
1698
const double* dof_values,
1699
const ufc::cell& c) const
1701
// Evaluate at vertices and use affine mapping
1702
vertex_values[0] = dof_values[0];
1703
vertex_values[1] = dof_values[0];
1704
vertex_values[2] = dof_values[0];
1705
// Evaluate at vertices and use affine mapping
1706
vertex_values[3] = dof_values[1];
1707
vertex_values[4] = dof_values[1];
1708
vertex_values[5] = dof_values[1];
1711
/// Return the number of sub elements (for a mixed element)
1712
virtual unsigned int num_sub_elements() const
1717
/// Create a new finite element for sub element i (for a mixed element)
1718
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1723
return new UFC_LiftFunctional_finite_element_1_0();
1726
return new UFC_LiftFunctional_finite_element_1_1();
1734
/// This class defines the interface for a local-to-global mapping of
1735
/// degrees of freedom (dofs).
1737
class UFC_LiftFunctional_dof_map_0: public ufc::dof_map
1741
unsigned int __global_dimension;
1746
UFC_LiftFunctional_dof_map_0() : ufc::dof_map()
1748
__global_dimension = 0;
1752
virtual ~UFC_LiftFunctional_dof_map_0()
1757
/// Return a string identifying the dof map
1758
virtual const char* signature() const
1760
return "FFC dof map for Lagrange finite element of degree 1 on a triangle";
1763
/// Return true iff mesh entities of topological dimension d are needed
1764
virtual bool needs_mesh_entities(unsigned int d) const
1781
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1782
virtual bool init_mesh(const ufc::mesh& m)
1784
__global_dimension = m.num_entities[0];
1788
/// Initialize dof map for given cell
1789
virtual void init_cell(const ufc::mesh& m,
1795
/// Finish initialization of dof map for cells
1796
virtual void init_cell_finalize()
1801
/// Return the dimension of the global finite element function space
1802
virtual unsigned int global_dimension() const
1804
return __global_dimension;
1807
/// Return the dimension of the local finite element function space
1808
virtual unsigned int local_dimension() const
1813
// Return the geometric dimension of the coordinates this dof map provides
1814
virtual unsigned int geometric_dimension() const
1816
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1819
/// Return the number of dofs on each cell facet
1820
virtual unsigned int num_facet_dofs() const
1825
/// Return the number of dofs associated with each cell entity of dimension d
1826
virtual unsigned int num_entity_dofs(unsigned int d) const
1828
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1831
/// Tabulate the local-to-global mapping of dofs on a cell
1832
virtual void tabulate_dofs(unsigned int* dofs,
1834
const ufc::cell& c) const
1836
dofs[0] = c.entity_indices[0][0];
1837
dofs[1] = c.entity_indices[0][1];
1838
dofs[2] = c.entity_indices[0][2];
1841
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1842
virtual void tabulate_facet_dofs(unsigned int* dofs,
1843
unsigned int facet) const
1862
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1863
virtual void tabulate_entity_dofs(unsigned int* dofs,
1864
unsigned int d, unsigned int i) const
1866
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1869
/// Tabulate the coordinates of all dofs on a cell
1870
virtual void tabulate_coordinates(double** coordinates,
1871
const ufc::cell& c) const
1873
const double * const * x = c.coordinates;
1874
coordinates[0][0] = x[0][0];
1875
coordinates[0][1] = x[0][1];
1876
coordinates[1][0] = x[1][0];
1877
coordinates[1][1] = x[1][1];
1878
coordinates[2][0] = x[2][0];
1879
coordinates[2][1] = x[2][1];
1882
/// Return the number of sub dof maps (for a mixed element)
1883
virtual unsigned int num_sub_dof_maps() const
1888
/// Create a new dof_map for sub dof map i (for a mixed element)
1889
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1891
return new UFC_LiftFunctional_dof_map_0();
1896
/// This class defines the interface for a local-to-global mapping of
1897
/// degrees of freedom (dofs).
1899
class UFC_LiftFunctional_dof_map_1_0: public ufc::dof_map
1903
unsigned int __global_dimension;
1908
UFC_LiftFunctional_dof_map_1_0() : ufc::dof_map()
1910
__global_dimension = 0;
1914
virtual ~UFC_LiftFunctional_dof_map_1_0()
1919
/// Return a string identifying the dof map
1920
virtual const char* signature() const
1922
return "FFC dof map for Discontinuous Lagrange finite element of degree 0 on a triangle";
1925
/// Return true iff mesh entities of topological dimension d are needed
1926
virtual bool needs_mesh_entities(unsigned int d) const
1943
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1944
virtual bool init_mesh(const ufc::mesh& m)
1946
__global_dimension = m.num_entities[2];
1950
/// Initialize dof map for given cell
1951
virtual void init_cell(const ufc::mesh& m,
1957
/// Finish initialization of dof map for cells
1958
virtual void init_cell_finalize()
1963
/// Return the dimension of the global finite element function space
1964
virtual unsigned int global_dimension() const
1966
return __global_dimension;
1969
/// Return the dimension of the local finite element function space
1970
virtual unsigned int local_dimension() const
1975
// Return the geometric dimension of the coordinates this dof map provides
1976
virtual unsigned int geometric_dimension() const
1978
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1981
/// Return the number of dofs on each cell facet
1982
virtual unsigned int num_facet_dofs() const
1987
/// Return the number of dofs associated with each cell entity of dimension d
1988
virtual unsigned int num_entity_dofs(unsigned int d) const
1990
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1993
/// Tabulate the local-to-global mapping of dofs on a cell
1994
virtual void tabulate_dofs(unsigned int* dofs,
1996
const ufc::cell& c) const
1998
dofs[0] = c.entity_indices[2][0];
2001
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2002
virtual void tabulate_facet_dofs(unsigned int* dofs,
2003
unsigned int facet) const
2019
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2020
virtual void tabulate_entity_dofs(unsigned int* dofs,
2021
unsigned int d, unsigned int i) const
2023
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2026
/// Tabulate the coordinates of all dofs on a cell
2027
virtual void tabulate_coordinates(double** coordinates,
2028
const ufc::cell& c) const
2030
const double * const * x = c.coordinates;
2031
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
2032
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
2035
/// Return the number of sub dof maps (for a mixed element)
2036
virtual unsigned int num_sub_dof_maps() const
2041
/// Create a new dof_map for sub dof map i (for a mixed element)
2042
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2044
return new UFC_LiftFunctional_dof_map_1_0();
2049
/// This class defines the interface for a local-to-global mapping of
2050
/// degrees of freedom (dofs).
2052
class UFC_LiftFunctional_dof_map_1_1: public ufc::dof_map
2056
unsigned int __global_dimension;
2061
UFC_LiftFunctional_dof_map_1_1() : ufc::dof_map()
2063
__global_dimension = 0;
2067
virtual ~UFC_LiftFunctional_dof_map_1_1()
2072
/// Return a string identifying the dof map
2073
virtual const char* signature() const
2075
return "FFC dof map for Discontinuous Lagrange finite element of degree 0 on a triangle";
2078
/// Return true iff mesh entities of topological dimension d are needed
2079
virtual bool needs_mesh_entities(unsigned int d) const
2096
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2097
virtual bool init_mesh(const ufc::mesh& m)
2099
__global_dimension = m.num_entities[2];
2103
/// Initialize dof map for given cell
2104
virtual void init_cell(const ufc::mesh& m,
2110
/// Finish initialization of dof map for cells
2111
virtual void init_cell_finalize()
2116
/// Return the dimension of the global finite element function space
2117
virtual unsigned int global_dimension() const
2119
return __global_dimension;
2122
/// Return the dimension of the local finite element function space
2123
virtual unsigned int local_dimension() const
2128
// Return the geometric dimension of the coordinates this dof map provides
2129
virtual unsigned int geometric_dimension() const
2131
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2134
/// Return the number of dofs on each cell facet
2135
virtual unsigned int num_facet_dofs() const
2140
/// Return the number of dofs associated with each cell entity of dimension d
2141
virtual unsigned int num_entity_dofs(unsigned int d) const
2143
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2146
/// Tabulate the local-to-global mapping of dofs on a cell
2147
virtual void tabulate_dofs(unsigned int* dofs,
2149
const ufc::cell& c) const
2151
dofs[0] = c.entity_indices[2][0];
2154
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2155
virtual void tabulate_facet_dofs(unsigned int* dofs,
2156
unsigned int facet) const
2172
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2173
virtual void tabulate_entity_dofs(unsigned int* dofs,
2174
unsigned int d, unsigned int i) const
2176
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2179
/// Tabulate the coordinates of all dofs on a cell
2180
virtual void tabulate_coordinates(double** coordinates,
2181
const ufc::cell& c) const
2183
const double * const * x = c.coordinates;
2184
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
2185
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
2188
/// Return the number of sub dof maps (for a mixed element)
2189
virtual unsigned int num_sub_dof_maps() const
2194
/// Create a new dof_map for sub dof map i (for a mixed element)
2195
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2197
return new UFC_LiftFunctional_dof_map_1_1();
2202
/// This class defines the interface for a local-to-global mapping of
2203
/// degrees of freedom (dofs).
2205
class UFC_LiftFunctional_dof_map_1: public ufc::dof_map
2209
unsigned int __global_dimension;
2214
UFC_LiftFunctional_dof_map_1() : ufc::dof_map()
2216
__global_dimension = 0;
2220
virtual ~UFC_LiftFunctional_dof_map_1()
2225
/// Return a string identifying the dof map
2226
virtual const char* signature() const
2228
return "FFC dof map for Mixed finite element: [Discontinuous Lagrange finite element of degree 0 on a triangle, Discontinuous Lagrange finite element of degree 0 on a triangle]";
2231
/// Return true iff mesh entities of topological dimension d are needed
2232
virtual bool needs_mesh_entities(unsigned int d) const
2249
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2250
virtual bool init_mesh(const ufc::mesh& m)
2252
__global_dimension = 2*m.num_entities[2];
2256
/// Initialize dof map for given cell
2257
virtual void init_cell(const ufc::mesh& m,
2263
/// Finish initialization of dof map for cells
2264
virtual void init_cell_finalize()
2269
/// Return the dimension of the global finite element function space
2270
virtual unsigned int global_dimension() const
2272
return __global_dimension;
2275
/// Return the dimension of the local finite element function space
2276
virtual unsigned int local_dimension() const
2281
// Return the geometric dimension of the coordinates this dof map provides
2282
virtual unsigned int geometric_dimension() const
2284
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2287
/// Return the number of dofs on each cell facet
2288
virtual unsigned int num_facet_dofs() const
2293
/// Return the number of dofs associated with each cell entity of dimension d
2294
virtual unsigned int num_entity_dofs(unsigned int d) const
2296
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2299
/// Tabulate the local-to-global mapping of dofs on a cell
2300
virtual void tabulate_dofs(unsigned int* dofs,
2302
const ufc::cell& c) const
2304
dofs[0] = c.entity_indices[2][0];
2305
unsigned int offset = m.num_entities[2];
2306
dofs[1] = offset + c.entity_indices[2][0];
2309
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2310
virtual void tabulate_facet_dofs(unsigned int* dofs,
2311
unsigned int facet) const
2327
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2328
virtual void tabulate_entity_dofs(unsigned int* dofs,
2329
unsigned int d, unsigned int i) const
2331
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2334
/// Tabulate the coordinates of all dofs on a cell
2335
virtual void tabulate_coordinates(double** coordinates,
2336
const ufc::cell& c) const
2338
const double * const * x = c.coordinates;
2339
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
2340
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
2341
coordinates[1][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
2342
coordinates[1][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
2345
/// Return the number of sub dof maps (for a mixed element)
2346
virtual unsigned int num_sub_dof_maps() const
2351
/// Create a new dof_map for sub dof map i (for a mixed element)
2352
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2357
return new UFC_LiftFunctional_dof_map_1_0();
2360
return new UFC_LiftFunctional_dof_map_1_1();
2368
/// This class defines the interface for the tabulation of the
2369
/// exterior facet tensor corresponding to the local contribution to
2370
/// a form from the integral over an exterior facet.
2372
class UFC_LiftFunctional_exterior_facet_integral_0: public ufc::exterior_facet_integral
2377
UFC_LiftFunctional_exterior_facet_integral_0() : ufc::exterior_facet_integral()
2383
virtual ~UFC_LiftFunctional_exterior_facet_integral_0()
2388
/// Tabulate the tensor for the contribution from a local exterior facet
2389
virtual void tabulate_tensor(double* A,
2390
const double * const * w,
2392
unsigned int facet) const
2394
// Extract vertex coordinates
2395
const double * const * x = c.coordinates;
2397
// Compute Jacobian of affine map from reference cell
2399
// Compute determinant of Jacobian
2401
// Compute inverse of Jacobian
2403
// Vertices on edges
2404
static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
2407
const unsigned int v0 = edge_vertices[facet][0];
2408
const unsigned int v1 = edge_vertices[facet][1];
2410
// Compute scale factor (length of edge scaled by length of reference interval)
2411
const double dx0 = x[v1][0] - x[v0][0];
2412
const double dx1 = x[v1][1] - x[v0][1];
2413
const double det = std::sqrt(dx0*dx0 + dx1*dx1);
2415
// Compute coefficients
2416
const double c0_0_0_0 = w[0][0];
2417
const double c0_0_0_1 = w[0][1];
2418
const double c0_0_0_2 = w[0][2];
2419
const double c1_0_1_1 = w[1][1];
2421
// Compute geometry tensors
2422
const double G0_0_1 = det*c0_0_0_0*c1_0_1_1;
2423
const double G0_1_1 = det*c0_0_0_1*c1_0_1_1;
2424
const double G0_2_1 = det*c0_0_0_2*c1_0_1_1;
2426
// Compute element tensor for all facets
2430
A[0] = 0.5*G0_1_1 + 0.5*G0_2_1;
2433
A[0] = 0.5*G0_0_1 + 0.5*G0_2_1;
2436
A[0] = 0.5*G0_0_1 + 0.5*G0_1_1;
2443
/// This class defines the interface for the assembly of the global
2444
/// tensor corresponding to a form with r + n arguments, that is, a
2447
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2449
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2450
/// global tensor A is defined by
2452
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2454
/// where each argument Vj represents the application to the
2455
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2456
/// fixed functions (coefficients).
2458
class UFC_LiftFunctional: public ufc::form
2463
UFC_LiftFunctional() : ufc::form()
2469
virtual ~UFC_LiftFunctional()
2474
/// Return a string identifying the form
2475
virtual const char* signature() const
2477
return "w0_a0w1_a1 | va0*va1[1]*ds(0)";
2480
/// Return the rank of the global tensor (r)
2481
virtual unsigned int rank() const
2486
/// Return the number of coefficients (n)
2487
virtual unsigned int num_coefficients() const
2492
/// Return the number of cell integrals
2493
virtual unsigned int num_cell_integrals() const
2498
/// Return the number of exterior facet integrals
2499
virtual unsigned int num_exterior_facet_integrals() const
2504
/// Return the number of interior facet integrals
2505
virtual unsigned int num_interior_facet_integrals() const
2510
/// Create a new finite element for argument function i
2511
virtual ufc::finite_element* create_finite_element(unsigned int i) const
2516
return new UFC_LiftFunctional_finite_element_0();
2519
return new UFC_LiftFunctional_finite_element_1();
2525
/// Create a new dof map for argument function i
2526
virtual ufc::dof_map* create_dof_map(unsigned int i) const
2531
return new UFC_LiftFunctional_dof_map_0();
2534
return new UFC_LiftFunctional_dof_map_1();
2540
/// Create a new cell integral on sub domain i
2541
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
2546
/// Create a new exterior facet integral on sub domain i
2547
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
2549
return new UFC_LiftFunctional_exterior_facet_integral_0();
2552
/// Create a new interior facet integral on sub domain i
2553
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
2562
#include <dolfin/fem/Form.h>
2564
class LiftFunctional : public dolfin::Form
2568
LiftFunctional(dolfin::Function& w0, dolfin::Function& w1) : dolfin::Form()
2570
__coefficients.push_back(&w0);
2571
__coefficients.push_back(&w1);
2575
virtual const ufc::form& form() const
2580
/// Return array of coefficients
2581
virtual const dolfin::Array<dolfin::Function*>& coefficients() const
2583
return __coefficients;
2589
UFC_LiftFunctional __form;
2591
/// Array of coefficients
2592
dolfin::Array<dolfin::Function*> __coefficients;