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.
7
#ifndef __CONVECTIONMATRIX2D_H
8
#define __CONVECTIONMATRIX2D_H
15
/// This class defines the interface for a finite element.
17
class UFC_ConvectionMatrix2DBilinearForm_finite_element_0: public ufc::finite_element
22
UFC_ConvectionMatrix2DBilinearForm_finite_element_0() : ufc::finite_element()
28
virtual ~UFC_ConvectionMatrix2DBilinearForm_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_ConvectionMatrix2DBilinearForm_finite_element_0();
436
/// This class defines the interface for a finite element.
438
class UFC_ConvectionMatrix2DBilinearForm_finite_element_1: public ufc::finite_element
443
UFC_ConvectionMatrix2DBilinearForm_finite_element_1() : ufc::finite_element()
449
virtual ~UFC_ConvectionMatrix2DBilinearForm_finite_element_1()
454
/// Return a string identifying the finite element
455
virtual const char* signature() const
457
return "Lagrange finite element of degree 1 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;
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_ConvectionMatrix2DBilinearForm_finite_element_1();
857
/// This class defines the interface for a finite element.
859
class UFC_ConvectionMatrix2DBilinearForm_finite_element_2: public ufc::finite_element
864
UFC_ConvectionMatrix2DBilinearForm_finite_element_2() : ufc::finite_element()
870
virtual ~UFC_ConvectionMatrix2DBilinearForm_finite_element_2()
875
/// Return a string identifying the finite element
876
virtual const char* signature() const
878
return "Discontinuous Lagrange finite element of degree 0 on a triangle";
881
/// Return the cell shape
882
virtual ufc::shape cell_shape() const
884
return ufc::triangle;
887
/// Return the dimension of the finite element function space
888
virtual unsigned int space_dimension() const
893
/// Return the rank of the value space
894
virtual unsigned int value_rank() const
899
/// Return the dimension of the value space for axis i
900
virtual unsigned int value_dimension(unsigned int i) const
905
/// Evaluate basis function i at given point in cell
906
virtual void evaluate_basis(unsigned int i,
908
const double* coordinates,
909
const ufc::cell& c) const
911
// Extract vertex coordinates
912
const double * const * element_coordinates = c.coordinates;
914
// Compute Jacobian of affine map from reference cell
915
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
916
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
917
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
918
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
920
// Compute determinant of Jacobian
921
const double detJ = J_00*J_11 - J_01*J_10;
923
// Compute inverse of Jacobian
925
// Get coordinates and map to the reference (UFC) element
926
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
927
element_coordinates[0][0]*element_coordinates[2][1] +\
928
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
929
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
930
element_coordinates[1][0]*element_coordinates[0][1] -\
931
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
933
// Map coordinates to the reference square
934
if (std::abs(y - 1.0) < 1e-14)
937
x = 2.0 *x/(1.0 - y) - 1.0;
943
// Map degree of freedom to element degree of freedom
944
const unsigned int dof = i;
947
const double scalings_y_0 = 1;
949
// Compute psitilde_a
950
const double psitilde_a_0 = 1;
952
// Compute psitilde_bs
953
const double psitilde_bs_0_0 = 1;
955
// Compute basisvalues
956
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
958
// Table(s) of coefficients
959
const static double coefficients0[1][1] = \
960
{{1.41421356237309}};
962
// Extract relevant coefficients
963
const double coeff0_0 = coefficients0[dof][0];
966
*values = coeff0_0*basisvalue0;
969
/// Evaluate all basis functions at given point in cell
970
virtual void evaluate_basis_all(double* values,
971
const double* coordinates,
972
const ufc::cell& c) const
974
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
977
/// Evaluate order n derivatives of basis function i at given point in cell
978
virtual void evaluate_basis_derivatives(unsigned int i,
981
const double* coordinates,
982
const ufc::cell& c) const
984
// Extract vertex coordinates
985
const double * const * element_coordinates = c.coordinates;
987
// Compute Jacobian of affine map from reference cell
988
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
989
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
990
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
991
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
993
// Compute determinant of Jacobian
994
const double detJ = J_00*J_11 - J_01*J_10;
996
// Compute inverse of Jacobian
998
// Get coordinates and map to the reference (UFC) element
999
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1000
element_coordinates[0][0]*element_coordinates[2][1] +\
1001
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1002
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1003
element_coordinates[1][0]*element_coordinates[0][1] -\
1004
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1006
// Map coordinates to the reference square
1007
if (std::abs(y - 1.0) < 1e-14)
1010
x = 2.0 *x/(1.0 - y) - 1.0;
1013
// Compute number of derivatives
1014
unsigned int num_derivatives = 1;
1016
for (unsigned int j = 0; j < n; j++)
1017
num_derivatives *= 2;
1020
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1021
unsigned int **combinations = new unsigned int *[num_derivatives];
1023
for (unsigned int j = 0; j < num_derivatives; j++)
1025
combinations[j] = new unsigned int [n];
1026
for (unsigned int k = 0; k < n; k++)
1027
combinations[j][k] = 0;
1030
// Generate combinations of derivatives
1031
for (unsigned int row = 1; row < num_derivatives; row++)
1033
for (unsigned int num = 0; num < row; num++)
1035
for (unsigned int col = n-1; col+1 > 0; col--)
1037
if (combinations[row][col] + 1 > 1)
1038
combinations[row][col] = 0;
1041
combinations[row][col] += 1;
1048
// Compute inverse of Jacobian
1049
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1051
// Declare transformation matrix
1052
// Declare pointer to two dimensional array and initialise
1053
double **transform = new double *[num_derivatives];
1055
for (unsigned int j = 0; j < num_derivatives; j++)
1057
transform[j] = new double [num_derivatives];
1058
for (unsigned int k = 0; k < num_derivatives; k++)
1059
transform[j][k] = 1;
1062
// Construct transformation matrix
1063
for (unsigned int row = 0; row < num_derivatives; row++)
1065
for (unsigned int col = 0; col < num_derivatives; col++)
1067
for (unsigned int k = 0; k < n; k++)
1068
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1073
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1076
// Map degree of freedom to element degree of freedom
1077
const unsigned int dof = i;
1079
// Generate scalings
1080
const double scalings_y_0 = 1;
1082
// Compute psitilde_a
1083
const double psitilde_a_0 = 1;
1085
// Compute psitilde_bs
1086
const double psitilde_bs_0_0 = 1;
1088
// Compute basisvalues
1089
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1091
// Table(s) of coefficients
1092
const static double coefficients0[1][1] = \
1093
{{1.41421356237309}};
1095
// Interesting (new) part
1096
// Tables of derivatives of the polynomial base (transpose)
1097
const static double dmats0[1][1] = \
1100
const static double dmats1[1][1] = \
1103
// Compute reference derivatives
1104
// Declare pointer to array of derivatives on FIAT element
1105
double *derivatives = new double [num_derivatives];
1107
// Declare coefficients
1108
double coeff0_0 = 0;
1110
// Declare new coefficients
1111
double new_coeff0_0 = 0;
1113
// Loop possible derivatives
1114
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1116
// Get values from coefficients array
1117
new_coeff0_0 = coefficients0[dof][0];
1119
// Loop derivative order
1120
for (unsigned int j = 0; j < n; j++)
1122
// Update old coefficients
1123
coeff0_0 = new_coeff0_0;
1125
if(combinations[deriv_num][j] == 0)
1127
new_coeff0_0 = coeff0_0*dmats0[0][0];
1129
if(combinations[deriv_num][j] == 1)
1131
new_coeff0_0 = coeff0_0*dmats1[0][0];
1135
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1136
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
1139
// Transform derivatives back to physical element
1140
for (unsigned int row = 0; row < num_derivatives; row++)
1142
for (unsigned int col = 0; col < num_derivatives; col++)
1144
values[row] += transform[row][col]*derivatives[col];
1147
// Delete pointer to array of derivatives on FIAT element
1148
delete [] derivatives;
1150
// Delete pointer to array of combinations of derivatives and transform
1151
for (unsigned int row = 0; row < num_derivatives; row++)
1153
delete [] combinations[row];
1154
delete [] transform[row];
1157
delete [] combinations;
1158
delete [] transform;
1161
/// Evaluate order n derivatives of all basis functions at given point in cell
1162
virtual void evaluate_basis_derivatives_all(unsigned int n,
1164
const double* coordinates,
1165
const ufc::cell& c) const
1167
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1170
/// Evaluate linear functional for dof i on the function f
1171
virtual double evaluate_dof(unsigned int i,
1172
const ufc::function& f,
1173
const ufc::cell& c) const
1175
// The reference points, direction and weights:
1176
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
1177
const static double W[1][1] = {{1}};
1178
const static double D[1][1][1] = {{{1}}};
1180
const double * const * x = c.coordinates;
1181
double result = 0.0;
1182
// Iterate over the points:
1183
// Evaluate basis functions for affine mapping
1184
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1185
const double w1 = X[i][0][0];
1186
const double w2 = X[i][0][1];
1188
// Compute affine mapping y = F(X)
1190
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1191
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1193
// Evaluate function at physical points
1195
f.evaluate(values, y, c);
1197
// Map function values using appropriate mapping
1198
// Affine map: Do nothing
1200
// Note that we do not map the weights (yet).
1202
// Take directional components
1203
for(int k = 0; k < 1; k++)
1204
result += values[k]*D[i][0][k];
1205
// Multiply by weights
1211
/// Evaluate linear functionals for all dofs on the function f
1212
virtual void evaluate_dofs(double* values,
1213
const ufc::function& f,
1214
const ufc::cell& c) const
1216
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1219
/// Interpolate vertex values from dof values
1220
virtual void interpolate_vertex_values(double* vertex_values,
1221
const double* dof_values,
1222
const ufc::cell& c) const
1224
// Evaluate at vertices and use affine mapping
1225
vertex_values[0] = dof_values[0];
1226
vertex_values[1] = dof_values[0];
1227
vertex_values[2] = dof_values[0];
1230
/// Return the number of sub elements (for a mixed element)
1231
virtual unsigned int num_sub_elements() const
1236
/// Create a new finite element for sub element i (for a mixed element)
1237
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1239
return new UFC_ConvectionMatrix2DBilinearForm_finite_element_2();
1244
/// This class defines the interface for a finite element.
1246
class UFC_ConvectionMatrix2DBilinearForm_finite_element_3: public ufc::finite_element
1251
UFC_ConvectionMatrix2DBilinearForm_finite_element_3() : ufc::finite_element()
1257
virtual ~UFC_ConvectionMatrix2DBilinearForm_finite_element_3()
1262
/// Return a string identifying the finite element
1263
virtual const char* signature() const
1265
return "Discontinuous Lagrange finite element of degree 0 on a triangle";
1268
/// Return the cell shape
1269
virtual ufc::shape cell_shape() const
1271
return ufc::triangle;
1274
/// Return the dimension of the finite element function space
1275
virtual unsigned int space_dimension() const
1280
/// Return the rank of the value space
1281
virtual unsigned int value_rank() const
1286
/// Return the dimension of the value space for axis i
1287
virtual unsigned int value_dimension(unsigned int i) const
1292
/// Evaluate basis function i at given point in cell
1293
virtual void evaluate_basis(unsigned int i,
1295
const double* coordinates,
1296
const ufc::cell& c) const
1298
// Extract vertex coordinates
1299
const double * const * element_coordinates = c.coordinates;
1301
// Compute Jacobian of affine map from reference cell
1302
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1303
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1304
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1305
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1307
// Compute determinant of Jacobian
1308
const double detJ = J_00*J_11 - J_01*J_10;
1310
// Compute inverse of Jacobian
1312
// Get coordinates and map to the reference (UFC) element
1313
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1314
element_coordinates[0][0]*element_coordinates[2][1] +\
1315
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1316
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1317
element_coordinates[1][0]*element_coordinates[0][1] -\
1318
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1320
// Map coordinates to the reference square
1321
if (std::abs(y - 1.0) < 1e-14)
1324
x = 2.0 *x/(1.0 - y) - 1.0;
1330
// Map degree of freedom to element degree of freedom
1331
const unsigned int dof = i;
1333
// Generate scalings
1334
const double scalings_y_0 = 1;
1336
// Compute psitilde_a
1337
const double psitilde_a_0 = 1;
1339
// Compute psitilde_bs
1340
const double psitilde_bs_0_0 = 1;
1342
// Compute basisvalues
1343
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1345
// Table(s) of coefficients
1346
const static double coefficients0[1][1] = \
1347
{{1.41421356237309}};
1349
// Extract relevant coefficients
1350
const double coeff0_0 = coefficients0[dof][0];
1353
*values = coeff0_0*basisvalue0;
1356
/// Evaluate all basis functions at given point in cell
1357
virtual void evaluate_basis_all(double* values,
1358
const double* coordinates,
1359
const ufc::cell& c) const
1361
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1364
/// Evaluate order n derivatives of basis function i at given point in cell
1365
virtual void evaluate_basis_derivatives(unsigned int i,
1368
const double* coordinates,
1369
const ufc::cell& c) const
1371
// Extract vertex coordinates
1372
const double * const * element_coordinates = c.coordinates;
1374
// Compute Jacobian of affine map from reference cell
1375
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1376
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1377
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1378
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1380
// Compute determinant of Jacobian
1381
const double detJ = J_00*J_11 - J_01*J_10;
1383
// Compute inverse of Jacobian
1385
// Get coordinates and map to the reference (UFC) element
1386
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1387
element_coordinates[0][0]*element_coordinates[2][1] +\
1388
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1389
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1390
element_coordinates[1][0]*element_coordinates[0][1] -\
1391
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1393
// Map coordinates to the reference square
1394
if (std::abs(y - 1.0) < 1e-14)
1397
x = 2.0 *x/(1.0 - y) - 1.0;
1400
// Compute number of derivatives
1401
unsigned int num_derivatives = 1;
1403
for (unsigned int j = 0; j < n; j++)
1404
num_derivatives *= 2;
1407
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1408
unsigned int **combinations = new unsigned int *[num_derivatives];
1410
for (unsigned int j = 0; j < num_derivatives; j++)
1412
combinations[j] = new unsigned int [n];
1413
for (unsigned int k = 0; k < n; k++)
1414
combinations[j][k] = 0;
1417
// Generate combinations of derivatives
1418
for (unsigned int row = 1; row < num_derivatives; row++)
1420
for (unsigned int num = 0; num < row; num++)
1422
for (unsigned int col = n-1; col+1 > 0; col--)
1424
if (combinations[row][col] + 1 > 1)
1425
combinations[row][col] = 0;
1428
combinations[row][col] += 1;
1435
// Compute inverse of Jacobian
1436
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1438
// Declare transformation matrix
1439
// Declare pointer to two dimensional array and initialise
1440
double **transform = new double *[num_derivatives];
1442
for (unsigned int j = 0; j < num_derivatives; j++)
1444
transform[j] = new double [num_derivatives];
1445
for (unsigned int k = 0; k < num_derivatives; k++)
1446
transform[j][k] = 1;
1449
// Construct transformation matrix
1450
for (unsigned int row = 0; row < num_derivatives; row++)
1452
for (unsigned int col = 0; col < num_derivatives; col++)
1454
for (unsigned int k = 0; k < n; k++)
1455
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1460
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1463
// Map degree of freedom to element degree of freedom
1464
const unsigned int dof = i;
1466
// Generate scalings
1467
const double scalings_y_0 = 1;
1469
// Compute psitilde_a
1470
const double psitilde_a_0 = 1;
1472
// Compute psitilde_bs
1473
const double psitilde_bs_0_0 = 1;
1475
// Compute basisvalues
1476
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1478
// Table(s) of coefficients
1479
const static double coefficients0[1][1] = \
1480
{{1.41421356237309}};
1482
// Interesting (new) part
1483
// Tables of derivatives of the polynomial base (transpose)
1484
const static double dmats0[1][1] = \
1487
const static double dmats1[1][1] = \
1490
// Compute reference derivatives
1491
// Declare pointer to array of derivatives on FIAT element
1492
double *derivatives = new double [num_derivatives];
1494
// Declare coefficients
1495
double coeff0_0 = 0;
1497
// Declare new coefficients
1498
double new_coeff0_0 = 0;
1500
// Loop possible derivatives
1501
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1503
// Get values from coefficients array
1504
new_coeff0_0 = coefficients0[dof][0];
1506
// Loop derivative order
1507
for (unsigned int j = 0; j < n; j++)
1509
// Update old coefficients
1510
coeff0_0 = new_coeff0_0;
1512
if(combinations[deriv_num][j] == 0)
1514
new_coeff0_0 = coeff0_0*dmats0[0][0];
1516
if(combinations[deriv_num][j] == 1)
1518
new_coeff0_0 = coeff0_0*dmats1[0][0];
1522
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1523
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
1526
// Transform derivatives back to physical element
1527
for (unsigned int row = 0; row < num_derivatives; row++)
1529
for (unsigned int col = 0; col < num_derivatives; col++)
1531
values[row] += transform[row][col]*derivatives[col];
1534
// Delete pointer to array of derivatives on FIAT element
1535
delete [] derivatives;
1537
// Delete pointer to array of combinations of derivatives and transform
1538
for (unsigned int row = 0; row < num_derivatives; row++)
1540
delete [] combinations[row];
1541
delete [] transform[row];
1544
delete [] combinations;
1545
delete [] transform;
1548
/// Evaluate order n derivatives of all basis functions at given point in cell
1549
virtual void evaluate_basis_derivatives_all(unsigned int n,
1551
const double* coordinates,
1552
const ufc::cell& c) const
1554
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1557
/// Evaluate linear functional for dof i on the function f
1558
virtual double evaluate_dof(unsigned int i,
1559
const ufc::function& f,
1560
const ufc::cell& c) const
1562
// The reference points, direction and weights:
1563
const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
1564
const static double W[1][1] = {{1}};
1565
const static double D[1][1][1] = {{{1}}};
1567
const double * const * x = c.coordinates;
1568
double result = 0.0;
1569
// Iterate over the points:
1570
// Evaluate basis functions for affine mapping
1571
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1572
const double w1 = X[i][0][0];
1573
const double w2 = X[i][0][1];
1575
// Compute affine mapping y = F(X)
1577
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1578
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1580
// Evaluate function at physical points
1582
f.evaluate(values, y, c);
1584
// Map function values using appropriate mapping
1585
// Affine map: Do nothing
1587
// Note that we do not map the weights (yet).
1589
// Take directional components
1590
for(int k = 0; k < 1; k++)
1591
result += values[k]*D[i][0][k];
1592
// Multiply by weights
1598
/// Evaluate linear functionals for all dofs on the function f
1599
virtual void evaluate_dofs(double* values,
1600
const ufc::function& f,
1601
const ufc::cell& c) const
1603
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1606
/// Interpolate vertex values from dof values
1607
virtual void interpolate_vertex_values(double* vertex_values,
1608
const double* dof_values,
1609
const ufc::cell& c) const
1611
// Evaluate at vertices and use affine mapping
1612
vertex_values[0] = dof_values[0];
1613
vertex_values[1] = dof_values[0];
1614
vertex_values[2] = dof_values[0];
1617
/// Return the number of sub elements (for a mixed element)
1618
virtual unsigned int num_sub_elements() const
1623
/// Create a new finite element for sub element i (for a mixed element)
1624
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1626
return new UFC_ConvectionMatrix2DBilinearForm_finite_element_3();
1631
/// This class defines the interface for a local-to-global mapping of
1632
/// degrees of freedom (dofs).
1634
class UFC_ConvectionMatrix2DBilinearForm_dof_map_0: public ufc::dof_map
1638
unsigned int __global_dimension;
1643
UFC_ConvectionMatrix2DBilinearForm_dof_map_0() : ufc::dof_map()
1645
__global_dimension = 0;
1649
virtual ~UFC_ConvectionMatrix2DBilinearForm_dof_map_0()
1654
/// Return a string identifying the dof map
1655
virtual const char* signature() const
1657
return "FFC dof map for Lagrange finite element of degree 1 on a triangle";
1660
/// Return true iff mesh entities of topological dimension d are needed
1661
virtual bool needs_mesh_entities(unsigned int d) const
1678
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1679
virtual bool init_mesh(const ufc::mesh& m)
1681
__global_dimension = m.num_entities[0];
1685
/// Initialize dof map for given cell
1686
virtual void init_cell(const ufc::mesh& m,
1692
/// Finish initialization of dof map for cells
1693
virtual void init_cell_finalize()
1698
/// Return the dimension of the global finite element function space
1699
virtual unsigned int global_dimension() const
1701
return __global_dimension;
1704
/// Return the dimension of the local finite element function space
1705
virtual unsigned int local_dimension() const
1710
// Return the geometric dimension of the coordinates this dof map provides
1711
virtual unsigned int geometric_dimension() const
1713
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1716
/// Return the number of dofs on each cell facet
1717
virtual unsigned int num_facet_dofs() const
1722
/// Return the number of dofs associated with each cell entity of dimension d
1723
virtual unsigned int num_entity_dofs(unsigned int d) const
1725
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1728
/// Tabulate the local-to-global mapping of dofs on a cell
1729
virtual void tabulate_dofs(unsigned int* dofs,
1731
const ufc::cell& c) const
1733
dofs[0] = c.entity_indices[0][0];
1734
dofs[1] = c.entity_indices[0][1];
1735
dofs[2] = c.entity_indices[0][2];
1738
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1739
virtual void tabulate_facet_dofs(unsigned int* dofs,
1740
unsigned int facet) const
1759
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1760
virtual void tabulate_entity_dofs(unsigned int* dofs,
1761
unsigned int d, unsigned int i) const
1763
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1766
/// Tabulate the coordinates of all dofs on a cell
1767
virtual void tabulate_coordinates(double** coordinates,
1768
const ufc::cell& c) const
1770
const double * const * x = c.coordinates;
1771
coordinates[0][0] = x[0][0];
1772
coordinates[0][1] = x[0][1];
1773
coordinates[1][0] = x[1][0];
1774
coordinates[1][1] = x[1][1];
1775
coordinates[2][0] = x[2][0];
1776
coordinates[2][1] = x[2][1];
1779
/// Return the number of sub dof maps (for a mixed element)
1780
virtual unsigned int num_sub_dof_maps() const
1785
/// Create a new dof_map for sub dof map i (for a mixed element)
1786
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1788
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_0();
1793
/// This class defines the interface for a local-to-global mapping of
1794
/// degrees of freedom (dofs).
1796
class UFC_ConvectionMatrix2DBilinearForm_dof_map_1: public ufc::dof_map
1800
unsigned int __global_dimension;
1805
UFC_ConvectionMatrix2DBilinearForm_dof_map_1() : ufc::dof_map()
1807
__global_dimension = 0;
1811
virtual ~UFC_ConvectionMatrix2DBilinearForm_dof_map_1()
1816
/// Return a string identifying the dof map
1817
virtual const char* signature() const
1819
return "FFC dof map for Lagrange finite element of degree 1 on a triangle";
1822
/// Return true iff mesh entities of topological dimension d are needed
1823
virtual bool needs_mesh_entities(unsigned int d) const
1840
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1841
virtual bool init_mesh(const ufc::mesh& m)
1843
__global_dimension = m.num_entities[0];
1847
/// Initialize dof map for given cell
1848
virtual void init_cell(const ufc::mesh& m,
1854
/// Finish initialization of dof map for cells
1855
virtual void init_cell_finalize()
1860
/// Return the dimension of the global finite element function space
1861
virtual unsigned int global_dimension() const
1863
return __global_dimension;
1866
/// Return the dimension of the local finite element function space
1867
virtual unsigned int local_dimension() const
1872
// Return the geometric dimension of the coordinates this dof map provides
1873
virtual unsigned int geometric_dimension() const
1875
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1878
/// Return the number of dofs on each cell facet
1879
virtual unsigned int num_facet_dofs() const
1884
/// Return the number of dofs associated with each cell entity of dimension d
1885
virtual unsigned int num_entity_dofs(unsigned int d) const
1887
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1890
/// Tabulate the local-to-global mapping of dofs on a cell
1891
virtual void tabulate_dofs(unsigned int* dofs,
1893
const ufc::cell& c) const
1895
dofs[0] = c.entity_indices[0][0];
1896
dofs[1] = c.entity_indices[0][1];
1897
dofs[2] = c.entity_indices[0][2];
1900
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1901
virtual void tabulate_facet_dofs(unsigned int* dofs,
1902
unsigned int facet) const
1921
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1922
virtual void tabulate_entity_dofs(unsigned int* dofs,
1923
unsigned int d, unsigned int i) const
1925
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1928
/// Tabulate the coordinates of all dofs on a cell
1929
virtual void tabulate_coordinates(double** coordinates,
1930
const ufc::cell& c) const
1932
const double * const * x = c.coordinates;
1933
coordinates[0][0] = x[0][0];
1934
coordinates[0][1] = x[0][1];
1935
coordinates[1][0] = x[1][0];
1936
coordinates[1][1] = x[1][1];
1937
coordinates[2][0] = x[2][0];
1938
coordinates[2][1] = x[2][1];
1941
/// Return the number of sub dof maps (for a mixed element)
1942
virtual unsigned int num_sub_dof_maps() const
1947
/// Create a new dof_map for sub dof map i (for a mixed element)
1948
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1950
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_1();
1955
/// This class defines the interface for a local-to-global mapping of
1956
/// degrees of freedom (dofs).
1958
class UFC_ConvectionMatrix2DBilinearForm_dof_map_2: public ufc::dof_map
1962
unsigned int __global_dimension;
1967
UFC_ConvectionMatrix2DBilinearForm_dof_map_2() : ufc::dof_map()
1969
__global_dimension = 0;
1973
virtual ~UFC_ConvectionMatrix2DBilinearForm_dof_map_2()
1978
/// Return a string identifying the dof map
1979
virtual const char* signature() const
1981
return "FFC dof map for Discontinuous Lagrange finite element of degree 0 on a triangle";
1984
/// Return true iff mesh entities of topological dimension d are needed
1985
virtual bool needs_mesh_entities(unsigned int d) const
2002
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2003
virtual bool init_mesh(const ufc::mesh& m)
2005
__global_dimension = m.num_entities[2];
2009
/// Initialize dof map for given cell
2010
virtual void init_cell(const ufc::mesh& m,
2016
/// Finish initialization of dof map for cells
2017
virtual void init_cell_finalize()
2022
/// Return the dimension of the global finite element function space
2023
virtual unsigned int global_dimension() const
2025
return __global_dimension;
2028
/// Return the dimension of the local finite element function space
2029
virtual unsigned int local_dimension() const
2034
// Return the geometric dimension of the coordinates this dof map provides
2035
virtual unsigned int geometric_dimension() const
2037
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2040
/// Return the number of dofs on each cell facet
2041
virtual unsigned int num_facet_dofs() const
2046
/// Return the number of dofs associated with each cell entity of dimension d
2047
virtual unsigned int num_entity_dofs(unsigned int d) const
2049
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2052
/// Tabulate the local-to-global mapping of dofs on a cell
2053
virtual void tabulate_dofs(unsigned int* dofs,
2055
const ufc::cell& c) const
2057
dofs[0] = c.entity_indices[2][0];
2060
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2061
virtual void tabulate_facet_dofs(unsigned int* dofs,
2062
unsigned int facet) const
2078
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2079
virtual void tabulate_entity_dofs(unsigned int* dofs,
2080
unsigned int d, unsigned int i) const
2082
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2085
/// Tabulate the coordinates of all dofs on a cell
2086
virtual void tabulate_coordinates(double** coordinates,
2087
const ufc::cell& c) const
2089
const double * const * x = c.coordinates;
2090
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
2091
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
2094
/// Return the number of sub dof maps (for a mixed element)
2095
virtual unsigned int num_sub_dof_maps() const
2100
/// Create a new dof_map for sub dof map i (for a mixed element)
2101
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2103
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_2();
2108
/// This class defines the interface for a local-to-global mapping of
2109
/// degrees of freedom (dofs).
2111
class UFC_ConvectionMatrix2DBilinearForm_dof_map_3: public ufc::dof_map
2115
unsigned int __global_dimension;
2120
UFC_ConvectionMatrix2DBilinearForm_dof_map_3() : ufc::dof_map()
2122
__global_dimension = 0;
2126
virtual ~UFC_ConvectionMatrix2DBilinearForm_dof_map_3()
2131
/// Return a string identifying the dof map
2132
virtual const char* signature() const
2134
return "FFC dof map for Discontinuous Lagrange finite element of degree 0 on a triangle";
2137
/// Return true iff mesh entities of topological dimension d are needed
2138
virtual bool needs_mesh_entities(unsigned int d) const
2155
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2156
virtual bool init_mesh(const ufc::mesh& m)
2158
__global_dimension = m.num_entities[2];
2162
/// Initialize dof map for given cell
2163
virtual void init_cell(const ufc::mesh& m,
2169
/// Finish initialization of dof map for cells
2170
virtual void init_cell_finalize()
2175
/// Return the dimension of the global finite element function space
2176
virtual unsigned int global_dimension() const
2178
return __global_dimension;
2181
/// Return the dimension of the local finite element function space
2182
virtual unsigned int local_dimension() const
2187
// Return the geometric dimension of the coordinates this dof map provides
2188
virtual unsigned int geometric_dimension() const
2190
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2193
/// Return the number of dofs on each cell facet
2194
virtual unsigned int num_facet_dofs() const
2199
/// Return the number of dofs associated with each cell entity of dimension d
2200
virtual unsigned int num_entity_dofs(unsigned int d) const
2202
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2205
/// Tabulate the local-to-global mapping of dofs on a cell
2206
virtual void tabulate_dofs(unsigned int* dofs,
2208
const ufc::cell& c) const
2210
dofs[0] = c.entity_indices[2][0];
2213
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2214
virtual void tabulate_facet_dofs(unsigned int* dofs,
2215
unsigned int facet) const
2231
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2232
virtual void tabulate_entity_dofs(unsigned int* dofs,
2233
unsigned int d, unsigned int i) const
2235
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2238
/// Tabulate the coordinates of all dofs on a cell
2239
virtual void tabulate_coordinates(double** coordinates,
2240
const ufc::cell& c) const
2242
const double * const * x = c.coordinates;
2243
coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
2244
coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
2247
/// Return the number of sub dof maps (for a mixed element)
2248
virtual unsigned int num_sub_dof_maps() const
2253
/// Create a new dof_map for sub dof map i (for a mixed element)
2254
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2256
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_3();
2261
/// This class defines the interface for the tabulation of the cell
2262
/// tensor corresponding to the local contribution to a form from
2263
/// the integral over a cell.
2265
class UFC_ConvectionMatrix2DBilinearForm_cell_integral_0: public ufc::cell_integral
2270
UFC_ConvectionMatrix2DBilinearForm_cell_integral_0() : ufc::cell_integral()
2276
virtual ~UFC_ConvectionMatrix2DBilinearForm_cell_integral_0()
2281
/// Tabulate the tensor for the contribution from a local cell
2282
virtual void tabulate_tensor(double* A,
2283
const double * const * w,
2284
const ufc::cell& c) const
2286
// Extract vertex coordinates
2287
const double * const * x = c.coordinates;
2289
// Compute Jacobian of affine map from reference cell
2290
const double J_00 = x[1][0] - x[0][0];
2291
const double J_01 = x[2][0] - x[0][0];
2292
const double J_10 = x[1][1] - x[0][1];
2293
const double J_11 = x[2][1] - x[0][1];
2295
// Compute determinant of Jacobian
2296
double detJ = J_00*J_11 - J_01*J_10;
2298
// Compute inverse of Jacobian
2299
const double Jinv_00 = J_11 / detJ;
2300
const double Jinv_01 = -J_01 / detJ;
2301
const double Jinv_10 = -J_10 / detJ;
2302
const double Jinv_11 = J_00 / detJ;
2305
const double det = std::abs(detJ);
2307
// Compute coefficients
2308
const double c0_0_0_0 = w[0][0];
2309
const double c1_1_0_0 = w[1][0];
2311
// Compute geometry tensors
2312
const double G0_0_0 = det*(c0_0_0_0*Jinv_00 + c1_1_0_0*Jinv_01);
2313
const double G0_0_1 = det*(c0_0_0_0*Jinv_10 + c1_1_0_0*Jinv_11);
2315
// Compute element tensor
2316
A[0] = -0.166666666666667*G0_0_0 - 0.166666666666667*G0_0_1;
2317
A[1] = 0.166666666666667*G0_0_0;
2318
A[2] = 0.166666666666667*G0_0_1;
2319
A[3] = -0.166666666666667*G0_0_0 - 0.166666666666667*G0_0_1;
2320
A[4] = 0.166666666666667*G0_0_0;
2321
A[5] = 0.166666666666667*G0_0_1;
2322
A[6] = -0.166666666666667*G0_0_0 - 0.166666666666667*G0_0_1;
2323
A[7] = 0.166666666666667*G0_0_0;
2324
A[8] = 0.166666666666667*G0_0_1;
2329
/// This class defines the interface for the assembly of the global
2330
/// tensor corresponding to a form with r + n arguments, that is, a
2333
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2335
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2336
/// global tensor A is defined by
2338
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2340
/// where each argument Vj represents the application to the
2341
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2342
/// fixed functions (coefficients).
2344
class UFC_ConvectionMatrix2DBilinearForm: public ufc::form
2349
UFC_ConvectionMatrix2DBilinearForm() : ufc::form()
2355
virtual ~UFC_ConvectionMatrix2DBilinearForm()
2360
/// Return a string identifying the form
2361
virtual const char* signature() const
2363
return "w0_a0(dXa1/dx0) | vi0*va0*((d/dXa1)vi1)*dX(0) + w1_a0(dXa1/dx1) | vi0*va0*((d/dXa1)vi1)*dX(0)";
2366
/// Return the rank of the global tensor (r)
2367
virtual unsigned int rank() const
2372
/// Return the number of coefficients (n)
2373
virtual unsigned int num_coefficients() const
2378
/// Return the number of cell integrals
2379
virtual unsigned int num_cell_integrals() const
2384
/// Return the number of exterior facet integrals
2385
virtual unsigned int num_exterior_facet_integrals() const
2390
/// Return the number of interior facet integrals
2391
virtual unsigned int num_interior_facet_integrals() const
2396
/// Create a new finite element for argument function i
2397
virtual ufc::finite_element* create_finite_element(unsigned int i) const
2402
return new UFC_ConvectionMatrix2DBilinearForm_finite_element_0();
2405
return new UFC_ConvectionMatrix2DBilinearForm_finite_element_1();
2408
return new UFC_ConvectionMatrix2DBilinearForm_finite_element_2();
2411
return new UFC_ConvectionMatrix2DBilinearForm_finite_element_3();
2417
/// Create a new dof map for argument function i
2418
virtual ufc::dof_map* create_dof_map(unsigned int i) const
2423
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_0();
2426
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_1();
2429
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_2();
2432
return new UFC_ConvectionMatrix2DBilinearForm_dof_map_3();
2438
/// Create a new cell integral on sub domain i
2439
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
2441
return new UFC_ConvectionMatrix2DBilinearForm_cell_integral_0();
2444
/// Create a new exterior facet integral on sub domain i
2445
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
2450
/// Create a new interior facet integral on sub domain i
2451
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
2460
#include <dolfin/Form.h>
2462
class ConvectionMatrix2DBilinearForm : public dolfin::Form
2466
ConvectionMatrix2DBilinearForm(dolfin::Function& w0, dolfin::Function& w1) : dolfin::Form()
2468
__coefficients.push_back(&w0);
2469
__coefficients.push_back(&w1);
2473
virtual const ufc::form& form() const
2478
/// Return array of coefficients
2479
virtual const dolfin::Array<dolfin::Function*>& coefficients() const
2481
return __coefficients;
2487
UFC_ConvectionMatrix2DBilinearForm __form;
2489
/// Array of coefficients
2490
dolfin::Array<dolfin::Function*> __coefficients;