1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.6.0.
4
// Warning: This code was generated with the option '-l dolfin'
5
// and contains DOLFIN-specific wrappers that depend on DOLFIN.
7
#ifndef __P1PROJECTION_H
8
#define __P1PROJECTION_H
15
/// This class defines the interface for a finite element.
17
class UFC_P1ProjectionBilinearForm_finite_element_0: public ufc::finite_element
22
UFC_P1ProjectionBilinearForm_finite_element_0() : ufc::finite_element()
28
virtual ~UFC_P1ProjectionBilinearForm_finite_element_0()
33
/// Return a string identifying the finite element
34
virtual const char* signature() const
36
return "FiniteElement('Lagrange', 'triangle', 1)";
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_P1ProjectionBilinearForm_finite_element_0();
436
/// This class defines the interface for a finite element.
438
class UFC_P1ProjectionBilinearForm_finite_element_1: public ufc::finite_element
443
UFC_P1ProjectionBilinearForm_finite_element_1() : ufc::finite_element()
449
virtual ~UFC_P1ProjectionBilinearForm_finite_element_1()
454
/// Return a string identifying the finite element
455
virtual const char* signature() const
457
return "FiniteElement('Lagrange', 'triangle', 1)";
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;
527
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
529
// Compute psitilde_a
530
const double psitilde_a_0 = 1;
531
const double psitilde_a_1 = x;
533
// Compute psitilde_bs
534
const double psitilde_bs_0_0 = 1;
535
const double psitilde_bs_0_1 = 1.5*y + 0.5;
536
const double psitilde_bs_1_0 = 1;
538
// Compute basisvalues
539
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
540
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
541
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
543
// Table(s) of coefficients
544
const static double coefficients0[3][3] = \
545
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
546
{0.471404520791032, 0.288675134594813, -0.166666666666667},
547
{0.471404520791032, 0, 0.333333333333333}};
549
// Extract relevant coefficients
550
const double coeff0_0 = coefficients0[dof][0];
551
const double coeff0_1 = coefficients0[dof][1];
552
const double coeff0_2 = coefficients0[dof][2];
555
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
558
/// Evaluate all basis functions at given point in cell
559
virtual void evaluate_basis_all(double* values,
560
const double* coordinates,
561
const ufc::cell& c) const
563
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
566
/// Evaluate order n derivatives of basis function i at given point in cell
567
virtual void evaluate_basis_derivatives(unsigned int i,
570
const double* coordinates,
571
const ufc::cell& c) const
573
// Extract vertex coordinates
574
const double * const * element_coordinates = c.coordinates;
576
// Compute Jacobian of affine map from reference cell
577
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
578
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
579
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
580
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
582
// Compute determinant of Jacobian
583
const double detJ = J_00*J_11 - J_01*J_10;
585
// Compute inverse of Jacobian
587
// Get coordinates and map to the reference (UFC) element
588
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
589
element_coordinates[0][0]*element_coordinates[2][1] +\
590
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
591
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
592
element_coordinates[1][0]*element_coordinates[0][1] -\
593
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
595
// Map coordinates to the reference square
596
if (std::abs(y - 1.0) < 1e-14)
599
x = 2.0 *x/(1.0 - y) - 1.0;
602
// Compute number of derivatives
603
unsigned int num_derivatives = 1;
605
for (unsigned int j = 0; j < n; j++)
606
num_derivatives *= 2;
609
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
610
unsigned int **combinations = new unsigned int *[num_derivatives];
612
for (unsigned int j = 0; j < num_derivatives; j++)
614
combinations[j] = new unsigned int [n];
615
for (unsigned int k = 0; k < n; k++)
616
combinations[j][k] = 0;
619
// Generate combinations of derivatives
620
for (unsigned int row = 1; row < num_derivatives; row++)
622
for (unsigned int num = 0; num < row; num++)
624
for (unsigned int col = n-1; col+1 > 0; col--)
626
if (combinations[row][col] + 1 > 1)
627
combinations[row][col] = 0;
630
combinations[row][col] += 1;
637
// Compute inverse of Jacobian
638
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
640
// Declare transformation matrix
641
// Declare pointer to two dimensional array and initialise
642
double **transform = new double *[num_derivatives];
644
for (unsigned int j = 0; j < num_derivatives; j++)
646
transform[j] = new double [num_derivatives];
647
for (unsigned int k = 0; k < num_derivatives; k++)
651
// Construct transformation matrix
652
for (unsigned int row = 0; row < num_derivatives; row++)
654
for (unsigned int col = 0; col < num_derivatives; col++)
656
for (unsigned int k = 0; k < n; k++)
657
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
662
for (unsigned int j = 0; j < 1*num_derivatives; j++)
665
// Map degree of freedom to element degree of freedom
666
const unsigned int dof = i;
669
const double scalings_y_0 = 1;
670
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
672
// Compute psitilde_a
673
const double psitilde_a_0 = 1;
674
const double psitilde_a_1 = x;
676
// Compute psitilde_bs
677
const double psitilde_bs_0_0 = 1;
678
const double psitilde_bs_0_1 = 1.5*y + 0.5;
679
const double psitilde_bs_1_0 = 1;
681
// Compute basisvalues
682
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
683
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
684
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
686
// Table(s) of coefficients
687
const static double coefficients0[3][3] = \
688
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
689
{0.471404520791032, 0.288675134594813, -0.166666666666667},
690
{0.471404520791032, 0, 0.333333333333333}};
692
// Interesting (new) part
693
// Tables of derivatives of the polynomial base (transpose)
694
const static double dmats0[3][3] = \
696
{4.89897948556636, 0, 0},
699
const static double dmats1[3][3] = \
701
{2.44948974278318, 0, 0},
702
{4.24264068711928, 0, 0}};
704
// Compute reference derivatives
705
// Declare pointer to array of derivatives on FIAT element
706
double *derivatives = new double [num_derivatives];
708
// Declare coefficients
713
// Declare new coefficients
714
double new_coeff0_0 = 0;
715
double new_coeff0_1 = 0;
716
double new_coeff0_2 = 0;
718
// Loop possible derivatives
719
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
721
// Get values from coefficients array
722
new_coeff0_0 = coefficients0[dof][0];
723
new_coeff0_1 = coefficients0[dof][1];
724
new_coeff0_2 = coefficients0[dof][2];
726
// Loop derivative order
727
for (unsigned int j = 0; j < n; j++)
729
// Update old coefficients
730
coeff0_0 = new_coeff0_0;
731
coeff0_1 = new_coeff0_1;
732
coeff0_2 = new_coeff0_2;
734
if(combinations[deriv_num][j] == 0)
736
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
737
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
738
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
740
if(combinations[deriv_num][j] == 1)
742
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
743
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
744
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
748
// Compute derivatives on reference element as dot product of coefficients and basisvalues
749
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
752
// Transform derivatives back to physical element
753
for (unsigned int row = 0; row < num_derivatives; row++)
755
for (unsigned int col = 0; col < num_derivatives; col++)
757
values[row] += transform[row][col]*derivatives[col];
760
// Delete pointer to array of derivatives on FIAT element
761
delete [] derivatives;
763
// Delete pointer to array of combinations of derivatives and transform
764
for (unsigned int row = 0; row < num_derivatives; row++)
766
delete [] combinations[row];
767
delete [] transform[row];
770
delete [] combinations;
774
/// Evaluate order n derivatives of all basis functions at given point in cell
775
virtual void evaluate_basis_derivatives_all(unsigned int n,
777
const double* coordinates,
778
const ufc::cell& c) const
780
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
783
/// Evaluate linear functional for dof i on the function f
784
virtual double evaluate_dof(unsigned int i,
785
const ufc::function& f,
786
const ufc::cell& c) const
788
// The reference points, direction and weights:
789
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
790
const static double W[3][1] = {{1}, {1}, {1}};
791
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
793
const double * const * x = c.coordinates;
795
// Iterate over the points:
796
// Evaluate basis functions for affine mapping
797
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
798
const double w1 = X[i][0][0];
799
const double w2 = X[i][0][1];
801
// Compute affine mapping y = F(X)
803
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
804
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
806
// Evaluate function at physical points
808
f.evaluate(values, y, c);
810
// Map function values using appropriate mapping
811
// Affine map: Do nothing
813
// Note that we do not map the weights (yet).
815
// Take directional components
816
for(int k = 0; k < 1; k++)
817
result += values[k]*D[i][0][k];
818
// Multiply by weights
824
/// Evaluate linear functionals for all dofs on the function f
825
virtual void evaluate_dofs(double* values,
826
const ufc::function& f,
827
const ufc::cell& c) const
829
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
832
/// Interpolate vertex values from dof values
833
virtual void interpolate_vertex_values(double* vertex_values,
834
const double* dof_values,
835
const ufc::cell& c) const
837
// Evaluate at vertices and use affine mapping
838
vertex_values[0] = dof_values[0];
839
vertex_values[1] = dof_values[1];
840
vertex_values[2] = dof_values[2];
843
/// Return the number of sub elements (for a mixed element)
844
virtual unsigned int num_sub_elements() const
849
/// Create a new finite element for sub element i (for a mixed element)
850
virtual ufc::finite_element* create_sub_element(unsigned int i) const
852
return new UFC_P1ProjectionBilinearForm_finite_element_1();
857
/// This class defines the interface for a local-to-global mapping of
858
/// degrees of freedom (dofs).
860
class UFC_P1ProjectionBilinearForm_dof_map_0: public ufc::dof_map
864
unsigned int __global_dimension;
869
UFC_P1ProjectionBilinearForm_dof_map_0() : ufc::dof_map()
871
__global_dimension = 0;
875
virtual ~UFC_P1ProjectionBilinearForm_dof_map_0()
880
/// Return a string identifying the dof map
881
virtual const char* signature() const
883
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
886
/// Return true iff mesh entities of topological dimension d are needed
887
virtual bool needs_mesh_entities(unsigned int d) const
904
/// Initialize dof map for mesh (return true iff init_cell() is needed)
905
virtual bool init_mesh(const ufc::mesh& m)
907
__global_dimension = m.num_entities[0];
911
/// Initialize dof map for given cell
912
virtual void init_cell(const ufc::mesh& m,
918
/// Finish initialization of dof map for cells
919
virtual void init_cell_finalize()
924
/// Return the dimension of the global finite element function space
925
virtual unsigned int global_dimension() const
927
return __global_dimension;
930
/// Return the dimension of the local finite element function space
931
virtual unsigned int local_dimension() const
936
// Return the geometric dimension of the coordinates this dof map provides
937
virtual unsigned int geometric_dimension() const
942
/// Return the number of dofs on each cell facet
943
virtual unsigned int num_facet_dofs() const
948
/// Return the number of dofs associated with each cell entity of dimension d
949
virtual unsigned int num_entity_dofs(unsigned int d) const
951
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
954
/// Tabulate the local-to-global mapping of dofs on a cell
955
virtual void tabulate_dofs(unsigned int* dofs,
957
const ufc::cell& c) const
959
dofs[0] = c.entity_indices[0][0];
960
dofs[1] = c.entity_indices[0][1];
961
dofs[2] = c.entity_indices[0][2];
964
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
965
virtual void tabulate_facet_dofs(unsigned int* dofs,
966
unsigned int facet) const
985
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
986
virtual void tabulate_entity_dofs(unsigned int* dofs,
987
unsigned int d, unsigned int i) const
989
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
992
/// Tabulate the coordinates of all dofs on a cell
993
virtual void tabulate_coordinates(double** coordinates,
994
const ufc::cell& c) const
996
const double * const * x = c.coordinates;
997
coordinates[0][0] = x[0][0];
998
coordinates[0][1] = x[0][1];
999
coordinates[1][0] = x[1][0];
1000
coordinates[1][1] = x[1][1];
1001
coordinates[2][0] = x[2][0];
1002
coordinates[2][1] = x[2][1];
1005
/// Return the number of sub dof maps (for a mixed element)
1006
virtual unsigned int num_sub_dof_maps() const
1011
/// Create a new dof_map for sub dof map i (for a mixed element)
1012
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1014
return new UFC_P1ProjectionBilinearForm_dof_map_0();
1019
/// This class defines the interface for a local-to-global mapping of
1020
/// degrees of freedom (dofs).
1022
class UFC_P1ProjectionBilinearForm_dof_map_1: public ufc::dof_map
1026
unsigned int __global_dimension;
1031
UFC_P1ProjectionBilinearForm_dof_map_1() : ufc::dof_map()
1033
__global_dimension = 0;
1037
virtual ~UFC_P1ProjectionBilinearForm_dof_map_1()
1042
/// Return a string identifying the dof map
1043
virtual const char* signature() const
1045
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
1048
/// Return true iff mesh entities of topological dimension d are needed
1049
virtual bool needs_mesh_entities(unsigned int d) const
1066
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1067
virtual bool init_mesh(const ufc::mesh& m)
1069
__global_dimension = m.num_entities[0];
1073
/// Initialize dof map for given cell
1074
virtual void init_cell(const ufc::mesh& m,
1080
/// Finish initialization of dof map for cells
1081
virtual void init_cell_finalize()
1086
/// Return the dimension of the global finite element function space
1087
virtual unsigned int global_dimension() const
1089
return __global_dimension;
1092
/// Return the dimension of the local finite element function space
1093
virtual unsigned int local_dimension() const
1098
// Return the geometric dimension of the coordinates this dof map provides
1099
virtual unsigned int geometric_dimension() const
1104
/// Return the number of dofs on each cell facet
1105
virtual unsigned int num_facet_dofs() const
1110
/// Return the number of dofs associated with each cell entity of dimension d
1111
virtual unsigned int num_entity_dofs(unsigned int d) const
1113
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1116
/// Tabulate the local-to-global mapping of dofs on a cell
1117
virtual void tabulate_dofs(unsigned int* dofs,
1119
const ufc::cell& c) const
1121
dofs[0] = c.entity_indices[0][0];
1122
dofs[1] = c.entity_indices[0][1];
1123
dofs[2] = c.entity_indices[0][2];
1126
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1127
virtual void tabulate_facet_dofs(unsigned int* dofs,
1128
unsigned int facet) const
1147
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1148
virtual void tabulate_entity_dofs(unsigned int* dofs,
1149
unsigned int d, unsigned int i) const
1151
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1154
/// Tabulate the coordinates of all dofs on a cell
1155
virtual void tabulate_coordinates(double** coordinates,
1156
const ufc::cell& c) const
1158
const double * const * x = c.coordinates;
1159
coordinates[0][0] = x[0][0];
1160
coordinates[0][1] = x[0][1];
1161
coordinates[1][0] = x[1][0];
1162
coordinates[1][1] = x[1][1];
1163
coordinates[2][0] = x[2][0];
1164
coordinates[2][1] = x[2][1];
1167
/// Return the number of sub dof maps (for a mixed element)
1168
virtual unsigned int num_sub_dof_maps() const
1173
/// Create a new dof_map for sub dof map i (for a mixed element)
1174
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1176
return new UFC_P1ProjectionBilinearForm_dof_map_1();
1181
/// This class defines the interface for the tabulation of the cell
1182
/// tensor corresponding to the local contribution to a form from
1183
/// the integral over a cell.
1185
class UFC_P1ProjectionBilinearForm_cell_integral_0: public ufc::cell_integral
1190
UFC_P1ProjectionBilinearForm_cell_integral_0() : ufc::cell_integral()
1196
virtual ~UFC_P1ProjectionBilinearForm_cell_integral_0()
1201
/// Tabulate the tensor for the contribution from a local cell
1202
virtual void tabulate_tensor(double* A,
1203
const double * const * w,
1204
const ufc::cell& c) const
1206
// Extract vertex coordinates
1207
const double * const * x = c.coordinates;
1209
// Compute Jacobian of affine map from reference cell
1210
const double J_00 = x[1][0] - x[0][0];
1211
const double J_01 = x[2][0] - x[0][0];
1212
const double J_10 = x[1][1] - x[0][1];
1213
const double J_11 = x[2][1] - x[0][1];
1215
// Compute determinant of Jacobian
1216
double detJ = J_00*J_11 - J_01*J_10;
1218
// Compute inverse of Jacobian
1221
const double det = std::abs(detJ);
1223
// Number of operations to compute element tensor = 10
1224
// Compute geometry tensors
1225
// Number of operations to compute decalrations = 1
1226
const double G0_ = det;
1228
// Compute element tensor
1229
// Number of operations to compute tensor = 9
1230
A[0] = 0.0833333333333332*G0_;
1231
A[1] = 0.0416666666666666*G0_;
1232
A[2] = 0.0416666666666666*G0_;
1233
A[3] = 0.0416666666666666*G0_;
1234
A[4] = 0.0833333333333332*G0_;
1235
A[5] = 0.0416666666666666*G0_;
1236
A[6] = 0.0416666666666666*G0_;
1237
A[7] = 0.0416666666666666*G0_;
1238
A[8] = 0.0833333333333332*G0_;
1243
/// This class defines the interface for the assembly of the global
1244
/// tensor corresponding to a form with r + n arguments, that is, a
1247
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
1249
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
1250
/// global tensor A is defined by
1252
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
1254
/// where each argument Vj represents the application to the
1255
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
1256
/// fixed functions (coefficients).
1258
class UFC_P1ProjectionBilinearForm: public ufc::form
1263
UFC_P1ProjectionBilinearForm() : ufc::form()
1269
virtual ~UFC_P1ProjectionBilinearForm()
1274
/// Return a string identifying the form
1275
virtual const char* signature() const
1277
return " | vi0[0, 1, 2]*vi1[0, 1, 2]*dX(0)";
1280
/// Return the rank of the global tensor (r)
1281
virtual unsigned int rank() const
1286
/// Return the number of coefficients (n)
1287
virtual unsigned int num_coefficients() const
1292
/// Return the number of cell integrals
1293
virtual unsigned int num_cell_integrals() const
1298
/// Return the number of exterior facet integrals
1299
virtual unsigned int num_exterior_facet_integrals() const
1304
/// Return the number of interior facet integrals
1305
virtual unsigned int num_interior_facet_integrals() const
1310
/// Create a new finite element for argument function i
1311
virtual ufc::finite_element* create_finite_element(unsigned int i) const
1316
return new UFC_P1ProjectionBilinearForm_finite_element_0();
1319
return new UFC_P1ProjectionBilinearForm_finite_element_1();
1325
/// Create a new dof map for argument function i
1326
virtual ufc::dof_map* create_dof_map(unsigned int i) const
1331
return new UFC_P1ProjectionBilinearForm_dof_map_0();
1334
return new UFC_P1ProjectionBilinearForm_dof_map_1();
1340
/// Create a new cell integral on sub domain i
1341
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
1343
return new UFC_P1ProjectionBilinearForm_cell_integral_0();
1346
/// Create a new exterior facet integral on sub domain i
1347
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
1352
/// Create a new interior facet integral on sub domain i
1353
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
1360
/// This class defines the interface for a finite element.
1362
class UFC_P1ProjectionLinearForm_finite_element_0: public ufc::finite_element
1367
UFC_P1ProjectionLinearForm_finite_element_0() : ufc::finite_element()
1373
virtual ~UFC_P1ProjectionLinearForm_finite_element_0()
1378
/// Return a string identifying the finite element
1379
virtual const char* signature() const
1381
return "FiniteElement('Lagrange', 'triangle', 1)";
1384
/// Return the cell shape
1385
virtual ufc::shape cell_shape() const
1387
return ufc::triangle;
1390
/// Return the dimension of the finite element function space
1391
virtual unsigned int space_dimension() const
1396
/// Return the rank of the value space
1397
virtual unsigned int value_rank() const
1402
/// Return the dimension of the value space for axis i
1403
virtual unsigned int value_dimension(unsigned int i) const
1408
/// Evaluate basis function i at given point in cell
1409
virtual void evaluate_basis(unsigned int i,
1411
const double* coordinates,
1412
const ufc::cell& c) const
1414
// Extract vertex coordinates
1415
const double * const * element_coordinates = c.coordinates;
1417
// Compute Jacobian of affine map from reference cell
1418
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1419
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1420
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1421
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1423
// Compute determinant of Jacobian
1424
const double detJ = J_00*J_11 - J_01*J_10;
1426
// Compute inverse of Jacobian
1428
// Get coordinates and map to the reference (UFC) element
1429
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1430
element_coordinates[0][0]*element_coordinates[2][1] +\
1431
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1432
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1433
element_coordinates[1][0]*element_coordinates[0][1] -\
1434
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1436
// Map coordinates to the reference square
1437
if (std::abs(y - 1.0) < 1e-14)
1440
x = 2.0 *x/(1.0 - y) - 1.0;
1446
// Map degree of freedom to element degree of freedom
1447
const unsigned int dof = i;
1449
// Generate scalings
1450
const double scalings_y_0 = 1;
1451
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1453
// Compute psitilde_a
1454
const double psitilde_a_0 = 1;
1455
const double psitilde_a_1 = x;
1457
// Compute psitilde_bs
1458
const double psitilde_bs_0_0 = 1;
1459
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1460
const double psitilde_bs_1_0 = 1;
1462
// Compute basisvalues
1463
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1464
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1465
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1467
// Table(s) of coefficients
1468
const static double coefficients0[3][3] = \
1469
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1470
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1471
{0.471404520791032, 0, 0.333333333333333}};
1473
// Extract relevant coefficients
1474
const double coeff0_0 = coefficients0[dof][0];
1475
const double coeff0_1 = coefficients0[dof][1];
1476
const double coeff0_2 = coefficients0[dof][2];
1479
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1482
/// Evaluate all basis functions at given point in cell
1483
virtual void evaluate_basis_all(double* values,
1484
const double* coordinates,
1485
const ufc::cell& c) const
1487
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1490
/// Evaluate order n derivatives of basis function i at given point in cell
1491
virtual void evaluate_basis_derivatives(unsigned int i,
1494
const double* coordinates,
1495
const ufc::cell& c) const
1497
// Extract vertex coordinates
1498
const double * const * element_coordinates = c.coordinates;
1500
// Compute Jacobian of affine map from reference cell
1501
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1502
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1503
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1504
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1506
// Compute determinant of Jacobian
1507
const double detJ = J_00*J_11 - J_01*J_10;
1509
// Compute inverse of Jacobian
1511
// Get coordinates and map to the reference (UFC) element
1512
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1513
element_coordinates[0][0]*element_coordinates[2][1] +\
1514
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1515
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1516
element_coordinates[1][0]*element_coordinates[0][1] -\
1517
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1519
// Map coordinates to the reference square
1520
if (std::abs(y - 1.0) < 1e-14)
1523
x = 2.0 *x/(1.0 - y) - 1.0;
1526
// Compute number of derivatives
1527
unsigned int num_derivatives = 1;
1529
for (unsigned int j = 0; j < n; j++)
1530
num_derivatives *= 2;
1533
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1534
unsigned int **combinations = new unsigned int *[num_derivatives];
1536
for (unsigned int j = 0; j < num_derivatives; j++)
1538
combinations[j] = new unsigned int [n];
1539
for (unsigned int k = 0; k < n; k++)
1540
combinations[j][k] = 0;
1543
// Generate combinations of derivatives
1544
for (unsigned int row = 1; row < num_derivatives; row++)
1546
for (unsigned int num = 0; num < row; num++)
1548
for (unsigned int col = n-1; col+1 > 0; col--)
1550
if (combinations[row][col] + 1 > 1)
1551
combinations[row][col] = 0;
1554
combinations[row][col] += 1;
1561
// Compute inverse of Jacobian
1562
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1564
// Declare transformation matrix
1565
// Declare pointer to two dimensional array and initialise
1566
double **transform = new double *[num_derivatives];
1568
for (unsigned int j = 0; j < num_derivatives; j++)
1570
transform[j] = new double [num_derivatives];
1571
for (unsigned int k = 0; k < num_derivatives; k++)
1572
transform[j][k] = 1;
1575
// Construct transformation matrix
1576
for (unsigned int row = 0; row < num_derivatives; row++)
1578
for (unsigned int col = 0; col < num_derivatives; col++)
1580
for (unsigned int k = 0; k < n; k++)
1581
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1586
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1589
// Map degree of freedom to element degree of freedom
1590
const unsigned int dof = i;
1592
// Generate scalings
1593
const double scalings_y_0 = 1;
1594
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1596
// Compute psitilde_a
1597
const double psitilde_a_0 = 1;
1598
const double psitilde_a_1 = x;
1600
// Compute psitilde_bs
1601
const double psitilde_bs_0_0 = 1;
1602
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1603
const double psitilde_bs_1_0 = 1;
1605
// Compute basisvalues
1606
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1607
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1608
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1610
// Table(s) of coefficients
1611
const static double coefficients0[3][3] = \
1612
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1613
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1614
{0.471404520791032, 0, 0.333333333333333}};
1616
// Interesting (new) part
1617
// Tables of derivatives of the polynomial base (transpose)
1618
const static double dmats0[3][3] = \
1620
{4.89897948556636, 0, 0},
1623
const static double dmats1[3][3] = \
1625
{2.44948974278318, 0, 0},
1626
{4.24264068711928, 0, 0}};
1628
// Compute reference derivatives
1629
// Declare pointer to array of derivatives on FIAT element
1630
double *derivatives = new double [num_derivatives];
1632
// Declare coefficients
1633
double coeff0_0 = 0;
1634
double coeff0_1 = 0;
1635
double coeff0_2 = 0;
1637
// Declare new coefficients
1638
double new_coeff0_0 = 0;
1639
double new_coeff0_1 = 0;
1640
double new_coeff0_2 = 0;
1642
// Loop possible derivatives
1643
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1645
// Get values from coefficients array
1646
new_coeff0_0 = coefficients0[dof][0];
1647
new_coeff0_1 = coefficients0[dof][1];
1648
new_coeff0_2 = coefficients0[dof][2];
1650
// Loop derivative order
1651
for (unsigned int j = 0; j < n; j++)
1653
// Update old coefficients
1654
coeff0_0 = new_coeff0_0;
1655
coeff0_1 = new_coeff0_1;
1656
coeff0_2 = new_coeff0_2;
1658
if(combinations[deriv_num][j] == 0)
1660
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1661
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1662
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1664
if(combinations[deriv_num][j] == 1)
1666
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1667
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1668
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1672
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1673
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1676
// Transform derivatives back to physical element
1677
for (unsigned int row = 0; row < num_derivatives; row++)
1679
for (unsigned int col = 0; col < num_derivatives; col++)
1681
values[row] += transform[row][col]*derivatives[col];
1684
// Delete pointer to array of derivatives on FIAT element
1685
delete [] derivatives;
1687
// Delete pointer to array of combinations of derivatives and transform
1688
for (unsigned int row = 0; row < num_derivatives; row++)
1690
delete [] combinations[row];
1691
delete [] transform[row];
1694
delete [] combinations;
1695
delete [] transform;
1698
/// Evaluate order n derivatives of all basis functions at given point in cell
1699
virtual void evaluate_basis_derivatives_all(unsigned int n,
1701
const double* coordinates,
1702
const ufc::cell& c) const
1704
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1707
/// Evaluate linear functional for dof i on the function f
1708
virtual double evaluate_dof(unsigned int i,
1709
const ufc::function& f,
1710
const ufc::cell& c) const
1712
// The reference points, direction and weights:
1713
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
1714
const static double W[3][1] = {{1}, {1}, {1}};
1715
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
1717
const double * const * x = c.coordinates;
1718
double result = 0.0;
1719
// Iterate over the points:
1720
// Evaluate basis functions for affine mapping
1721
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1722
const double w1 = X[i][0][0];
1723
const double w2 = X[i][0][1];
1725
// Compute affine mapping y = F(X)
1727
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1728
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1730
// Evaluate function at physical points
1732
f.evaluate(values, y, c);
1734
// Map function values using appropriate mapping
1735
// Affine map: Do nothing
1737
// Note that we do not map the weights (yet).
1739
// Take directional components
1740
for(int k = 0; k < 1; k++)
1741
result += values[k]*D[i][0][k];
1742
// Multiply by weights
1748
/// Evaluate linear functionals for all dofs on the function f
1749
virtual void evaluate_dofs(double* values,
1750
const ufc::function& f,
1751
const ufc::cell& c) const
1753
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1756
/// Interpolate vertex values from dof values
1757
virtual void interpolate_vertex_values(double* vertex_values,
1758
const double* dof_values,
1759
const ufc::cell& c) const
1761
// Evaluate at vertices and use affine mapping
1762
vertex_values[0] = dof_values[0];
1763
vertex_values[1] = dof_values[1];
1764
vertex_values[2] = dof_values[2];
1767
/// Return the number of sub elements (for a mixed element)
1768
virtual unsigned int num_sub_elements() const
1773
/// Create a new finite element for sub element i (for a mixed element)
1774
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1776
return new UFC_P1ProjectionLinearForm_finite_element_0();
1781
/// This class defines the interface for a finite element.
1783
class UFC_P1ProjectionLinearForm_finite_element_1: public ufc::finite_element
1788
UFC_P1ProjectionLinearForm_finite_element_1() : ufc::finite_element()
1794
virtual ~UFC_P1ProjectionLinearForm_finite_element_1()
1799
/// Return a string identifying the finite element
1800
virtual const char* signature() const
1802
return "FiniteElement('Discontinuous Lagrange', 'triangle', 1)";
1805
/// Return the cell shape
1806
virtual ufc::shape cell_shape() const
1808
return ufc::triangle;
1811
/// Return the dimension of the finite element function space
1812
virtual unsigned int space_dimension() const
1817
/// Return the rank of the value space
1818
virtual unsigned int value_rank() const
1823
/// Return the dimension of the value space for axis i
1824
virtual unsigned int value_dimension(unsigned int i) const
1829
/// Evaluate basis function i at given point in cell
1830
virtual void evaluate_basis(unsigned int i,
1832
const double* coordinates,
1833
const ufc::cell& c) const
1835
// Extract vertex coordinates
1836
const double * const * element_coordinates = c.coordinates;
1838
// Compute Jacobian of affine map from reference cell
1839
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1840
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1841
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1842
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1844
// Compute determinant of Jacobian
1845
const double detJ = J_00*J_11 - J_01*J_10;
1847
// Compute inverse of Jacobian
1849
// Get coordinates and map to the reference (UFC) element
1850
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1851
element_coordinates[0][0]*element_coordinates[2][1] +\
1852
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1853
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1854
element_coordinates[1][0]*element_coordinates[0][1] -\
1855
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1857
// Map coordinates to the reference square
1858
if (std::abs(y - 1.0) < 1e-14)
1861
x = 2.0 *x/(1.0 - y) - 1.0;
1867
// Map degree of freedom to element degree of freedom
1868
const unsigned int dof = i;
1870
// Generate scalings
1871
const double scalings_y_0 = 1;
1872
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1874
// Compute psitilde_a
1875
const double psitilde_a_0 = 1;
1876
const double psitilde_a_1 = x;
1878
// Compute psitilde_bs
1879
const double psitilde_bs_0_0 = 1;
1880
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1881
const double psitilde_bs_1_0 = 1;
1883
// Compute basisvalues
1884
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1885
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1886
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1888
// Table(s) of coefficients
1889
const static double coefficients0[3][3] = \
1890
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
1891
{0.471404520791032, 0.288675134594813, -0.166666666666667},
1892
{0.471404520791032, 0, 0.333333333333333}};
1894
// Extract relevant coefficients
1895
const double coeff0_0 = coefficients0[dof][0];
1896
const double coeff0_1 = coefficients0[dof][1];
1897
const double coeff0_2 = coefficients0[dof][2];
1900
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1903
/// Evaluate all basis functions at given point in cell
1904
virtual void evaluate_basis_all(double* values,
1905
const double* coordinates,
1906
const ufc::cell& c) const
1908
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1911
/// Evaluate order n derivatives of basis function i at given point in cell
1912
virtual void evaluate_basis_derivatives(unsigned int i,
1915
const double* coordinates,
1916
const ufc::cell& c) const
1918
// Extract vertex coordinates
1919
const double * const * element_coordinates = c.coordinates;
1921
// Compute Jacobian of affine map from reference cell
1922
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1923
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1924
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1925
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1927
// Compute determinant of Jacobian
1928
const double detJ = J_00*J_11 - J_01*J_10;
1930
// Compute inverse of Jacobian
1932
// Get coordinates and map to the reference (UFC) element
1933
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1934
element_coordinates[0][0]*element_coordinates[2][1] +\
1935
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1936
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1937
element_coordinates[1][0]*element_coordinates[0][1] -\
1938
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1940
// Map coordinates to the reference square
1941
if (std::abs(y - 1.0) < 1e-14)
1944
x = 2.0 *x/(1.0 - y) - 1.0;
1947
// Compute number of derivatives
1948
unsigned int num_derivatives = 1;
1950
for (unsigned int j = 0; j < n; j++)
1951
num_derivatives *= 2;
1954
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1955
unsigned int **combinations = new unsigned int *[num_derivatives];
1957
for (unsigned int j = 0; j < num_derivatives; j++)
1959
combinations[j] = new unsigned int [n];
1960
for (unsigned int k = 0; k < n; k++)
1961
combinations[j][k] = 0;
1964
// Generate combinations of derivatives
1965
for (unsigned int row = 1; row < num_derivatives; row++)
1967
for (unsigned int num = 0; num < row; num++)
1969
for (unsigned int col = n-1; col+1 > 0; col--)
1971
if (combinations[row][col] + 1 > 1)
1972
combinations[row][col] = 0;
1975
combinations[row][col] += 1;
1982
// Compute inverse of Jacobian
1983
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1985
// Declare transformation matrix
1986
// Declare pointer to two dimensional array and initialise
1987
double **transform = new double *[num_derivatives];
1989
for (unsigned int j = 0; j < num_derivatives; j++)
1991
transform[j] = new double [num_derivatives];
1992
for (unsigned int k = 0; k < num_derivatives; k++)
1993
transform[j][k] = 1;
1996
// Construct transformation matrix
1997
for (unsigned int row = 0; row < num_derivatives; row++)
1999
for (unsigned int col = 0; col < num_derivatives; col++)
2001
for (unsigned int k = 0; k < n; k++)
2002
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2007
for (unsigned int j = 0; j < 1*num_derivatives; j++)
2010
// Map degree of freedom to element degree of freedom
2011
const unsigned int dof = i;
2013
// Generate scalings
2014
const double scalings_y_0 = 1;
2015
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2017
// Compute psitilde_a
2018
const double psitilde_a_0 = 1;
2019
const double psitilde_a_1 = x;
2021
// Compute psitilde_bs
2022
const double psitilde_bs_0_0 = 1;
2023
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2024
const double psitilde_bs_1_0 = 1;
2026
// Compute basisvalues
2027
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2028
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2029
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2031
// Table(s) of coefficients
2032
const static double coefficients0[3][3] = \
2033
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
2034
{0.471404520791032, 0.288675134594813, -0.166666666666667},
2035
{0.471404520791032, 0, 0.333333333333333}};
2037
// Interesting (new) part
2038
// Tables of derivatives of the polynomial base (transpose)
2039
const static double dmats0[3][3] = \
2041
{4.89897948556636, 0, 0},
2044
const static double dmats1[3][3] = \
2046
{2.44948974278318, 0, 0},
2047
{4.24264068711928, 0, 0}};
2049
// Compute reference derivatives
2050
// Declare pointer to array of derivatives on FIAT element
2051
double *derivatives = new double [num_derivatives];
2053
// Declare coefficients
2054
double coeff0_0 = 0;
2055
double coeff0_1 = 0;
2056
double coeff0_2 = 0;
2058
// Declare new coefficients
2059
double new_coeff0_0 = 0;
2060
double new_coeff0_1 = 0;
2061
double new_coeff0_2 = 0;
2063
// Loop possible derivatives
2064
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2066
// Get values from coefficients array
2067
new_coeff0_0 = coefficients0[dof][0];
2068
new_coeff0_1 = coefficients0[dof][1];
2069
new_coeff0_2 = coefficients0[dof][2];
2071
// Loop derivative order
2072
for (unsigned int j = 0; j < n; j++)
2074
// Update old coefficients
2075
coeff0_0 = new_coeff0_0;
2076
coeff0_1 = new_coeff0_1;
2077
coeff0_2 = new_coeff0_2;
2079
if(combinations[deriv_num][j] == 0)
2081
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2082
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2083
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2085
if(combinations[deriv_num][j] == 1)
2087
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2088
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2089
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2093
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2094
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2097
// Transform derivatives back to physical element
2098
for (unsigned int row = 0; row < num_derivatives; row++)
2100
for (unsigned int col = 0; col < num_derivatives; col++)
2102
values[row] += transform[row][col]*derivatives[col];
2105
// Delete pointer to array of derivatives on FIAT element
2106
delete [] derivatives;
2108
// Delete pointer to array of combinations of derivatives and transform
2109
for (unsigned int row = 0; row < num_derivatives; row++)
2111
delete [] combinations[row];
2112
delete [] transform[row];
2115
delete [] combinations;
2116
delete [] transform;
2119
/// Evaluate order n derivatives of all basis functions at given point in cell
2120
virtual void evaluate_basis_derivatives_all(unsigned int n,
2122
const double* coordinates,
2123
const ufc::cell& c) const
2125
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2128
/// Evaluate linear functional for dof i on the function f
2129
virtual double evaluate_dof(unsigned int i,
2130
const ufc::function& f,
2131
const ufc::cell& c) const
2133
// The reference points, direction and weights:
2134
const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
2135
const static double W[3][1] = {{1}, {1}, {1}};
2136
const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
2138
const double * const * x = c.coordinates;
2139
double result = 0.0;
2140
// Iterate over the points:
2141
// Evaluate basis functions for affine mapping
2142
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2143
const double w1 = X[i][0][0];
2144
const double w2 = X[i][0][1];
2146
// Compute affine mapping y = F(X)
2148
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2149
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2151
// Evaluate function at physical points
2153
f.evaluate(values, y, c);
2155
// Map function values using appropriate mapping
2156
// Affine map: Do nothing
2158
// Note that we do not map the weights (yet).
2160
// Take directional components
2161
for(int k = 0; k < 1; k++)
2162
result += values[k]*D[i][0][k];
2163
// Multiply by weights
2169
/// Evaluate linear functionals for all dofs on the function f
2170
virtual void evaluate_dofs(double* values,
2171
const ufc::function& f,
2172
const ufc::cell& c) const
2174
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2177
/// Interpolate vertex values from dof values
2178
virtual void interpolate_vertex_values(double* vertex_values,
2179
const double* dof_values,
2180
const ufc::cell& c) const
2182
// Evaluate at vertices and use affine mapping
2183
vertex_values[0] = dof_values[0];
2184
vertex_values[1] = dof_values[1];
2185
vertex_values[2] = dof_values[2];
2188
/// Return the number of sub elements (for a mixed element)
2189
virtual unsigned int num_sub_elements() const
2194
/// Create a new finite element for sub element i (for a mixed element)
2195
virtual ufc::finite_element* create_sub_element(unsigned int i) const
2197
return new UFC_P1ProjectionLinearForm_finite_element_1();
2202
/// This class defines the interface for a local-to-global mapping of
2203
/// degrees of freedom (dofs).
2205
class UFC_P1ProjectionLinearForm_dof_map_0: public ufc::dof_map
2209
unsigned int __global_dimension;
2214
UFC_P1ProjectionLinearForm_dof_map_0() : ufc::dof_map()
2216
__global_dimension = 0;
2220
virtual ~UFC_P1ProjectionLinearForm_dof_map_0()
2225
/// Return a string identifying the dof map
2226
virtual const char* signature() const
2228
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
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 = m.num_entities[0];
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
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[0][0];
2305
dofs[1] = c.entity_indices[0][1];
2306
dofs[2] = c.entity_indices[0][2];
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
2330
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2331
virtual void tabulate_entity_dofs(unsigned int* dofs,
2332
unsigned int d, unsigned int i) const
2334
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2337
/// Tabulate the coordinates of all dofs on a cell
2338
virtual void tabulate_coordinates(double** coordinates,
2339
const ufc::cell& c) const
2341
const double * const * x = c.coordinates;
2342
coordinates[0][0] = x[0][0];
2343
coordinates[0][1] = x[0][1];
2344
coordinates[1][0] = x[1][0];
2345
coordinates[1][1] = x[1][1];
2346
coordinates[2][0] = x[2][0];
2347
coordinates[2][1] = x[2][1];
2350
/// Return the number of sub dof maps (for a mixed element)
2351
virtual unsigned int num_sub_dof_maps() const
2356
/// Create a new dof_map for sub dof map i (for a mixed element)
2357
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2359
return new UFC_P1ProjectionLinearForm_dof_map_0();
2364
/// This class defines the interface for a local-to-global mapping of
2365
/// degrees of freedom (dofs).
2367
class UFC_P1ProjectionLinearForm_dof_map_1: public ufc::dof_map
2371
unsigned int __global_dimension;
2376
UFC_P1ProjectionLinearForm_dof_map_1() : ufc::dof_map()
2378
__global_dimension = 0;
2382
virtual ~UFC_P1ProjectionLinearForm_dof_map_1()
2387
/// Return a string identifying the dof map
2388
virtual const char* signature() const
2390
return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 1)";
2393
/// Return true iff mesh entities of topological dimension d are needed
2394
virtual bool needs_mesh_entities(unsigned int d) const
2411
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2412
virtual bool init_mesh(const ufc::mesh& m)
2414
__global_dimension = 3*m.num_entities[2];
2418
/// Initialize dof map for given cell
2419
virtual void init_cell(const ufc::mesh& m,
2425
/// Finish initialization of dof map for cells
2426
virtual void init_cell_finalize()
2431
/// Return the dimension of the global finite element function space
2432
virtual unsigned int global_dimension() const
2434
return __global_dimension;
2437
/// Return the dimension of the local finite element function space
2438
virtual unsigned int local_dimension() const
2443
// Return the geometric dimension of the coordinates this dof map provides
2444
virtual unsigned int geometric_dimension() const
2449
/// Return the number of dofs on each cell facet
2450
virtual unsigned int num_facet_dofs() const
2455
/// Return the number of dofs associated with each cell entity of dimension d
2456
virtual unsigned int num_entity_dofs(unsigned int d) const
2458
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2461
/// Tabulate the local-to-global mapping of dofs on a cell
2462
virtual void tabulate_dofs(unsigned int* dofs,
2464
const ufc::cell& c) const
2466
dofs[0] = 3*c.entity_indices[2][0];
2467
dofs[1] = 3*c.entity_indices[2][0] + 1;
2468
dofs[2] = 3*c.entity_indices[2][0] + 2;
2471
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2472
virtual void tabulate_facet_dofs(unsigned int* dofs,
2473
unsigned int facet) const
2489
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2490
virtual void tabulate_entity_dofs(unsigned int* dofs,
2491
unsigned int d, unsigned int i) const
2493
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2496
/// Tabulate the coordinates of all dofs on a cell
2497
virtual void tabulate_coordinates(double** coordinates,
2498
const ufc::cell& c) const
2500
const double * const * x = c.coordinates;
2501
coordinates[0][0] = x[0][0];
2502
coordinates[0][1] = x[0][1];
2503
coordinates[1][0] = x[1][0];
2504
coordinates[1][1] = x[1][1];
2505
coordinates[2][0] = x[2][0];
2506
coordinates[2][1] = x[2][1];
2509
/// Return the number of sub dof maps (for a mixed element)
2510
virtual unsigned int num_sub_dof_maps() const
2515
/// Create a new dof_map for sub dof map i (for a mixed element)
2516
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2518
return new UFC_P1ProjectionLinearForm_dof_map_1();
2523
/// This class defines the interface for the tabulation of the cell
2524
/// tensor corresponding to the local contribution to a form from
2525
/// the integral over a cell.
2527
class UFC_P1ProjectionLinearForm_cell_integral_0: public ufc::cell_integral
2532
UFC_P1ProjectionLinearForm_cell_integral_0() : ufc::cell_integral()
2538
virtual ~UFC_P1ProjectionLinearForm_cell_integral_0()
2543
/// Tabulate the tensor for the contribution from a local cell
2544
virtual void tabulate_tensor(double* A,
2545
const double * const * w,
2546
const ufc::cell& c) const
2548
// Extract vertex coordinates
2549
const double * const * x = c.coordinates;
2551
// Compute Jacobian of affine map from reference cell
2552
const double J_00 = x[1][0] - x[0][0];
2553
const double J_01 = x[2][0] - x[0][0];
2554
const double J_10 = x[1][1] - x[0][1];
2555
const double J_11 = x[2][1] - x[0][1];
2557
// Compute determinant of Jacobian
2558
double detJ = J_00*J_11 - J_01*J_10;
2560
// Compute inverse of Jacobian
2563
const double det = std::abs(detJ);
2565
// Number of operations to compute element tensor = 18
2566
// Compute coefficients
2567
const double c0_0_0_0 = w[0][0];
2568
const double c0_0_0_1 = w[0][1];
2569
const double c0_0_0_2 = w[0][2];
2571
// Compute geometry tensors
2572
// Number of operations to compute decalrations = 3
2573
const double G0_0 = det*c0_0_0_0;
2574
const double G0_1 = det*c0_0_0_1;
2575
const double G0_2 = det*c0_0_0_2;
2577
// Compute element tensor
2578
// Number of operations to compute tensor = 15
2579
A[0] = 0.0833333333333332*G0_0 + 0.0416666666666666*G0_1 + 0.0416666666666666*G0_2;
2580
A[1] = 0.0416666666666666*G0_0 + 0.0833333333333332*G0_1 + 0.0416666666666666*G0_2;
2581
A[2] = 0.0416666666666666*G0_0 + 0.0416666666666666*G0_1 + 0.0833333333333332*G0_2;
2586
/// This class defines the interface for the assembly of the global
2587
/// tensor corresponding to a form with r + n arguments, that is, a
2590
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2592
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2593
/// global tensor A is defined by
2595
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2597
/// where each argument Vj represents the application to the
2598
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2599
/// fixed functions (coefficients).
2601
class UFC_P1ProjectionLinearForm: public ufc::form
2606
UFC_P1ProjectionLinearForm() : ufc::form()
2612
virtual ~UFC_P1ProjectionLinearForm()
2617
/// Return a string identifying the form
2618
virtual const char* signature() const
2620
return "w0_a0[0, 1, 2] | vi0[0, 1, 2]*va0[0, 1, 2]*dX(0)";
2623
/// Return the rank of the global tensor (r)
2624
virtual unsigned int rank() const
2629
/// Return the number of coefficients (n)
2630
virtual unsigned int num_coefficients() const
2635
/// Return the number of cell integrals
2636
virtual unsigned int num_cell_integrals() const
2641
/// Return the number of exterior facet integrals
2642
virtual unsigned int num_exterior_facet_integrals() const
2647
/// Return the number of interior facet integrals
2648
virtual unsigned int num_interior_facet_integrals() const
2653
/// Create a new finite element for argument function i
2654
virtual ufc::finite_element* create_finite_element(unsigned int i) const
2659
return new UFC_P1ProjectionLinearForm_finite_element_0();
2662
return new UFC_P1ProjectionLinearForm_finite_element_1();
2668
/// Create a new dof map for argument function i
2669
virtual ufc::dof_map* create_dof_map(unsigned int i) const
2674
return new UFC_P1ProjectionLinearForm_dof_map_0();
2677
return new UFC_P1ProjectionLinearForm_dof_map_1();
2683
/// Create a new cell integral on sub domain i
2684
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
2686
return new UFC_P1ProjectionLinearForm_cell_integral_0();
2689
/// Create a new exterior facet integral on sub domain i
2690
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
2695
/// Create a new interior facet integral on sub domain i
2696
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
2705
#include <dolfin/fem/Form.h>
2706
#include <dolfin/fem/FiniteElement.h>
2707
#include <dolfin/fem/DofMap.h>
2708
#include <dolfin/function/Coefficient.h>
2709
#include <dolfin/function/Function.h>
2710
#include <dolfin/function/FunctionSpace.h>
2712
class P1ProjectionBilinearFormFunctionSpace0 : public dolfin::FunctionSpace
2716
P1ProjectionBilinearFormFunctionSpace0(const dolfin::Mesh& mesh)
2717
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2718
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_0()))),
2719
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_0()), mesh)))
2726
class P1ProjectionBilinearFormFunctionSpace1 : public dolfin::FunctionSpace
2730
P1ProjectionBilinearFormFunctionSpace1(const dolfin::Mesh& mesh)
2731
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2732
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_0()))),
2733
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_0()), mesh)))
2740
class P1ProjectionLinearFormFunctionSpace0 : public dolfin::FunctionSpace
2744
P1ProjectionLinearFormFunctionSpace0(const dolfin::Mesh& mesh)
2745
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2746
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_0()))),
2747
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_0()), mesh)))
2754
class P1ProjectionLinearFormCoefficientSpace0 : public dolfin::FunctionSpace
2758
P1ProjectionLinearFormCoefficientSpace0(const dolfin::Mesh& mesh)
2759
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2760
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_1()))),
2761
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_1()), mesh)))
2768
class P1ProjectionTestSpace : public dolfin::FunctionSpace
2772
P1ProjectionTestSpace(const dolfin::Mesh& mesh)
2773
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2774
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_0()))),
2775
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_0()), mesh)))
2782
class P1ProjectionTrialSpace : public dolfin::FunctionSpace
2786
P1ProjectionTrialSpace(const dolfin::Mesh& mesh)
2787
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2788
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_0()))),
2789
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_0()), mesh)))
2796
class P1ProjectionCoefficientSpace : public dolfin::FunctionSpace
2800
P1ProjectionCoefficientSpace(const dolfin::Mesh& mesh)
2801
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2802
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_1()))),
2803
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_1()), mesh)))
2810
class P1ProjectionFunctionSpace : public dolfin::FunctionSpace
2814
P1ProjectionFunctionSpace(const dolfin::Mesh& mesh)
2815
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2816
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_P1ProjectionLinearForm_finite_element_0()))),
2817
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_P1ProjectionLinearForm_dof_map_0()), mesh)))
2824
class P1ProjectionBilinearForm : public dolfin::Form
2828
// Create form on given function space(s)
2829
P1ProjectionBilinearForm(const dolfin::FunctionSpace& V0, const dolfin::FunctionSpace& V1) : dolfin::Form()
2831
boost::shared_ptr<const dolfin::FunctionSpace> _V0(&V0, dolfin::NoDeleter<const dolfin::FunctionSpace>());
2832
_function_spaces.push_back(_V0);
2833
boost::shared_ptr<const dolfin::FunctionSpace> _V1(&V1, dolfin::NoDeleter<const dolfin::FunctionSpace>());
2834
_function_spaces.push_back(_V1);
2836
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_P1ProjectionBilinearForm());
2839
// Create form on given function space(s) (shared data)
2840
P1ProjectionBilinearForm(boost::shared_ptr<const dolfin::FunctionSpace> V0, boost::shared_ptr<const dolfin::FunctionSpace> V1) : dolfin::Form()
2842
_function_spaces.push_back(V0);
2843
_function_spaces.push_back(V1);
2845
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_P1ProjectionBilinearForm());
2849
~P1ProjectionBilinearForm() {}
2853
class P1ProjectionLinearFormCoefficient0 : public dolfin::Coefficient
2858
P1ProjectionLinearFormCoefficient0(dolfin::Form& form) : dolfin::Coefficient(form) {}
2861
~P1ProjectionLinearFormCoefficient0() {}
2863
// Attach function to coefficient
2864
const P1ProjectionLinearFormCoefficient0& operator= (dolfin::Function& v)
2870
/// Create function space for coefficient
2871
const dolfin::FunctionSpace* create_function_space() const
2873
return new P1ProjectionLinearFormCoefficientSpace0(form.mesh());
2876
/// Return coefficient number
2877
dolfin::uint number() const
2882
/// Return coefficient name
2883
virtual std::string name() const
2889
class P1ProjectionLinearForm : public dolfin::Form
2893
// Create form on given function space(s)
2894
P1ProjectionLinearForm(const dolfin::FunctionSpace& V0) : dolfin::Form(), u(*this)
2896
boost::shared_ptr<const dolfin::FunctionSpace> _V0(&V0, dolfin::NoDeleter<const dolfin::FunctionSpace>());
2897
_function_spaces.push_back(_V0);
2899
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
2901
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_P1ProjectionLinearForm());
2904
// Create form on given function space(s) (shared data)
2905
P1ProjectionLinearForm(boost::shared_ptr<const dolfin::FunctionSpace> V0) : dolfin::Form(), u(*this)
2907
_function_spaces.push_back(V0);
2909
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
2911
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_P1ProjectionLinearForm());
2914
// Create form on given function space(s) with given coefficient(s)
2915
P1ProjectionLinearForm(const dolfin::FunctionSpace& V0, dolfin::Function& w0) : dolfin::Form(), u(*this)
2917
boost::shared_ptr<const dolfin::FunctionSpace> _V0(&V0, dolfin::NoDeleter<const dolfin::FunctionSpace>());
2918
_function_spaces.push_back(_V0);
2920
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
2924
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_P1ProjectionLinearForm());
2927
// Create form on given function space(s) with given coefficient(s) (shared data)
2928
P1ProjectionLinearForm(boost::shared_ptr<const dolfin::FunctionSpace> V0, dolfin::Function& w0) : dolfin::Form(), u(*this)
2930
_function_spaces.push_back(V0);
2932
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
2936
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_P1ProjectionLinearForm());
2940
~P1ProjectionLinearForm() {}
2943
P1ProjectionLinearFormCoefficient0 u;