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 __MASSMATRIX2D_H
8
#define __MASSMATRIX2D_H
15
/// This class defines the interface for a finite element.
17
class UFC_MassMatrix2DBilinearForm_finite_element_0: public ufc::finite_element
22
UFC_MassMatrix2DBilinearForm_finite_element_0() : ufc::finite_element()
28
virtual ~UFC_MassMatrix2DBilinearForm_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_MassMatrix2DBilinearForm_finite_element_0();
436
/// This class defines the interface for a finite element.
438
class UFC_MassMatrix2DBilinearForm_finite_element_1: public ufc::finite_element
443
UFC_MassMatrix2DBilinearForm_finite_element_1() : ufc::finite_element()
449
virtual ~UFC_MassMatrix2DBilinearForm_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_MassMatrix2DBilinearForm_finite_element_1();
857
/// This class defines the interface for a local-to-global mapping of
858
/// degrees of freedom (dofs).
860
class UFC_MassMatrix2DBilinearForm_dof_map_0: public ufc::dof_map
864
unsigned int __global_dimension;
869
UFC_MassMatrix2DBilinearForm_dof_map_0() : ufc::dof_map()
871
__global_dimension = 0;
875
virtual ~UFC_MassMatrix2DBilinearForm_dof_map_0()
880
/// Return a string identifying the dof map
881
virtual const char* signature() const
883
return "FFC dof map for Lagrange finite element of degree 1 on a triangle";
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
939
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
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_MassMatrix2DBilinearForm_dof_map_0();
1019
/// This class defines the interface for a local-to-global mapping of
1020
/// degrees of freedom (dofs).
1022
class UFC_MassMatrix2DBilinearForm_dof_map_1: public ufc::dof_map
1026
unsigned int __global_dimension;
1031
UFC_MassMatrix2DBilinearForm_dof_map_1() : ufc::dof_map()
1033
__global_dimension = 0;
1037
virtual ~UFC_MassMatrix2DBilinearForm_dof_map_1()
1042
/// Return a string identifying the dof map
1043
virtual const char* signature() const
1045
return "FFC dof map for Lagrange finite element of degree 1 on a triangle";
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
1101
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
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_MassMatrix2DBilinearForm_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_MassMatrix2DBilinearForm_cell_integral_0: public ufc::cell_integral
1190
UFC_MassMatrix2DBilinearForm_cell_integral_0() : ufc::cell_integral()
1196
virtual ~UFC_MassMatrix2DBilinearForm_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
// Compute geometry tensors
1224
const double G0_ = det;
1226
// Compute element tensor
1227
A[0] = 0.0833333333333332*G0_;
1228
A[1] = 0.0416666666666666*G0_;
1229
A[2] = 0.0416666666666666*G0_;
1230
A[3] = 0.0416666666666666*G0_;
1231
A[4] = 0.0833333333333332*G0_;
1232
A[5] = 0.0416666666666666*G0_;
1233
A[6] = 0.0416666666666666*G0_;
1234
A[7] = 0.0416666666666666*G0_;
1235
A[8] = 0.0833333333333332*G0_;
1240
/// This class defines the interface for the assembly of the global
1241
/// tensor corresponding to a form with r + n arguments, that is, a
1244
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
1246
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
1247
/// global tensor A is defined by
1249
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
1251
/// where each argument Vj represents the application to the
1252
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
1253
/// fixed functions (coefficients).
1255
class UFC_MassMatrix2DBilinearForm: public ufc::form
1260
UFC_MassMatrix2DBilinearForm() : ufc::form()
1266
virtual ~UFC_MassMatrix2DBilinearForm()
1271
/// Return a string identifying the form
1272
virtual const char* signature() const
1274
return " | vi0*vi1*dX(0)";
1277
/// Return the rank of the global tensor (r)
1278
virtual unsigned int rank() const
1283
/// Return the number of coefficients (n)
1284
virtual unsigned int num_coefficients() const
1289
/// Return the number of cell integrals
1290
virtual unsigned int num_cell_integrals() const
1295
/// Return the number of exterior facet integrals
1296
virtual unsigned int num_exterior_facet_integrals() const
1301
/// Return the number of interior facet integrals
1302
virtual unsigned int num_interior_facet_integrals() const
1307
/// Create a new finite element for argument function i
1308
virtual ufc::finite_element* create_finite_element(unsigned int i) const
1313
return new UFC_MassMatrix2DBilinearForm_finite_element_0();
1316
return new UFC_MassMatrix2DBilinearForm_finite_element_1();
1322
/// Create a new dof map for argument function i
1323
virtual ufc::dof_map* create_dof_map(unsigned int i) const
1328
return new UFC_MassMatrix2DBilinearForm_dof_map_0();
1331
return new UFC_MassMatrix2DBilinearForm_dof_map_1();
1337
/// Create a new cell integral on sub domain i
1338
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
1340
return new UFC_MassMatrix2DBilinearForm_cell_integral_0();
1343
/// Create a new exterior facet integral on sub domain i
1344
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
1349
/// Create a new interior facet integral on sub domain i
1350
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
1359
#include <dolfin/Form.h>
1361
class MassMatrix2DBilinearForm : public dolfin::Form
1365
MassMatrix2DBilinearForm() : dolfin::Form()
1371
virtual const ufc::form& form() const
1376
/// Return array of coefficients
1377
virtual const dolfin::Array<dolfin::Function*>& coefficients() const
1379
return __coefficients;
1385
UFC_MassMatrix2DBilinearForm __form;
1387
/// Array of coefficients
1388
dolfin::Array<dolfin::Function*> __coefficients;