1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.7.0.
11
/// This class defines the interface for a finite element.
13
class poissondg_0_finite_element_0: public ufc::finite_element
18
poissondg_0_finite_element_0() : ufc::finite_element()
24
virtual ~poissondg_0_finite_element_0()
29
/// Return a string identifying the finite element
30
virtual const char* signature() const
32
return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
35
/// Return the cell shape
36
virtual ufc::shape cell_shape() const
41
/// Return the dimension of the finite element function space
42
virtual unsigned int space_dimension() const
47
/// Return the rank of the value space
48
virtual unsigned int value_rank() const
53
/// Return the dimension of the value space for axis i
54
virtual unsigned int value_dimension(unsigned int i) const
59
/// Evaluate basis function i at given point in cell
60
virtual void evaluate_basis(unsigned int i,
62
const double* coordinates,
63
const ufc::cell& c) const
65
// Extract vertex coordinates
66
const double * const * element_coordinates = c.coordinates;
68
// Compute Jacobian of affine map from reference cell
69
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
70
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
71
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
72
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
74
// Compute determinant of Jacobian
75
const double detJ = J_00*J_11 - J_01*J_10;
77
// Compute inverse of Jacobian
79
// Get coordinates and map to the reference (UFC) element
80
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
81
element_coordinates[0][0]*element_coordinates[2][1] +\
82
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
83
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
84
element_coordinates[1][0]*element_coordinates[0][1] -\
85
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
87
// Map coordinates to the reference square
88
if (std::abs(y - 1.0) < 1e-08)
91
x = 2.0 *x/(1.0 - y) - 1.0;
97
// Map degree of freedom to element degree of freedom
98
const unsigned int dof = i;
101
const double scalings_y_0 = 1;
102
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
104
// Compute psitilde_a
105
const double psitilde_a_0 = 1;
106
const double psitilde_a_1 = x;
108
// Compute psitilde_bs
109
const double psitilde_bs_0_0 = 1;
110
const double psitilde_bs_0_1 = 1.5*y + 0.5;
111
const double psitilde_bs_1_0 = 1;
113
// Compute basisvalues
114
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
115
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
116
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
118
// Table(s) of coefficients
119
static const double coefficients0[3][3] = \
120
{{0.471404521, -0.288675135, -0.166666667},
121
{0.471404521, 0.288675135, -0.166666667},
122
{0.471404521, 0, 0.333333333}};
124
// Extract relevant coefficients
125
const double coeff0_0 = coefficients0[dof][0];
126
const double coeff0_1 = coefficients0[dof][1];
127
const double coeff0_2 = coefficients0[dof][2];
130
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
133
/// Evaluate all basis functions at given point in cell
134
virtual void evaluate_basis_all(double* values,
135
const double* coordinates,
136
const ufc::cell& c) const
138
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
141
/// Evaluate order n derivatives of basis function i at given point in cell
142
virtual void evaluate_basis_derivatives(unsigned int i,
145
const double* coordinates,
146
const ufc::cell& c) const
148
// Extract vertex coordinates
149
const double * const * element_coordinates = c.coordinates;
151
// Compute Jacobian of affine map from reference cell
152
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
153
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
154
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
155
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
157
// Compute determinant of Jacobian
158
const double detJ = J_00*J_11 - J_01*J_10;
160
// Compute inverse of Jacobian
162
// Get coordinates and map to the reference (UFC) element
163
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
164
element_coordinates[0][0]*element_coordinates[2][1] +\
165
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
166
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
167
element_coordinates[1][0]*element_coordinates[0][1] -\
168
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
170
// Map coordinates to the reference square
171
if (std::abs(y - 1.0) < 1e-08)
174
x = 2.0 *x/(1.0 - y) - 1.0;
177
// Compute number of derivatives
178
unsigned int num_derivatives = 1;
180
for (unsigned int j = 0; j < n; j++)
181
num_derivatives *= 2;
184
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
185
unsigned int **combinations = new unsigned int *[num_derivatives];
187
for (unsigned int j = 0; j < num_derivatives; j++)
189
combinations[j] = new unsigned int [n];
190
for (unsigned int k = 0; k < n; k++)
191
combinations[j][k] = 0;
194
// Generate combinations of derivatives
195
for (unsigned int row = 1; row < num_derivatives; row++)
197
for (unsigned int num = 0; num < row; num++)
199
for (unsigned int col = n-1; col+1 > 0; col--)
201
if (combinations[row][col] + 1 > 1)
202
combinations[row][col] = 0;
205
combinations[row][col] += 1;
212
// Compute inverse of Jacobian
213
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
215
// Declare transformation matrix
216
// Declare pointer to two dimensional array and initialise
217
double **transform = new double *[num_derivatives];
219
for (unsigned int j = 0; j < num_derivatives; j++)
221
transform[j] = new double [num_derivatives];
222
for (unsigned int k = 0; k < num_derivatives; k++)
226
// Construct transformation matrix
227
for (unsigned int row = 0; row < num_derivatives; row++)
229
for (unsigned int col = 0; col < num_derivatives; col++)
231
for (unsigned int k = 0; k < n; k++)
232
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
237
for (unsigned int j = 0; j < 1*num_derivatives; j++)
240
// Map degree of freedom to element degree of freedom
241
const unsigned int dof = i;
244
const double scalings_y_0 = 1;
245
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
247
// Compute psitilde_a
248
const double psitilde_a_0 = 1;
249
const double psitilde_a_1 = x;
251
// Compute psitilde_bs
252
const double psitilde_bs_0_0 = 1;
253
const double psitilde_bs_0_1 = 1.5*y + 0.5;
254
const double psitilde_bs_1_0 = 1;
256
// Compute basisvalues
257
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
258
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
259
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
261
// Table(s) of coefficients
262
static const double coefficients0[3][3] = \
263
{{0.471404521, -0.288675135, -0.166666667},
264
{0.471404521, 0.288675135, -0.166666667},
265
{0.471404521, 0, 0.333333333}};
267
// Interesting (new) part
268
// Tables of derivatives of the polynomial base (transpose)
269
static const double dmats0[3][3] = \
274
static const double dmats1[3][3] = \
279
// Compute reference derivatives
280
// Declare pointer to array of derivatives on FIAT element
281
double *derivatives = new double [num_derivatives];
283
// Declare coefficients
288
// Declare new coefficients
289
double new_coeff0_0 = 0;
290
double new_coeff0_1 = 0;
291
double new_coeff0_2 = 0;
293
// Loop possible derivatives
294
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
296
// Get values from coefficients array
297
new_coeff0_0 = coefficients0[dof][0];
298
new_coeff0_1 = coefficients0[dof][1];
299
new_coeff0_2 = coefficients0[dof][2];
301
// Loop derivative order
302
for (unsigned int j = 0; j < n; j++)
304
// Update old coefficients
305
coeff0_0 = new_coeff0_0;
306
coeff0_1 = new_coeff0_1;
307
coeff0_2 = new_coeff0_2;
309
if(combinations[deriv_num][j] == 0)
311
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
312
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
313
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
315
if(combinations[deriv_num][j] == 1)
317
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
318
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
319
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
323
// Compute derivatives on reference element as dot product of coefficients and basisvalues
324
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
327
// Transform derivatives back to physical element
328
for (unsigned int row = 0; row < num_derivatives; row++)
330
for (unsigned int col = 0; col < num_derivatives; col++)
332
values[row] += transform[row][col]*derivatives[col];
335
// Delete pointer to array of derivatives on FIAT element
336
delete [] derivatives;
338
// Delete pointer to array of combinations of derivatives and transform
339
for (unsigned int row = 0; row < num_derivatives; row++)
341
delete [] combinations[row];
342
delete [] transform[row];
345
delete [] combinations;
349
/// Evaluate order n derivatives of all basis functions at given point in cell
350
virtual void evaluate_basis_derivatives_all(unsigned int n,
352
const double* coordinates,
353
const ufc::cell& c) const
355
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
358
/// Evaluate linear functional for dof i on the function f
359
virtual double evaluate_dof(unsigned int i,
360
const ufc::function& f,
361
const ufc::cell& c) const
363
// The reference points, direction and weights:
364
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
365
static const double W[3][1] = {{1}, {1}, {1}};
366
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
368
const double * const * x = c.coordinates;
370
// Iterate over the points:
371
// Evaluate basis functions for affine mapping
372
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
373
const double w1 = X[i][0][0];
374
const double w2 = X[i][0][1];
376
// Compute affine mapping y = F(X)
378
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
379
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
381
// Evaluate function at physical points
383
f.evaluate(values, y, c);
385
// Map function values using appropriate mapping
386
// Affine map: Do nothing
388
// Note that we do not map the weights (yet).
390
// Take directional components
391
for(int k = 0; k < 1; k++)
392
result += values[k]*D[i][0][k];
393
// Multiply by weights
399
/// Evaluate linear functionals for all dofs on the function f
400
virtual void evaluate_dofs(double* values,
401
const ufc::function& f,
402
const ufc::cell& c) const
404
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
407
/// Interpolate vertex values from dof values
408
virtual void interpolate_vertex_values(double* vertex_values,
409
const double* dof_values,
410
const ufc::cell& c) const
412
// Evaluate at vertices and use affine mapping
413
vertex_values[0] = dof_values[0];
414
vertex_values[1] = dof_values[1];
415
vertex_values[2] = dof_values[2];
418
/// Return the number of sub elements (for a mixed element)
419
virtual unsigned int num_sub_elements() const
424
/// Create a new finite element for sub element i (for a mixed element)
425
virtual ufc::finite_element* create_sub_element(unsigned int i) const
427
return new poissondg_0_finite_element_0();
432
/// This class defines the interface for a finite element.
434
class poissondg_0_finite_element_1: public ufc::finite_element
439
poissondg_0_finite_element_1() : ufc::finite_element()
445
virtual ~poissondg_0_finite_element_1()
450
/// Return a string identifying the finite element
451
virtual const char* signature() const
453
return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
456
/// Return the cell shape
457
virtual ufc::shape cell_shape() const
459
return ufc::triangle;
462
/// Return the dimension of the finite element function space
463
virtual unsigned int space_dimension() const
468
/// Return the rank of the value space
469
virtual unsigned int value_rank() const
474
/// Return the dimension of the value space for axis i
475
virtual unsigned int value_dimension(unsigned int i) const
480
/// Evaluate basis function i at given point in cell
481
virtual void evaluate_basis(unsigned int i,
483
const double* coordinates,
484
const ufc::cell& c) const
486
// Extract vertex coordinates
487
const double * const * element_coordinates = c.coordinates;
489
// Compute Jacobian of affine map from reference cell
490
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
491
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
492
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
493
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
495
// Compute determinant of Jacobian
496
const double detJ = J_00*J_11 - J_01*J_10;
498
// Compute inverse of Jacobian
500
// Get coordinates and map to the reference (UFC) element
501
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
502
element_coordinates[0][0]*element_coordinates[2][1] +\
503
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
504
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
505
element_coordinates[1][0]*element_coordinates[0][1] -\
506
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
508
// Map coordinates to the reference square
509
if (std::abs(y - 1.0) < 1e-08)
512
x = 2.0 *x/(1.0 - y) - 1.0;
518
// Map degree of freedom to element degree of freedom
519
const unsigned int dof = i;
522
const double scalings_y_0 = 1;
523
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
525
// Compute psitilde_a
526
const double psitilde_a_0 = 1;
527
const double psitilde_a_1 = x;
529
// Compute psitilde_bs
530
const double psitilde_bs_0_0 = 1;
531
const double psitilde_bs_0_1 = 1.5*y + 0.5;
532
const double psitilde_bs_1_0 = 1;
534
// Compute basisvalues
535
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
536
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
537
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
539
// Table(s) of coefficients
540
static const double coefficients0[3][3] = \
541
{{0.471404521, -0.288675135, -0.166666667},
542
{0.471404521, 0.288675135, -0.166666667},
543
{0.471404521, 0, 0.333333333}};
545
// Extract relevant coefficients
546
const double coeff0_0 = coefficients0[dof][0];
547
const double coeff0_1 = coefficients0[dof][1];
548
const double coeff0_2 = coefficients0[dof][2];
551
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
554
/// Evaluate all basis functions at given point in cell
555
virtual void evaluate_basis_all(double* values,
556
const double* coordinates,
557
const ufc::cell& c) const
559
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
562
/// Evaluate order n derivatives of basis function i at given point in cell
563
virtual void evaluate_basis_derivatives(unsigned int i,
566
const double* coordinates,
567
const ufc::cell& c) const
569
// Extract vertex coordinates
570
const double * const * element_coordinates = c.coordinates;
572
// Compute Jacobian of affine map from reference cell
573
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
574
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
575
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
576
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
578
// Compute determinant of Jacobian
579
const double detJ = J_00*J_11 - J_01*J_10;
581
// Compute inverse of Jacobian
583
// Get coordinates and map to the reference (UFC) element
584
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
585
element_coordinates[0][0]*element_coordinates[2][1] +\
586
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
587
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
588
element_coordinates[1][0]*element_coordinates[0][1] -\
589
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
591
// Map coordinates to the reference square
592
if (std::abs(y - 1.0) < 1e-08)
595
x = 2.0 *x/(1.0 - y) - 1.0;
598
// Compute number of derivatives
599
unsigned int num_derivatives = 1;
601
for (unsigned int j = 0; j < n; j++)
602
num_derivatives *= 2;
605
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
606
unsigned int **combinations = new unsigned int *[num_derivatives];
608
for (unsigned int j = 0; j < num_derivatives; j++)
610
combinations[j] = new unsigned int [n];
611
for (unsigned int k = 0; k < n; k++)
612
combinations[j][k] = 0;
615
// Generate combinations of derivatives
616
for (unsigned int row = 1; row < num_derivatives; row++)
618
for (unsigned int num = 0; num < row; num++)
620
for (unsigned int col = n-1; col+1 > 0; col--)
622
if (combinations[row][col] + 1 > 1)
623
combinations[row][col] = 0;
626
combinations[row][col] += 1;
633
// Compute inverse of Jacobian
634
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
636
// Declare transformation matrix
637
// Declare pointer to two dimensional array and initialise
638
double **transform = new double *[num_derivatives];
640
for (unsigned int j = 0; j < num_derivatives; j++)
642
transform[j] = new double [num_derivatives];
643
for (unsigned int k = 0; k < num_derivatives; k++)
647
// Construct transformation matrix
648
for (unsigned int row = 0; row < num_derivatives; row++)
650
for (unsigned int col = 0; col < num_derivatives; col++)
652
for (unsigned int k = 0; k < n; k++)
653
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
658
for (unsigned int j = 0; j < 1*num_derivatives; j++)
661
// Map degree of freedom to element degree of freedom
662
const unsigned int dof = i;
665
const double scalings_y_0 = 1;
666
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
668
// Compute psitilde_a
669
const double psitilde_a_0 = 1;
670
const double psitilde_a_1 = x;
672
// Compute psitilde_bs
673
const double psitilde_bs_0_0 = 1;
674
const double psitilde_bs_0_1 = 1.5*y + 0.5;
675
const double psitilde_bs_1_0 = 1;
677
// Compute basisvalues
678
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
679
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
680
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
682
// Table(s) of coefficients
683
static const double coefficients0[3][3] = \
684
{{0.471404521, -0.288675135, -0.166666667},
685
{0.471404521, 0.288675135, -0.166666667},
686
{0.471404521, 0, 0.333333333}};
688
// Interesting (new) part
689
// Tables of derivatives of the polynomial base (transpose)
690
static const double dmats0[3][3] = \
695
static const double dmats1[3][3] = \
700
// Compute reference derivatives
701
// Declare pointer to array of derivatives on FIAT element
702
double *derivatives = new double [num_derivatives];
704
// Declare coefficients
709
// Declare new coefficients
710
double new_coeff0_0 = 0;
711
double new_coeff0_1 = 0;
712
double new_coeff0_2 = 0;
714
// Loop possible derivatives
715
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
717
// Get values from coefficients array
718
new_coeff0_0 = coefficients0[dof][0];
719
new_coeff0_1 = coefficients0[dof][1];
720
new_coeff0_2 = coefficients0[dof][2];
722
// Loop derivative order
723
for (unsigned int j = 0; j < n; j++)
725
// Update old coefficients
726
coeff0_0 = new_coeff0_0;
727
coeff0_1 = new_coeff0_1;
728
coeff0_2 = new_coeff0_2;
730
if(combinations[deriv_num][j] == 0)
732
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
733
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
734
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
736
if(combinations[deriv_num][j] == 1)
738
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
739
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
740
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
744
// Compute derivatives on reference element as dot product of coefficients and basisvalues
745
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
748
// Transform derivatives back to physical element
749
for (unsigned int row = 0; row < num_derivatives; row++)
751
for (unsigned int col = 0; col < num_derivatives; col++)
753
values[row] += transform[row][col]*derivatives[col];
756
// Delete pointer to array of derivatives on FIAT element
757
delete [] derivatives;
759
// Delete pointer to array of combinations of derivatives and transform
760
for (unsigned int row = 0; row < num_derivatives; row++)
762
delete [] combinations[row];
763
delete [] transform[row];
766
delete [] combinations;
770
/// Evaluate order n derivatives of all basis functions at given point in cell
771
virtual void evaluate_basis_derivatives_all(unsigned int n,
773
const double* coordinates,
774
const ufc::cell& c) const
776
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
779
/// Evaluate linear functional for dof i on the function f
780
virtual double evaluate_dof(unsigned int i,
781
const ufc::function& f,
782
const ufc::cell& c) const
784
// The reference points, direction and weights:
785
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
786
static const double W[3][1] = {{1}, {1}, {1}};
787
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
789
const double * const * x = c.coordinates;
791
// Iterate over the points:
792
// Evaluate basis functions for affine mapping
793
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
794
const double w1 = X[i][0][0];
795
const double w2 = X[i][0][1];
797
// Compute affine mapping y = F(X)
799
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
800
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
802
// Evaluate function at physical points
804
f.evaluate(values, y, c);
806
// Map function values using appropriate mapping
807
// Affine map: Do nothing
809
// Note that we do not map the weights (yet).
811
// Take directional components
812
for(int k = 0; k < 1; k++)
813
result += values[k]*D[i][0][k];
814
// Multiply by weights
820
/// Evaluate linear functionals for all dofs on the function f
821
virtual void evaluate_dofs(double* values,
822
const ufc::function& f,
823
const ufc::cell& c) const
825
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
828
/// Interpolate vertex values from dof values
829
virtual void interpolate_vertex_values(double* vertex_values,
830
const double* dof_values,
831
const ufc::cell& c) const
833
// Evaluate at vertices and use affine mapping
834
vertex_values[0] = dof_values[0];
835
vertex_values[1] = dof_values[1];
836
vertex_values[2] = dof_values[2];
839
/// Return the number of sub elements (for a mixed element)
840
virtual unsigned int num_sub_elements() const
845
/// Create a new finite element for sub element i (for a mixed element)
846
virtual ufc::finite_element* create_sub_element(unsigned int i) const
848
return new poissondg_0_finite_element_1();
853
/// This class defines the interface for a finite element.
855
class poissondg_0_finite_element_2: public ufc::finite_element
860
poissondg_0_finite_element_2() : ufc::finite_element()
866
virtual ~poissondg_0_finite_element_2()
871
/// Return a string identifying the finite element
872
virtual const char* signature() const
874
return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
877
/// Return the cell shape
878
virtual ufc::shape cell_shape() const
880
return ufc::triangle;
883
/// Return the dimension of the finite element function space
884
virtual unsigned int space_dimension() const
889
/// Return the rank of the value space
890
virtual unsigned int value_rank() const
895
/// Return the dimension of the value space for axis i
896
virtual unsigned int value_dimension(unsigned int i) const
901
/// Evaluate basis function i at given point in cell
902
virtual void evaluate_basis(unsigned int i,
904
const double* coordinates,
905
const ufc::cell& c) const
907
// Extract vertex coordinates
908
const double * const * element_coordinates = c.coordinates;
910
// Compute Jacobian of affine map from reference cell
911
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
912
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
913
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
914
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
916
// Compute determinant of Jacobian
917
const double detJ = J_00*J_11 - J_01*J_10;
919
// Compute inverse of Jacobian
921
// Get coordinates and map to the reference (UFC) element
922
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
923
element_coordinates[0][0]*element_coordinates[2][1] +\
924
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
925
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
926
element_coordinates[1][0]*element_coordinates[0][1] -\
927
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
929
// Map coordinates to the reference square
930
if (std::abs(y - 1.0) < 1e-08)
933
x = 2.0 *x/(1.0 - y) - 1.0;
939
// Map degree of freedom to element degree of freedom
940
const unsigned int dof = i;
943
const double scalings_y_0 = 1;
945
// Compute psitilde_a
946
const double psitilde_a_0 = 1;
948
// Compute psitilde_bs
949
const double psitilde_bs_0_0 = 1;
951
// Compute basisvalues
952
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
954
// Table(s) of coefficients
955
static const double coefficients0[1][1] = \
958
// Extract relevant coefficients
959
const double coeff0_0 = coefficients0[dof][0];
962
*values = coeff0_0*basisvalue0;
965
/// Evaluate all basis functions at given point in cell
966
virtual void evaluate_basis_all(double* values,
967
const double* coordinates,
968
const ufc::cell& c) const
970
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
973
/// Evaluate order n derivatives of basis function i at given point in cell
974
virtual void evaluate_basis_derivatives(unsigned int i,
977
const double* coordinates,
978
const ufc::cell& c) const
980
// Extract vertex coordinates
981
const double * const * element_coordinates = c.coordinates;
983
// Compute Jacobian of affine map from reference cell
984
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
985
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
986
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
987
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
989
// Compute determinant of Jacobian
990
const double detJ = J_00*J_11 - J_01*J_10;
992
// Compute inverse of Jacobian
994
// Get coordinates and map to the reference (UFC) element
995
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
996
element_coordinates[0][0]*element_coordinates[2][1] +\
997
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
998
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
999
element_coordinates[1][0]*element_coordinates[0][1] -\
1000
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1002
// Map coordinates to the reference square
1003
if (std::abs(y - 1.0) < 1e-08)
1006
x = 2.0 *x/(1.0 - y) - 1.0;
1009
// Compute number of derivatives
1010
unsigned int num_derivatives = 1;
1012
for (unsigned int j = 0; j < n; j++)
1013
num_derivatives *= 2;
1016
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1017
unsigned int **combinations = new unsigned int *[num_derivatives];
1019
for (unsigned int j = 0; j < num_derivatives; j++)
1021
combinations[j] = new unsigned int [n];
1022
for (unsigned int k = 0; k < n; k++)
1023
combinations[j][k] = 0;
1026
// Generate combinations of derivatives
1027
for (unsigned int row = 1; row < num_derivatives; row++)
1029
for (unsigned int num = 0; num < row; num++)
1031
for (unsigned int col = n-1; col+1 > 0; col--)
1033
if (combinations[row][col] + 1 > 1)
1034
combinations[row][col] = 0;
1037
combinations[row][col] += 1;
1044
// Compute inverse of Jacobian
1045
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1047
// Declare transformation matrix
1048
// Declare pointer to two dimensional array and initialise
1049
double **transform = new double *[num_derivatives];
1051
for (unsigned int j = 0; j < num_derivatives; j++)
1053
transform[j] = new double [num_derivatives];
1054
for (unsigned int k = 0; k < num_derivatives; k++)
1055
transform[j][k] = 1;
1058
// Construct transformation matrix
1059
for (unsigned int row = 0; row < num_derivatives; row++)
1061
for (unsigned int col = 0; col < num_derivatives; col++)
1063
for (unsigned int k = 0; k < n; k++)
1064
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1069
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1072
// Map degree of freedom to element degree of freedom
1073
const unsigned int dof = i;
1075
// Generate scalings
1076
const double scalings_y_0 = 1;
1078
// Compute psitilde_a
1079
const double psitilde_a_0 = 1;
1081
// Compute psitilde_bs
1082
const double psitilde_bs_0_0 = 1;
1084
// Compute basisvalues
1085
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1087
// Table(s) of coefficients
1088
static const double coefficients0[1][1] = \
1091
// Interesting (new) part
1092
// Tables of derivatives of the polynomial base (transpose)
1093
static const double dmats0[1][1] = \
1096
static const double dmats1[1][1] = \
1099
// Compute reference derivatives
1100
// Declare pointer to array of derivatives on FIAT element
1101
double *derivatives = new double [num_derivatives];
1103
// Declare coefficients
1104
double coeff0_0 = 0;
1106
// Declare new coefficients
1107
double new_coeff0_0 = 0;
1109
// Loop possible derivatives
1110
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1112
// Get values from coefficients array
1113
new_coeff0_0 = coefficients0[dof][0];
1115
// Loop derivative order
1116
for (unsigned int j = 0; j < n; j++)
1118
// Update old coefficients
1119
coeff0_0 = new_coeff0_0;
1121
if(combinations[deriv_num][j] == 0)
1123
new_coeff0_0 = coeff0_0*dmats0[0][0];
1125
if(combinations[deriv_num][j] == 1)
1127
new_coeff0_0 = coeff0_0*dmats1[0][0];
1131
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1132
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
1135
// Transform derivatives back to physical element
1136
for (unsigned int row = 0; row < num_derivatives; row++)
1138
for (unsigned int col = 0; col < num_derivatives; col++)
1140
values[row] += transform[row][col]*derivatives[col];
1143
// Delete pointer to array of derivatives on FIAT element
1144
delete [] derivatives;
1146
// Delete pointer to array of combinations of derivatives and transform
1147
for (unsigned int row = 0; row < num_derivatives; row++)
1149
delete [] combinations[row];
1150
delete [] transform[row];
1153
delete [] combinations;
1154
delete [] transform;
1157
/// Evaluate order n derivatives of all basis functions at given point in cell
1158
virtual void evaluate_basis_derivatives_all(unsigned int n,
1160
const double* coordinates,
1161
const ufc::cell& c) const
1163
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1166
/// Evaluate linear functional for dof i on the function f
1167
virtual double evaluate_dof(unsigned int i,
1168
const ufc::function& f,
1169
const ufc::cell& c) const
1171
// The reference points, direction and weights:
1172
static const double X[1][1][2] = {{{0.333333333, 0.333333333}}};
1173
static const double W[1][1] = {{1}};
1174
static const double D[1][1][1] = {{{1}}};
1176
const double * const * x = c.coordinates;
1177
double result = 0.0;
1178
// Iterate over the points:
1179
// Evaluate basis functions for affine mapping
1180
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1181
const double w1 = X[i][0][0];
1182
const double w2 = X[i][0][1];
1184
// Compute affine mapping y = F(X)
1186
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1187
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1189
// Evaluate function at physical points
1191
f.evaluate(values, y, c);
1193
// Map function values using appropriate mapping
1194
// Affine map: Do nothing
1196
// Note that we do not map the weights (yet).
1198
// Take directional components
1199
for(int k = 0; k < 1; k++)
1200
result += values[k]*D[i][0][k];
1201
// Multiply by weights
1207
/// Evaluate linear functionals for all dofs on the function f
1208
virtual void evaluate_dofs(double* values,
1209
const ufc::function& f,
1210
const ufc::cell& c) const
1212
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1215
/// Interpolate vertex values from dof values
1216
virtual void interpolate_vertex_values(double* vertex_values,
1217
const double* dof_values,
1218
const ufc::cell& c) const
1220
// Evaluate at vertices and use affine mapping
1221
vertex_values[0] = dof_values[0];
1222
vertex_values[1] = dof_values[0];
1223
vertex_values[2] = dof_values[0];
1226
/// Return the number of sub elements (for a mixed element)
1227
virtual unsigned int num_sub_elements() const
1232
/// Create a new finite element for sub element i (for a mixed element)
1233
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1235
return new poissondg_0_finite_element_2();
1240
/// This class defines the interface for a local-to-global mapping of
1241
/// degrees of freedom (dofs).
1243
class poissondg_0_dof_map_0: public ufc::dof_map
1247
unsigned int __global_dimension;
1252
poissondg_0_dof_map_0() : ufc::dof_map()
1254
__global_dimension = 0;
1258
virtual ~poissondg_0_dof_map_0()
1263
/// Return a string identifying the dof map
1264
virtual const char* signature() const
1266
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
1269
/// Return true iff mesh entities of topological dimension d are needed
1270
virtual bool needs_mesh_entities(unsigned int d) const
1287
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1288
virtual bool init_mesh(const ufc::mesh& m)
1290
__global_dimension = 3*m.num_entities[2];
1294
/// Initialize dof map for given cell
1295
virtual void init_cell(const ufc::mesh& m,
1301
/// Finish initialization of dof map for cells
1302
virtual void init_cell_finalize()
1307
/// Return the dimension of the global finite element function space
1308
virtual unsigned int global_dimension() const
1310
return __global_dimension;
1313
/// Return the dimension of the local finite element function space for a cell
1314
virtual unsigned int local_dimension(const ufc::cell& c) const
1319
/// Return the maximum dimension of the local finite element function space
1320
virtual unsigned int max_local_dimension() const
1325
// Return the geometric dimension of the coordinates this dof map provides
1326
virtual unsigned int geometric_dimension() const
1331
/// Return the number of dofs on each cell facet
1332
virtual unsigned int num_facet_dofs() const
1337
/// Return the number of dofs associated with each cell entity of dimension d
1338
virtual unsigned int num_entity_dofs(unsigned int d) const
1340
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1343
/// Tabulate the local-to-global mapping of dofs on a cell
1344
virtual void tabulate_dofs(unsigned int* dofs,
1346
const ufc::cell& c) const
1348
dofs[0] = 3*c.entity_indices[2][0];
1349
dofs[1] = 3*c.entity_indices[2][0] + 1;
1350
dofs[2] = 3*c.entity_indices[2][0] + 2;
1353
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1354
virtual void tabulate_facet_dofs(unsigned int* dofs,
1355
unsigned int facet) const
1371
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1372
virtual void tabulate_entity_dofs(unsigned int* dofs,
1373
unsigned int d, unsigned int i) const
1375
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1378
/// Tabulate the coordinates of all dofs on a cell
1379
virtual void tabulate_coordinates(double** coordinates,
1380
const ufc::cell& c) const
1382
const double * const * x = c.coordinates;
1383
coordinates[0][0] = x[0][0];
1384
coordinates[0][1] = x[0][1];
1385
coordinates[1][0] = x[1][0];
1386
coordinates[1][1] = x[1][1];
1387
coordinates[2][0] = x[2][0];
1388
coordinates[2][1] = x[2][1];
1391
/// Return the number of sub dof maps (for a mixed element)
1392
virtual unsigned int num_sub_dof_maps() const
1397
/// Create a new dof_map for sub dof map i (for a mixed element)
1398
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1400
return new poissondg_0_dof_map_0();
1405
/// This class defines the interface for a local-to-global mapping of
1406
/// degrees of freedom (dofs).
1408
class poissondg_0_dof_map_1: public ufc::dof_map
1412
unsigned int __global_dimension;
1417
poissondg_0_dof_map_1() : ufc::dof_map()
1419
__global_dimension = 0;
1423
virtual ~poissondg_0_dof_map_1()
1428
/// Return a string identifying the dof map
1429
virtual const char* signature() const
1431
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
1434
/// Return true iff mesh entities of topological dimension d are needed
1435
virtual bool needs_mesh_entities(unsigned int d) const
1452
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1453
virtual bool init_mesh(const ufc::mesh& m)
1455
__global_dimension = 3*m.num_entities[2];
1459
/// Initialize dof map for given cell
1460
virtual void init_cell(const ufc::mesh& m,
1466
/// Finish initialization of dof map for cells
1467
virtual void init_cell_finalize()
1472
/// Return the dimension of the global finite element function space
1473
virtual unsigned int global_dimension() const
1475
return __global_dimension;
1478
/// Return the dimension of the local finite element function space for a cell
1479
virtual unsigned int local_dimension(const ufc::cell& c) const
1484
/// Return the maximum dimension of the local finite element function space
1485
virtual unsigned int max_local_dimension() const
1490
// Return the geometric dimension of the coordinates this dof map provides
1491
virtual unsigned int geometric_dimension() const
1496
/// Return the number of dofs on each cell facet
1497
virtual unsigned int num_facet_dofs() const
1502
/// Return the number of dofs associated with each cell entity of dimension d
1503
virtual unsigned int num_entity_dofs(unsigned int d) const
1505
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1508
/// Tabulate the local-to-global mapping of dofs on a cell
1509
virtual void tabulate_dofs(unsigned int* dofs,
1511
const ufc::cell& c) const
1513
dofs[0] = 3*c.entity_indices[2][0];
1514
dofs[1] = 3*c.entity_indices[2][0] + 1;
1515
dofs[2] = 3*c.entity_indices[2][0] + 2;
1518
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1519
virtual void tabulate_facet_dofs(unsigned int* dofs,
1520
unsigned int facet) const
1536
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1537
virtual void tabulate_entity_dofs(unsigned int* dofs,
1538
unsigned int d, unsigned int i) const
1540
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1543
/// Tabulate the coordinates of all dofs on a cell
1544
virtual void tabulate_coordinates(double** coordinates,
1545
const ufc::cell& c) const
1547
const double * const * x = c.coordinates;
1548
coordinates[0][0] = x[0][0];
1549
coordinates[0][1] = x[0][1];
1550
coordinates[1][0] = x[1][0];
1551
coordinates[1][1] = x[1][1];
1552
coordinates[2][0] = x[2][0];
1553
coordinates[2][1] = x[2][1];
1556
/// Return the number of sub dof maps (for a mixed element)
1557
virtual unsigned int num_sub_dof_maps() const
1562
/// Create a new dof_map for sub dof map i (for a mixed element)
1563
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1565
return new poissondg_0_dof_map_1();
1570
/// This class defines the interface for a local-to-global mapping of
1571
/// degrees of freedom (dofs).
1573
class poissondg_0_dof_map_2: public ufc::dof_map
1577
unsigned int __global_dimension;
1582
poissondg_0_dof_map_2() : ufc::dof_map()
1584
__global_dimension = 0;
1588
virtual ~poissondg_0_dof_map_2()
1593
/// Return a string identifying the dof map
1594
virtual const char* signature() const
1596
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
1599
/// Return true iff mesh entities of topological dimension d are needed
1600
virtual bool needs_mesh_entities(unsigned int d) const
1617
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1618
virtual bool init_mesh(const ufc::mesh& m)
1620
__global_dimension = m.num_entities[2];
1624
/// Initialize dof map for given cell
1625
virtual void init_cell(const ufc::mesh& m,
1631
/// Finish initialization of dof map for cells
1632
virtual void init_cell_finalize()
1637
/// Return the dimension of the global finite element function space
1638
virtual unsigned int global_dimension() const
1640
return __global_dimension;
1643
/// Return the dimension of the local finite element function space for a cell
1644
virtual unsigned int local_dimension(const ufc::cell& c) const
1649
/// Return the maximum dimension of the local finite element function space
1650
virtual unsigned int max_local_dimension() const
1655
// Return the geometric dimension of the coordinates this dof map provides
1656
virtual unsigned int geometric_dimension() const
1661
/// Return the number of dofs on each cell facet
1662
virtual unsigned int num_facet_dofs() const
1667
/// Return the number of dofs associated with each cell entity of dimension d
1668
virtual unsigned int num_entity_dofs(unsigned int d) const
1670
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1673
/// Tabulate the local-to-global mapping of dofs on a cell
1674
virtual void tabulate_dofs(unsigned int* dofs,
1676
const ufc::cell& c) const
1678
dofs[0] = c.entity_indices[2][0];
1681
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1682
virtual void tabulate_facet_dofs(unsigned int* dofs,
1683
unsigned int facet) const
1699
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1700
virtual void tabulate_entity_dofs(unsigned int* dofs,
1701
unsigned int d, unsigned int i) const
1703
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1706
/// Tabulate the coordinates of all dofs on a cell
1707
virtual void tabulate_coordinates(double** coordinates,
1708
const ufc::cell& c) const
1710
const double * const * x = c.coordinates;
1711
coordinates[0][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
1712
coordinates[0][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
1715
/// Return the number of sub dof maps (for a mixed element)
1716
virtual unsigned int num_sub_dof_maps() const
1721
/// Create a new dof_map for sub dof map i (for a mixed element)
1722
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1724
return new poissondg_0_dof_map_2();
1729
/// This class defines the interface for the tabulation of the cell
1730
/// tensor corresponding to the local contribution to a form from
1731
/// the integral over a cell.
1733
class poissondg_0_cell_integral_0_quadrature: public ufc::cell_integral
1738
poissondg_0_cell_integral_0_quadrature() : ufc::cell_integral()
1744
virtual ~poissondg_0_cell_integral_0_quadrature()
1749
/// Tabulate the tensor for the contribution from a local cell
1750
virtual void tabulate_tensor(double* A,
1751
const double * const * w,
1752
const ufc::cell& c) const
1754
// Extract vertex coordinates
1755
const double * const * x = c.coordinates;
1757
// Compute Jacobian of affine map from reference cell
1758
const double J_00 = x[1][0] - x[0][0];
1759
const double J_01 = x[2][0] - x[0][0];
1760
const double J_10 = x[1][1] - x[0][1];
1761
const double J_11 = x[2][1] - x[0][1];
1763
// Compute determinant of Jacobian
1764
double detJ = J_00*J_11 - J_01*J_10;
1766
// Compute inverse of Jacobian
1767
const double Jinv_00 = J_11 / detJ;
1768
const double Jinv_01 = -J_01 / detJ;
1769
const double Jinv_10 = -J_10 / detJ;
1770
const double Jinv_11 = J_00 / detJ;
1773
const double det = std::abs(detJ);
1776
// Array of quadrature weights
1777
static const double W1 = 0.5;
1778
// Quadrature points on the UFC reference element: (0.333333333, 0.333333333)
1780
// Value of basis functions at quadrature points.
1781
static const double FE0_D01[1][3] = \
1784
static const double FE0_D10[1][3] = \
1788
// Compute element tensor using UFL quadrature representation
1789
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
1790
// Total number of operations to compute element tensor: 162
1792
// Loop quadrature points for integral
1793
// Number of operations to compute element tensor for following IP loop = 162
1794
// Only 1 integration point, omitting IP loop.
1796
// Number of operations for primary indices: 162
1797
for (unsigned int j = 0; j < 3; j++)
1799
for (unsigned int k = 0; k < 3; k++)
1801
// Number of operations to compute entry: 18
1802
A[j*3 + k] += ((Jinv_01*FE0_D10[0][j] + Jinv_11*FE0_D01[0][j])*(Jinv_01*FE0_D10[0][k] + Jinv_11*FE0_D01[0][k]) + (Jinv_00*FE0_D10[0][j] + Jinv_10*FE0_D01[0][j])*(Jinv_00*FE0_D10[0][k] + Jinv_10*FE0_D01[0][k]))*W1*det;
1803
}// end loop over 'k'
1804
}// end loop over 'j'
1809
/// This class defines the interface for the tabulation of the cell
1810
/// tensor corresponding to the local contribution to a form from
1811
/// the integral over a cell.
1813
class poissondg_0_cell_integral_0: public ufc::cell_integral
1817
poissondg_0_cell_integral_0_quadrature integral_0_quadrature;
1822
poissondg_0_cell_integral_0() : ufc::cell_integral()
1828
virtual ~poissondg_0_cell_integral_0()
1833
/// Tabulate the tensor for the contribution from a local cell
1834
virtual void tabulate_tensor(double* A,
1835
const double * const * w,
1836
const ufc::cell& c) const
1838
// Reset values of the element tensor block
1839
for (unsigned int j = 0; j < 9; j++)
1842
// Add all contributions to element tensor
1843
integral_0_quadrature.tabulate_tensor(A, w, c);
1848
/// This class defines the interface for the tabulation of the
1849
/// exterior facet tensor corresponding to the local contribution to
1850
/// a form from the integral over an exterior facet.
1852
class poissondg_0_exterior_facet_integral_0_quadrature: public ufc::exterior_facet_integral
1857
poissondg_0_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
1863
virtual ~poissondg_0_exterior_facet_integral_0_quadrature()
1868
/// Tabulate the tensor for the contribution from a local exterior facet
1869
virtual void tabulate_tensor(double* A,
1870
const double * const * w,
1872
unsigned int facet) const
1874
// Extract vertex coordinates
1875
const double * const * x = c.coordinates;
1877
// Compute Jacobian of affine map from reference cell
1878
const double J_00 = x[1][0] - x[0][0];
1879
const double J_01 = x[2][0] - x[0][0];
1880
const double J_10 = x[1][1] - x[0][1];
1881
const double J_11 = x[2][1] - x[0][1];
1883
// Compute determinant of Jacobian
1884
double detJ = J_00*J_11 - J_01*J_10;
1886
// Compute inverse of Jacobian
1887
const double Jinv_00 = J_11 / detJ;
1888
const double Jinv_01 = -J_01 / detJ;
1889
const double Jinv_10 = -J_10 / detJ;
1890
const double Jinv_11 = J_00 / detJ;
1892
// Vertices on edges
1893
static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
1896
const unsigned int v0 = edge_vertices[facet][0];
1897
const unsigned int v1 = edge_vertices[facet][1];
1899
// Compute scale factor (length of edge scaled by length of reference interval)
1900
const double dx0 = x[v1][0] - x[v0][0];
1901
const double dx1 = x[v1][1] - x[v0][1];
1902
const double det = std::sqrt(dx0*dx0 + dx1*dx1);
1904
const bool direction = dx1*(x[facet][0] - x[v0][0]) - dx0*(x[facet][1] - x[v0][1]) < 0;
1906
// Compute facet normals from the facet scale factor constants
1907
const double n0 = direction ? dx1 / det : -dx1 / det;
1908
const double n1 = direction ? -dx0 / det : dx0 / det;
1911
// Array of quadrature weights
1912
static const double W2[2] = {0.5, 0.5};
1913
// Quadrature points on the UFC reference element: (0.211324865), (0.788675135)
1915
// Value of basis functions at quadrature points.
1916
static const double FE1_f0[2][3] = \
1917
{{0, 0.788675135, 0.211324865},
1918
{0, 0.211324865, 0.788675135}};
1920
static const double FE1_f0_D01[2][3] = \
1924
static const double FE1_f0_D10[2][3] = \
1928
static const double FE1_f1[2][3] = \
1929
{{0.788675135, 0, 0.211324865},
1930
{0.211324865, 0, 0.788675135}};
1932
static const double FE1_f2[2][3] = \
1933
{{0.788675135, 0.211324865, 0},
1934
{0.211324865, 0.788675135, 0}};
1937
// Compute element tensor using UFL quadrature representation
1938
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
1943
// Total number of operations to compute element tensor (from this point): 558
1945
// Loop quadrature points for integral
1946
// Number of operations to compute element tensor for following IP loop = 558
1947
for (unsigned int ip = 0; ip < 2; ip++)
1950
// Number of operations for primary indices: 279
1951
for (unsigned int j = 0; j < 3; j++)
1953
for (unsigned int k = 0; k < 3; k++)
1955
// Number of operations to compute entry: 31
1956
A[j*3 + k] += (FE1_f0[ip][k]*FE1_f0[ip][j]*8/(w[0][0]) + ((FE1_f0[ip][j]*n0*(Jinv_00*FE1_f0_D10[ip][k] + Jinv_10*FE1_f0_D01[ip][k]) + FE1_f0[ip][j]*n1*(Jinv_01*FE1_f0_D10[ip][k] + Jinv_11*FE1_f0_D01[ip][k]))*-1 + (FE1_f0[ip][k]*n0*(Jinv_00*FE1_f0_D10[ip][j] + Jinv_10*FE1_f0_D01[ip][j]) + FE1_f0[ip][k]*n1*(Jinv_01*FE1_f0_D10[ip][j] + Jinv_11*FE1_f0_D01[ip][j]))*-1))*W2[ip]*det;
1957
}// end loop over 'k'
1958
}// end loop over 'j'
1959
}// end loop over 'ip'
1964
// Total number of operations to compute element tensor (from this point): 558
1966
// Loop quadrature points for integral
1967
// Number of operations to compute element tensor for following IP loop = 558
1968
for (unsigned int ip = 0; ip < 2; ip++)
1971
// Number of operations for primary indices: 279
1972
for (unsigned int j = 0; j < 3; j++)
1974
for (unsigned int k = 0; k < 3; k++)
1976
// Number of operations to compute entry: 31
1977
A[j*3 + k] += (FE1_f1[ip][k]*FE1_f1[ip][j]*8/(w[0][0]) + ((FE1_f1[ip][j]*n0*(Jinv_00*FE1_f0_D10[ip][k] + Jinv_10*FE1_f0_D01[ip][k]) + FE1_f1[ip][j]*n1*(Jinv_01*FE1_f0_D10[ip][k] + Jinv_11*FE1_f0_D01[ip][k]))*-1 + (FE1_f1[ip][k]*n1*(Jinv_01*FE1_f0_D10[ip][j] + Jinv_11*FE1_f0_D01[ip][j]) + FE1_f1[ip][k]*n0*(Jinv_00*FE1_f0_D10[ip][j] + Jinv_10*FE1_f0_D01[ip][j]))*-1))*W2[ip]*det;
1978
}// end loop over 'k'
1979
}// end loop over 'j'
1980
}// end loop over 'ip'
1985
// Total number of operations to compute element tensor (from this point): 558
1987
// Loop quadrature points for integral
1988
// Number of operations to compute element tensor for following IP loop = 558
1989
for (unsigned int ip = 0; ip < 2; ip++)
1992
// Number of operations for primary indices: 279
1993
for (unsigned int j = 0; j < 3; j++)
1995
for (unsigned int k = 0; k < 3; k++)
1997
// Number of operations to compute entry: 31
1998
A[j*3 + k] += (FE1_f2[ip][k]*FE1_f2[ip][j]*8/(w[0][0]) + ((FE1_f2[ip][j]*n1*(Jinv_01*FE1_f0_D10[ip][k] + Jinv_11*FE1_f0_D01[ip][k]) + FE1_f2[ip][j]*n0*(Jinv_00*FE1_f0_D10[ip][k] + Jinv_10*FE1_f0_D01[ip][k]))*-1 + (FE1_f2[ip][k]*n0*(Jinv_00*FE1_f0_D10[ip][j] + Jinv_10*FE1_f0_D01[ip][j]) + FE1_f2[ip][k]*n1*(Jinv_01*FE1_f0_D10[ip][j] + Jinv_11*FE1_f0_D01[ip][j]))*-1))*W2[ip]*det;
1999
}// end loop over 'k'
2000
}// end loop over 'j'
2001
}// end loop over 'ip'
2009
/// This class defines the interface for the tabulation of the
2010
/// exterior facet tensor corresponding to the local contribution to
2011
/// a form from the integral over an exterior facet.
2013
class poissondg_0_exterior_facet_integral_0: public ufc::exterior_facet_integral
2017
poissondg_0_exterior_facet_integral_0_quadrature integral_0_quadrature;
2022
poissondg_0_exterior_facet_integral_0() : ufc::exterior_facet_integral()
2028
virtual ~poissondg_0_exterior_facet_integral_0()
2033
/// Tabulate the tensor for the contribution from a local exterior facet
2034
virtual void tabulate_tensor(double* A,
2035
const double * const * w,
2037
unsigned int facet) const
2039
// Reset values of the element tensor block
2040
for (unsigned int j = 0; j < 9; j++)
2043
// Add all contributions to element tensor
2044
integral_0_quadrature.tabulate_tensor(A, w, c, facet);
2049
/// This class defines the interface for the tabulation of the
2050
/// interior facet tensor corresponding to the local contribution to
2051
/// a form from the integral over an interior facet.
2053
class poissondg_0_interior_facet_integral_0_quadrature: public ufc::interior_facet_integral
2058
poissondg_0_interior_facet_integral_0_quadrature() : ufc::interior_facet_integral()
2064
virtual ~poissondg_0_interior_facet_integral_0_quadrature()
2069
/// Tabulate the tensor for the contribution from a local interior facet
2070
virtual void tabulate_tensor(double* A,
2071
const double * const * w,
2072
const ufc::cell& c0,
2073
const ufc::cell& c1,
2074
unsigned int facet0,
2075
unsigned int facet1) const
2077
// Extract vertex coordinates
2078
const double * const * x0 = c0.coordinates;
2080
// Compute Jacobian of affine map from reference cell
2081
const double J0_00 = x0[1][0] - x0[0][0];
2082
const double J0_01 = x0[2][0] - x0[0][0];
2083
const double J0_10 = x0[1][1] - x0[0][1];
2084
const double J0_11 = x0[2][1] - x0[0][1];
2086
// Compute determinant of Jacobian
2087
double detJ0 = J0_00*J0_11 - J0_01*J0_10;
2089
// Compute inverse of Jacobian
2090
const double Jinv0_00 = J0_11 / detJ0;
2091
const double Jinv0_01 = -J0_01 / detJ0;
2092
const double Jinv0_10 = -J0_10 / detJ0;
2093
const double Jinv0_11 = J0_00 / detJ0;
2095
// Extract vertex coordinates
2096
const double * const * x1 = c1.coordinates;
2098
// Compute Jacobian of affine map from reference cell
2099
const double J1_00 = x1[1][0] - x1[0][0];
2100
const double J1_01 = x1[2][0] - x1[0][0];
2101
const double J1_10 = x1[1][1] - x1[0][1];
2102
const double J1_11 = x1[2][1] - x1[0][1];
2104
// Compute determinant of Jacobian
2105
double detJ1 = J1_00*J1_11 - J1_01*J1_10;
2107
// Compute inverse of Jacobian
2108
const double Jinv1_00 = J1_11 / detJ1;
2109
const double Jinv1_01 = -J1_01 / detJ1;
2110
const double Jinv1_10 = -J1_10 / detJ1;
2111
const double Jinv1_11 = J1_00 / detJ1;
2113
// Vertices on edges
2114
static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
2117
const unsigned int v0 = edge_vertices[facet0][0];
2118
const unsigned int v1 = edge_vertices[facet0][1];
2120
// Compute scale factor (length of edge scaled by length of reference interval)
2121
const double dx0 = x0[v1][0] - x0[v0][0];
2122
const double dx1 = x0[v1][1] - x0[v0][1];
2123
const double det = std::sqrt(dx0*dx0 + dx1*dx1);
2125
const bool direction = dx1*(x0[facet0][0] - x0[v0][0]) - dx0*(x0[facet0][1] - x0[v0][1]) < 0;
2127
// Compute facet normals from the facet scale factor constants
2128
const double n00 = direction ? dx1 / det : -dx1 / det;
2129
const double n01 = direction ? -dx0 / det : dx0 / det;
2131
// Compute facet normals from the facet scale factor constants
2132
const double n10 = !direction ? dx1 / det : -dx1 / det;
2133
const double n11 = !direction ? -dx0 / det : dx0 / det;
2136
// Array of quadrature weights
2137
static const double W2[2] = {0.5, 0.5};
2138
// Quadrature points on the UFC reference element: (0.211324865), (0.788675135)
2140
// Value of basis functions at quadrature points.
2141
static const double FE1_f0[2][3] = \
2142
{{0, 0.788675135, 0.211324865},
2143
{0, 0.211324865, 0.788675135}};
2145
static const double FE1_f0_D01[2][3] = \
2149
static const double FE1_f0_D10[2][3] = \
2153
static const double FE1_f1[2][3] = \
2154
{{0.788675135, 0, 0.211324865},
2155
{0.211324865, 0, 0.788675135}};
2157
static const double FE1_f2[2][3] = \
2158
{{0.788675135, 0.211324865, 0},
2159
{0.211324865, 0.788675135, 0}};
2162
// Compute element tensor using UFL quadrature representation
2163
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
2171
// Total number of operations to compute element tensor (from this point): 3024
2173
// Loop quadrature points for integral
2174
// Number of operations to compute element tensor for following IP loop = 3024
2175
for (unsigned int ip = 0; ip < 2; ip++)
2178
// Number of operations for primary indices: 1512
2179
for (unsigned int j = 0; j < 3; j++)
2181
for (unsigned int k = 0; k < 3; k++)
2183
// Number of operations to compute entry: 42
2184
A[(j + 3)*6 + k] += ((FE1_f0[ip][j]*n10*FE1_f0[ip][k]*n00 + FE1_f0[ip][j]*n11*FE1_f0[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n00 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n01)*-1 + ((Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n10 + (Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n11)*-1))*W2[ip]*det;
2185
// Number of operations to compute entry: 42
2186
A[j*6 + (k + 3)] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n10 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n00 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n01)*-1) + (FE1_f0[ip][j]*n00*FE1_f0[ip][k]*n10 + FE1_f0[ip][j]*n01*FE1_f0[ip][k]*n11)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2187
// Number of operations to compute entry: 42
2188
A[j*6 + k] += ((FE1_f0[ip][j]*n00*FE1_f0[ip][k]*n00 + FE1_f0[ip][j]*n01*FE1_f0[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n01 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n00)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n01 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n00)*-1))*W2[ip]*det;
2189
// Number of operations to compute entry: 42
2190
A[(j + 3)*6 + (k + 3)] += ((FE1_f0[ip][j]*n11*FE1_f0[ip][k]*n11 + FE1_f0[ip][j]*n10*FE1_f0[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n10 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n11)*-1))*W2[ip]*det;
2191
}// end loop over 'k'
2192
}// end loop over 'j'
2193
}// end loop over 'ip'
2198
// Total number of operations to compute element tensor (from this point): 3024
2200
// Loop quadrature points for integral
2201
// Number of operations to compute element tensor for following IP loop = 3024
2202
for (unsigned int ip = 0; ip < 2; ip++)
2205
// Number of operations for primary indices: 1512
2206
for (unsigned int j = 0; j < 3; j++)
2208
for (unsigned int k = 0; k < 3; k++)
2210
// Number of operations to compute entry: 42
2211
A[(j + 3)*6 + k] += ((FE1_f1[ip][j]*n10*FE1_f0[ip][k]*n00 + FE1_f1[ip][j]*n11*FE1_f0[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n11 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n10)*-1 + ((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n00 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n01)*-1))*W2[ip]*det;
2212
// Number of operations to compute entry: 42
2213
A[j*6 + (k + 3)] += ((FE1_f0[ip][j]*n00*FE1_f1[ip][k]*n10 + FE1_f0[ip][j]*n01*FE1_f1[ip][k]*n11)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n11 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n10)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n00 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n01)*-1))*W2[ip]*det;
2214
// Number of operations to compute entry: 42
2215
A[j*6 + k] += ((FE1_f0[ip][j]*n00*FE1_f0[ip][k]*n00 + FE1_f0[ip][j]*n01*FE1_f0[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n01 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n00)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n01 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n00)*-1))*W2[ip]*det;
2216
// Number of operations to compute entry: 42
2217
A[(j + 3)*6 + (k + 3)] += ((FE1_f1[ip][j]*n10*FE1_f1[ip][k]*n10 + FE1_f1[ip][j]*n11*FE1_f1[ip][k]*n11)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n10 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n11)*-1))*W2[ip]*det;
2218
}// end loop over 'k'
2219
}// end loop over 'j'
2220
}// end loop over 'ip'
2225
// Total number of operations to compute element tensor (from this point): 3024
2227
// Loop quadrature points for integral
2228
// Number of operations to compute element tensor for following IP loop = 3024
2229
for (unsigned int ip = 0; ip < 2; ip++)
2232
// Number of operations for primary indices: 1512
2233
for (unsigned int j = 0; j < 3; j++)
2235
for (unsigned int k = 0; k < 3; k++)
2237
// Number of operations to compute entry: 42
2238
A[(j + 3)*6 + k] += ((((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n00 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n01)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n11 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n10)*-1) + (FE1_f2[ip][j]*n10*FE1_f0[ip][k]*n00 + FE1_f2[ip][j]*n11*FE1_f0[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2239
// Number of operations to compute entry: 42
2240
A[j*6 + (k + 3)] += ((((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n11 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n10)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n00 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n01)*-1) + (FE1_f0[ip][j]*n01*FE1_f2[ip][k]*n11 + FE1_f0[ip][j]*n00*FE1_f2[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2241
// Number of operations to compute entry: 42
2242
A[j*6 + k] += ((FE1_f0[ip][j]*n00*FE1_f0[ip][k]*n00 + FE1_f0[ip][j]*n01*FE1_f0[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n01 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n00)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n01 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n00)*-1))*W2[ip]*det;
2243
// Number of operations to compute entry: 42
2244
A[(j + 3)*6 + (k + 3)] += ((FE1_f2[ip][j]*n11*FE1_f2[ip][k]*n11 + FE1_f2[ip][j]*n10*FE1_f2[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n11)*-1 + ((Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n11 + (Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n10)*-1))*W2[ip]*det;
2245
}// end loop over 'k'
2246
}// end loop over 'j'
2247
}// end loop over 'ip'
2257
// Total number of operations to compute element tensor (from this point): 3024
2259
// Loop quadrature points for integral
2260
// Number of operations to compute element tensor for following IP loop = 3024
2261
for (unsigned int ip = 0; ip < 2; ip++)
2264
// Number of operations for primary indices: 1512
2265
for (unsigned int j = 0; j < 3; j++)
2267
for (unsigned int k = 0; k < 3; k++)
2269
// Number of operations to compute entry: 42
2270
A[(j + 3)*6 + k] += ((FE1_f0[ip][j]*n11*FE1_f1[ip][k]*n01 + FE1_f0[ip][j]*n10*FE1_f1[ip][k]*n00)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n00 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n01)*-1 + ((Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n10 + (Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n11)*-1))*W2[ip]*det;
2271
// Number of operations to compute entry: 42
2272
A[j*6 + (k + 3)] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n10 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n00 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n01)*-1) + (FE1_f1[ip][j]*n01*FE1_f0[ip][k]*n11 + FE1_f1[ip][j]*n00*FE1_f0[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2273
// Number of operations to compute entry: 42
2274
A[j*6 + k] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n00 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n01)*-1 + ((Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n00 + (Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n01)*-1) + (FE1_f1[ip][j]*n01*FE1_f1[ip][k]*n01 + FE1_f1[ip][j]*n00*FE1_f1[ip][k]*n00)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2275
// Number of operations to compute entry: 42
2276
A[(j + 3)*6 + (k + 3)] += ((FE1_f0[ip][j]*n11*FE1_f0[ip][k]*n11 + FE1_f0[ip][j]*n10*FE1_f0[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n10 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n11)*-1))*W2[ip]*det;
2277
}// end loop over 'k'
2278
}// end loop over 'j'
2279
}// end loop over 'ip'
2284
// Total number of operations to compute element tensor (from this point): 3024
2286
// Loop quadrature points for integral
2287
// Number of operations to compute element tensor for following IP loop = 3024
2288
for (unsigned int ip = 0; ip < 2; ip++)
2291
// Number of operations for primary indices: 1512
2292
for (unsigned int j = 0; j < 3; j++)
2294
for (unsigned int k = 0; k < 3; k++)
2296
// Number of operations to compute entry: 42
2297
A[(j + 3)*6 + k] += ((((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n00 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n01)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n11 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n10)*-1) + (FE1_f1[ip][j]*n10*FE1_f1[ip][k]*n00 + FE1_f1[ip][j]*n11*FE1_f1[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2298
// Number of operations to compute entry: 42
2299
A[j*6 + (k + 3)] += ((FE1_f1[ip][j]*n00*FE1_f1[ip][k]*n10 + FE1_f1[ip][j]*n01*FE1_f1[ip][k]*n11)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n11 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n10)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n00 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n01)*-1))*W2[ip]*det;
2300
// Number of operations to compute entry: 42
2301
A[j*6 + k] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n00 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n01)*-1 + ((Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n00 + (Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n01)*-1) + (FE1_f1[ip][j]*n01*FE1_f1[ip][k]*n01 + FE1_f1[ip][j]*n00*FE1_f1[ip][k]*n00)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2302
// Number of operations to compute entry: 42
2303
A[(j + 3)*6 + (k + 3)] += ((FE1_f1[ip][j]*n10*FE1_f1[ip][k]*n10 + FE1_f1[ip][j]*n11*FE1_f1[ip][k]*n11)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n10 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n11)*-1))*W2[ip]*det;
2304
}// end loop over 'k'
2305
}// end loop over 'j'
2306
}// end loop over 'ip'
2311
// Total number of operations to compute element tensor (from this point): 3024
2313
// Loop quadrature points for integral
2314
// Number of operations to compute element tensor for following IP loop = 3024
2315
for (unsigned int ip = 0; ip < 2; ip++)
2318
// Number of operations for primary indices: 1512
2319
for (unsigned int j = 0; j < 3; j++)
2321
for (unsigned int k = 0; k < 3; k++)
2323
// Number of operations to compute entry: 42
2324
A[(j + 3)*6 + k] += ((FE1_f2[ip][j]*n10*FE1_f1[ip][k]*n00 + FE1_f2[ip][j]*n11*FE1_f1[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n00 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n01)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n11 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n10)*-1))*W2[ip]*det;
2325
// Number of operations to compute entry: 42
2326
A[j*6 + (k + 3)] += ((((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n11 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n10)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n00 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n01)*-1) + (FE1_f1[ip][j]*n00*FE1_f2[ip][k]*n10 + FE1_f1[ip][j]*n01*FE1_f2[ip][k]*n11)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2327
// Number of operations to compute entry: 42
2328
A[j*6 + k] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n00 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n01)*-1 + ((Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n00 + (Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n01)*-1) + (FE1_f1[ip][j]*n01*FE1_f1[ip][k]*n01 + FE1_f1[ip][j]*n00*FE1_f1[ip][k]*n00)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2329
// Number of operations to compute entry: 42
2330
A[(j + 3)*6 + (k + 3)] += ((FE1_f2[ip][j]*n11*FE1_f2[ip][k]*n11 + FE1_f2[ip][j]*n10*FE1_f2[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n11)*-1 + ((Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n11 + (Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n10)*-1))*W2[ip]*det;
2331
}// end loop over 'k'
2332
}// end loop over 'j'
2333
}// end loop over 'ip'
2343
// Total number of operations to compute element tensor (from this point): 3024
2345
// Loop quadrature points for integral
2346
// Number of operations to compute element tensor for following IP loop = 3024
2347
for (unsigned int ip = 0; ip < 2; ip++)
2350
// Number of operations for primary indices: 1512
2351
for (unsigned int j = 0; j < 3; j++)
2353
for (unsigned int k = 0; k < 3; k++)
2355
// Number of operations to compute entry: 42
2356
A[(j + 3)*6 + k] += ((FE1_f0[ip][j]*n11*FE1_f2[ip][k]*n01 + FE1_f0[ip][j]*n10*FE1_f2[ip][k]*n00)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n01 + (Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n00)*-1 + ((Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n10 + (Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n11)*-1))*W2[ip]*det;
2357
// Number of operations to compute entry: 42
2358
A[j*6 + (k + 3)] += ((FE1_f2[ip][j]*n01*FE1_f0[ip][k]*n11 + FE1_f2[ip][j]*n00*FE1_f0[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n10 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n11)*-1 + ((Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n01 + (Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n00)*-1))*W2[ip]*det;
2359
// Number of operations to compute entry: 42
2360
A[j*6 + k] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n00 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n01)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n01 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n00)*-1) + (FE1_f2[ip][j]*n00*FE1_f2[ip][k]*n00 + FE1_f2[ip][j]*n01*FE1_f2[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2361
// Number of operations to compute entry: 42
2362
A[(j + 3)*6 + (k + 3)] += ((FE1_f0[ip][j]*n11*FE1_f0[ip][k]*n11 + FE1_f0[ip][j]*n10*FE1_f0[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f0[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n10 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f0[ip][j]*n11)*-1))*W2[ip]*det;
2363
}// end loop over 'k'
2364
}// end loop over 'j'
2365
}// end loop over 'ip'
2370
// Total number of operations to compute element tensor (from this point): 3024
2372
// Loop quadrature points for integral
2373
// Number of operations to compute element tensor for following IP loop = 3024
2374
for (unsigned int ip = 0; ip < 2; ip++)
2377
// Number of operations for primary indices: 1512
2378
for (unsigned int j = 0; j < 3; j++)
2380
for (unsigned int k = 0; k < 3; k++)
2382
// Number of operations to compute entry: 42
2383
A[(j + 3)*6 + k] += ((FE1_f1[ip][j]*n11*FE1_f2[ip][k]*n01 + FE1_f1[ip][j]*n10*FE1_f2[ip][k]*n00)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n11 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n10)*-1 + ((Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n01 + (Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n00)*-1))*W2[ip]*det;
2384
// Number of operations to compute entry: 42
2385
A[j*6 + (k + 3)] += ((FE1_f2[ip][j]*n01*FE1_f1[ip][k]*n11 + FE1_f2[ip][j]*n00*FE1_f1[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n11 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n10)*-1 + ((Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n01 + (Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n00)*-1))*W2[ip]*det;
2386
// Number of operations to compute entry: 42
2387
A[j*6 + k] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n00 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n01)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n01 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n00)*-1) + (FE1_f2[ip][j]*n00*FE1_f2[ip][k]*n00 + FE1_f2[ip][j]*n01*FE1_f2[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2388
// Number of operations to compute entry: 42
2389
A[(j + 3)*6 + (k + 3)] += ((FE1_f1[ip][j]*n10*FE1_f1[ip][k]*n10 + FE1_f1[ip][j]*n11*FE1_f1[ip][k]*n11)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f1[ip][k]*n11)*-1 + ((Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n10 + (Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f1[ip][j]*n11)*-1))*W2[ip]*det;
2390
}// end loop over 'k'
2391
}// end loop over 'j'
2392
}// end loop over 'ip'
2397
// Total number of operations to compute element tensor (from this point): 3024
2399
// Loop quadrature points for integral
2400
// Number of operations to compute element tensor for following IP loop = 3024
2401
for (unsigned int ip = 0; ip < 2; ip++)
2404
// Number of operations for primary indices: 1512
2405
for (unsigned int j = 0; j < 3; j++)
2407
for (unsigned int k = 0; k < 3; k++)
2409
// Number of operations to compute entry: 42
2410
A[(j + 3)*6 + k] += ((((Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n01 + (Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n00)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n11 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n10)*-1) + (FE1_f2[ip][j]*n10*FE1_f2[ip][k]*n00 + FE1_f2[ip][j]*n11*FE1_f2[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2411
// Number of operations to compute entry: 42
2412
A[j*6 + (k + 3)] += ((FE1_f2[ip][j]*n01*FE1_f2[ip][k]*n11 + FE1_f2[ip][j]*n00*FE1_f2[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n11 + (Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n10)*-1 + ((Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n01 + (Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n00)*-1))*W2[ip]*det;
2413
// Number of operations to compute entry: 42
2414
A[j*6 + k] += ((((Jinv0_00*FE1_f0_D10[ip][j] + Jinv0_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n00 + (Jinv0_01*FE1_f0_D10[ip][j] + Jinv0_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n01)*-1 + ((Jinv0_01*FE1_f0_D10[ip][k] + Jinv0_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n01 + (Jinv0_00*FE1_f0_D10[ip][k] + Jinv0_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n00)*-1) + (FE1_f2[ip][j]*n00*FE1_f2[ip][k]*n00 + FE1_f2[ip][j]*n01*FE1_f2[ip][k]*n01)*4/((w[0][0] + w[0][1])/(2)))*W2[ip]*det;
2415
// Number of operations to compute entry: 42
2416
A[(j + 3)*6 + (k + 3)] += ((FE1_f2[ip][j]*n11*FE1_f2[ip][k]*n11 + FE1_f2[ip][j]*n10*FE1_f2[ip][k]*n10)*4/((w[0][0] + w[0][1])/(2)) + (((Jinv1_00*FE1_f0_D10[ip][j] + Jinv1_10*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n10 + (Jinv1_01*FE1_f0_D10[ip][j] + Jinv1_11*FE1_f0_D01[ip][j])*0.5*FE1_f2[ip][k]*n11)*-1 + ((Jinv1_01*FE1_f0_D10[ip][k] + Jinv1_11*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n11 + (Jinv1_00*FE1_f0_D10[ip][k] + Jinv1_10*FE1_f0_D01[ip][k])*0.5*FE1_f2[ip][j]*n10)*-1))*W2[ip]*det;
2417
}// end loop over 'k'
2418
}// end loop over 'j'
2419
}// end loop over 'ip'
2429
/// This class defines the interface for the tabulation of the
2430
/// interior facet tensor corresponding to the local contribution to
2431
/// a form from the integral over an interior facet.
2433
class poissondg_0_interior_facet_integral_0: public ufc::interior_facet_integral
2437
poissondg_0_interior_facet_integral_0_quadrature integral_0_quadrature;
2442
poissondg_0_interior_facet_integral_0() : ufc::interior_facet_integral()
2448
virtual ~poissondg_0_interior_facet_integral_0()
2453
/// Tabulate the tensor for the contribution from a local interior facet
2454
virtual void tabulate_tensor(double* A,
2455
const double * const * w,
2456
const ufc::cell& c0,
2457
const ufc::cell& c1,
2458
unsigned int facet0,
2459
unsigned int facet1) const
2461
// Reset values of the element tensor block
2462
for (unsigned int j = 0; j < 36; j++)
2465
// Add all contributions to element tensor
2466
integral_0_quadrature.tabulate_tensor(A, w, c0, c1, facet0, facet1);
2471
/// This class defines the interface for the assembly of the global
2472
/// tensor corresponding to a form with r + n arguments, that is, a
2475
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2477
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2478
/// global tensor A is defined by
2480
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2482
/// where each argument Vj represents the application to the
2483
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2484
/// fixed functions (coefficients).
2486
class poissondg_form_0: public ufc::form
2491
poissondg_form_0() : ufc::form()
2497
virtual ~poissondg_form_0()
2502
/// Return a string identifying the form
2503
virtual const char* signature() const
2505
return "Form([Integral(IndexSum(Product(Indexed(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2})), Measure('cell', 0, None)), Integral(Sum(Product(Division(FloatValue(4.0, (), (), {}), Division(Sum(NegativeRestricted(Constant(Cell('triangle', 1, Space(2)), 0)), PositiveRestricted(Constant(Cell('triangle', 1, Space(2)), 0))), FloatValue(2.0, (), (), {}))), IndexSum(Product(Indexed(Sum(ComponentTensor(Product(Indexed(NegativeRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(3),), {Index(3): 2})), NegativeRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0))), MultiIndex((Index(3),), {Index(3): 2})), ComponentTensor(Product(Indexed(PositiveRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(4),), {Index(4): 2})), PositiveRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0))), MultiIndex((Index(4),), {Index(4): 2}))), MultiIndex((Index(5),), {Index(5): 2})), Indexed(Sum(ComponentTensor(Product(Indexed(NegativeRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(6),), {Index(6): 2})), NegativeRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1))), MultiIndex((Index(6),), {Index(6): 2})), ComponentTensor(Product(Indexed(PositiveRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(7),), {Index(7): 2})), PositiveRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1))), MultiIndex((Index(7),), {Index(7): 2}))), MultiIndex((Index(5),), {Index(5): 2}))), MultiIndex((Index(5),), {Index(5): 2}))), Sum(Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(Product(FloatValue(0.5, (), (), {}), Indexed(Sum(NegativeRestricted(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(8),), {Index(8): 2})), MultiIndex((Index(8),), {Index(8): 2}))), PositiveRestricted(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(9),), {Index(9): 2})), MultiIndex((Index(9),), {Index(9): 2})))), MultiIndex((Index(10),), {Index(10): 2}))), MultiIndex((Index(10),), {Index(10): 2})), MultiIndex((Index(11),), {Index(11): 2})), Indexed(Sum(ComponentTensor(Product(Indexed(NegativeRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(12),), {Index(12): 2})), NegativeRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1))), MultiIndex((Index(12),), {Index(12): 2})), ComponentTensor(Product(Indexed(PositiveRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(13),), {Index(13): 2})), PositiveRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1))), MultiIndex((Index(13),), {Index(13): 2}))), MultiIndex((Index(11),), {Index(11): 2}))), MultiIndex((Index(11),), {Index(11): 2}))), Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(Product(FloatValue(0.5, (), (), {}), Indexed(Sum(NegativeRestricted(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1), MultiIndex((Index(14),), {Index(14): 2})), MultiIndex((Index(14),), {Index(14): 2}))), PositiveRestricted(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1), MultiIndex((Index(15),), {Index(15): 2})), MultiIndex((Index(15),), {Index(15): 2})))), MultiIndex((Index(16),), {Index(16): 2}))), MultiIndex((Index(16),), {Index(16): 2})), MultiIndex((Index(17),), {Index(17): 2})), Indexed(Sum(ComponentTensor(Product(Indexed(NegativeRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(18),), {Index(18): 2})), NegativeRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0))), MultiIndex((Index(18),), {Index(18): 2})), ComponentTensor(Product(Indexed(PositiveRestricted(FacetNormal(Cell('triangle', 1, Space(2)))), MultiIndex((Index(19),), {Index(19): 2})), PositiveRestricted(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0))), MultiIndex((Index(19),), {Index(19): 2}))), MultiIndex((Index(17),), {Index(17): 2}))), MultiIndex((Index(17),), {Index(17): 2}))))), Measure('interior_facet', 0, None)), Integral(Sum(Product(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1), Product(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), Division(FloatValue(8.0, (), (), {}), Constant(Cell('triangle', 1, Space(2)), 0)))), Sum(Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(Product(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((Index(20),), {Index(20): 2}))), MultiIndex((Index(20),), {Index(20): 2})), MultiIndex((Index(21),), {Index(21): 2})), Indexed(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1), MultiIndex((Index(22),), {Index(22): 2})), MultiIndex((Index(22),), {Index(22): 2})), MultiIndex((Index(21),), {Index(21): 2}))), MultiIndex((Index(21),), {Index(21): 2}))), Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(Product(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1), Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((Index(23),), {Index(23): 2}))), MultiIndex((Index(23),), {Index(23): 2})), MultiIndex((Index(24),), {Index(24): 2})), Indexed(ComponentTensor(SpatialDerivative(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(25),), {Index(25): 2})), MultiIndex((Index(25),), {Index(25): 2})), MultiIndex((Index(24),), {Index(24): 2}))), MultiIndex((Index(24),), {Index(24): 2}))))), Measure('exterior_facet', 0, None))])";
2508
/// Return the rank of the global tensor (r)
2509
virtual unsigned int rank() const
2514
/// Return the number of coefficients (n)
2515
virtual unsigned int num_coefficients() const
2520
/// Return the number of cell integrals
2521
virtual unsigned int num_cell_integrals() const
2526
/// Return the number of exterior facet integrals
2527
virtual unsigned int num_exterior_facet_integrals() const
2532
/// Return the number of interior facet integrals
2533
virtual unsigned int num_interior_facet_integrals() const
2538
/// Create a new finite element for argument function i
2539
virtual ufc::finite_element* create_finite_element(unsigned int i) const
2544
return new poissondg_0_finite_element_0();
2547
return new poissondg_0_finite_element_1();
2550
return new poissondg_0_finite_element_2();
2556
/// Create a new dof map for argument function i
2557
virtual ufc::dof_map* create_dof_map(unsigned int i) const
2562
return new poissondg_0_dof_map_0();
2565
return new poissondg_0_dof_map_1();
2568
return new poissondg_0_dof_map_2();
2574
/// Create a new cell integral on sub domain i
2575
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
2577
return new poissondg_0_cell_integral_0();
2580
/// Create a new exterior facet integral on sub domain i
2581
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
2583
return new poissondg_0_exterior_facet_integral_0();
2586
/// Create a new interior facet integral on sub domain i
2587
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
2589
return new poissondg_0_interior_facet_integral_0();
2594
/// This class defines the interface for a finite element.
2596
class poissondg_1_finite_element_0: public ufc::finite_element
2601
poissondg_1_finite_element_0() : ufc::finite_element()
2607
virtual ~poissondg_1_finite_element_0()
2612
/// Return a string identifying the finite element
2613
virtual const char* signature() const
2615
return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
2618
/// Return the cell shape
2619
virtual ufc::shape cell_shape() const
2621
return ufc::triangle;
2624
/// Return the dimension of the finite element function space
2625
virtual unsigned int space_dimension() const
2630
/// Return the rank of the value space
2631
virtual unsigned int value_rank() const
2636
/// Return the dimension of the value space for axis i
2637
virtual unsigned int value_dimension(unsigned int i) const
2642
/// Evaluate basis function i at given point in cell
2643
virtual void evaluate_basis(unsigned int i,
2645
const double* coordinates,
2646
const ufc::cell& c) const
2648
// Extract vertex coordinates
2649
const double * const * element_coordinates = c.coordinates;
2651
// Compute Jacobian of affine map from reference cell
2652
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2653
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2654
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2655
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2657
// Compute determinant of Jacobian
2658
const double detJ = J_00*J_11 - J_01*J_10;
2660
// Compute inverse of Jacobian
2662
// Get coordinates and map to the reference (UFC) element
2663
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2664
element_coordinates[0][0]*element_coordinates[2][1] +\
2665
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2666
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2667
element_coordinates[1][0]*element_coordinates[0][1] -\
2668
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2670
// Map coordinates to the reference square
2671
if (std::abs(y - 1.0) < 1e-08)
2674
x = 2.0 *x/(1.0 - y) - 1.0;
2680
// Map degree of freedom to element degree of freedom
2681
const unsigned int dof = i;
2683
// Generate scalings
2684
const double scalings_y_0 = 1;
2685
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2687
// Compute psitilde_a
2688
const double psitilde_a_0 = 1;
2689
const double psitilde_a_1 = x;
2691
// Compute psitilde_bs
2692
const double psitilde_bs_0_0 = 1;
2693
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2694
const double psitilde_bs_1_0 = 1;
2696
// Compute basisvalues
2697
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2698
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2699
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2701
// Table(s) of coefficients
2702
static const double coefficients0[3][3] = \
2703
{{0.471404521, -0.288675135, -0.166666667},
2704
{0.471404521, 0.288675135, -0.166666667},
2705
{0.471404521, 0, 0.333333333}};
2707
// Extract relevant coefficients
2708
const double coeff0_0 = coefficients0[dof][0];
2709
const double coeff0_1 = coefficients0[dof][1];
2710
const double coeff0_2 = coefficients0[dof][2];
2713
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2716
/// Evaluate all basis functions at given point in cell
2717
virtual void evaluate_basis_all(double* values,
2718
const double* coordinates,
2719
const ufc::cell& c) const
2721
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2724
/// Evaluate order n derivatives of basis function i at given point in cell
2725
virtual void evaluate_basis_derivatives(unsigned int i,
2728
const double* coordinates,
2729
const ufc::cell& c) const
2731
// Extract vertex coordinates
2732
const double * const * element_coordinates = c.coordinates;
2734
// Compute Jacobian of affine map from reference cell
2735
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2736
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2737
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2738
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2740
// Compute determinant of Jacobian
2741
const double detJ = J_00*J_11 - J_01*J_10;
2743
// Compute inverse of Jacobian
2745
// Get coordinates and map to the reference (UFC) element
2746
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2747
element_coordinates[0][0]*element_coordinates[2][1] +\
2748
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2749
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2750
element_coordinates[1][0]*element_coordinates[0][1] -\
2751
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2753
// Map coordinates to the reference square
2754
if (std::abs(y - 1.0) < 1e-08)
2757
x = 2.0 *x/(1.0 - y) - 1.0;
2760
// Compute number of derivatives
2761
unsigned int num_derivatives = 1;
2763
for (unsigned int j = 0; j < n; j++)
2764
num_derivatives *= 2;
2767
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2768
unsigned int **combinations = new unsigned int *[num_derivatives];
2770
for (unsigned int j = 0; j < num_derivatives; j++)
2772
combinations[j] = new unsigned int [n];
2773
for (unsigned int k = 0; k < n; k++)
2774
combinations[j][k] = 0;
2777
// Generate combinations of derivatives
2778
for (unsigned int row = 1; row < num_derivatives; row++)
2780
for (unsigned int num = 0; num < row; num++)
2782
for (unsigned int col = n-1; col+1 > 0; col--)
2784
if (combinations[row][col] + 1 > 1)
2785
combinations[row][col] = 0;
2788
combinations[row][col] += 1;
2795
// Compute inverse of Jacobian
2796
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2798
// Declare transformation matrix
2799
// Declare pointer to two dimensional array and initialise
2800
double **transform = new double *[num_derivatives];
2802
for (unsigned int j = 0; j < num_derivatives; j++)
2804
transform[j] = new double [num_derivatives];
2805
for (unsigned int k = 0; k < num_derivatives; k++)
2806
transform[j][k] = 1;
2809
// Construct transformation matrix
2810
for (unsigned int row = 0; row < num_derivatives; row++)
2812
for (unsigned int col = 0; col < num_derivatives; col++)
2814
for (unsigned int k = 0; k < n; k++)
2815
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2820
for (unsigned int j = 0; j < 1*num_derivatives; j++)
2823
// Map degree of freedom to element degree of freedom
2824
const unsigned int dof = i;
2826
// Generate scalings
2827
const double scalings_y_0 = 1;
2828
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2830
// Compute psitilde_a
2831
const double psitilde_a_0 = 1;
2832
const double psitilde_a_1 = x;
2834
// Compute psitilde_bs
2835
const double psitilde_bs_0_0 = 1;
2836
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2837
const double psitilde_bs_1_0 = 1;
2839
// Compute basisvalues
2840
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2841
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2842
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2844
// Table(s) of coefficients
2845
static const double coefficients0[3][3] = \
2846
{{0.471404521, -0.288675135, -0.166666667},
2847
{0.471404521, 0.288675135, -0.166666667},
2848
{0.471404521, 0, 0.333333333}};
2850
// Interesting (new) part
2851
// Tables of derivatives of the polynomial base (transpose)
2852
static const double dmats0[3][3] = \
2857
static const double dmats1[3][3] = \
2860
{4.24264069, 0, 0}};
2862
// Compute reference derivatives
2863
// Declare pointer to array of derivatives on FIAT element
2864
double *derivatives = new double [num_derivatives];
2866
// Declare coefficients
2867
double coeff0_0 = 0;
2868
double coeff0_1 = 0;
2869
double coeff0_2 = 0;
2871
// Declare new coefficients
2872
double new_coeff0_0 = 0;
2873
double new_coeff0_1 = 0;
2874
double new_coeff0_2 = 0;
2876
// Loop possible derivatives
2877
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2879
// Get values from coefficients array
2880
new_coeff0_0 = coefficients0[dof][0];
2881
new_coeff0_1 = coefficients0[dof][1];
2882
new_coeff0_2 = coefficients0[dof][2];
2884
// Loop derivative order
2885
for (unsigned int j = 0; j < n; j++)
2887
// Update old coefficients
2888
coeff0_0 = new_coeff0_0;
2889
coeff0_1 = new_coeff0_1;
2890
coeff0_2 = new_coeff0_2;
2892
if(combinations[deriv_num][j] == 0)
2894
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2895
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2896
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2898
if(combinations[deriv_num][j] == 1)
2900
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2901
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2902
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2906
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2907
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2910
// Transform derivatives back to physical element
2911
for (unsigned int row = 0; row < num_derivatives; row++)
2913
for (unsigned int col = 0; col < num_derivatives; col++)
2915
values[row] += transform[row][col]*derivatives[col];
2918
// Delete pointer to array of derivatives on FIAT element
2919
delete [] derivatives;
2921
// Delete pointer to array of combinations of derivatives and transform
2922
for (unsigned int row = 0; row < num_derivatives; row++)
2924
delete [] combinations[row];
2925
delete [] transform[row];
2928
delete [] combinations;
2929
delete [] transform;
2932
/// Evaluate order n derivatives of all basis functions at given point in cell
2933
virtual void evaluate_basis_derivatives_all(unsigned int n,
2935
const double* coordinates,
2936
const ufc::cell& c) const
2938
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2941
/// Evaluate linear functional for dof i on the function f
2942
virtual double evaluate_dof(unsigned int i,
2943
const ufc::function& f,
2944
const ufc::cell& c) const
2946
// The reference points, direction and weights:
2947
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
2948
static const double W[3][1] = {{1}, {1}, {1}};
2949
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
2951
const double * const * x = c.coordinates;
2952
double result = 0.0;
2953
// Iterate over the points:
2954
// Evaluate basis functions for affine mapping
2955
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2956
const double w1 = X[i][0][0];
2957
const double w2 = X[i][0][1];
2959
// Compute affine mapping y = F(X)
2961
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2962
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2964
// Evaluate function at physical points
2966
f.evaluate(values, y, c);
2968
// Map function values using appropriate mapping
2969
// Affine map: Do nothing
2971
// Note that we do not map the weights (yet).
2973
// Take directional components
2974
for(int k = 0; k < 1; k++)
2975
result += values[k]*D[i][0][k];
2976
// Multiply by weights
2982
/// Evaluate linear functionals for all dofs on the function f
2983
virtual void evaluate_dofs(double* values,
2984
const ufc::function& f,
2985
const ufc::cell& c) const
2987
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2990
/// Interpolate vertex values from dof values
2991
virtual void interpolate_vertex_values(double* vertex_values,
2992
const double* dof_values,
2993
const ufc::cell& c) const
2995
// Evaluate at vertices and use affine mapping
2996
vertex_values[0] = dof_values[0];
2997
vertex_values[1] = dof_values[1];
2998
vertex_values[2] = dof_values[2];
3001
/// Return the number of sub elements (for a mixed element)
3002
virtual unsigned int num_sub_elements() const
3007
/// Create a new finite element for sub element i (for a mixed element)
3008
virtual ufc::finite_element* create_sub_element(unsigned int i) const
3010
return new poissondg_1_finite_element_0();
3015
/// This class defines the interface for a finite element.
3017
class poissondg_1_finite_element_1: public ufc::finite_element
3022
poissondg_1_finite_element_1() : ufc::finite_element()
3028
virtual ~poissondg_1_finite_element_1()
3033
/// Return a string identifying the finite element
3034
virtual const char* signature() const
3036
return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
3039
/// Return the cell shape
3040
virtual ufc::shape cell_shape() const
3042
return ufc::triangle;
3045
/// Return the dimension of the finite element function space
3046
virtual unsigned int space_dimension() const
3051
/// Return the rank of the value space
3052
virtual unsigned int value_rank() const
3057
/// Return the dimension of the value space for axis i
3058
virtual unsigned int value_dimension(unsigned int i) const
3063
/// Evaluate basis function i at given point in cell
3064
virtual void evaluate_basis(unsigned int i,
3066
const double* coordinates,
3067
const ufc::cell& c) const
3069
// Extract vertex coordinates
3070
const double * const * element_coordinates = c.coordinates;
3072
// Compute Jacobian of affine map from reference cell
3073
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3074
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3075
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3076
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3078
// Compute determinant of Jacobian
3079
const double detJ = J_00*J_11 - J_01*J_10;
3081
// Compute inverse of Jacobian
3083
// Get coordinates and map to the reference (UFC) element
3084
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3085
element_coordinates[0][0]*element_coordinates[2][1] +\
3086
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3087
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3088
element_coordinates[1][0]*element_coordinates[0][1] -\
3089
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3091
// Map coordinates to the reference square
3092
if (std::abs(y - 1.0) < 1e-08)
3095
x = 2.0 *x/(1.0 - y) - 1.0;
3101
// Map degree of freedom to element degree of freedom
3102
const unsigned int dof = i;
3104
// Generate scalings
3105
const double scalings_y_0 = 1;
3106
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3108
// Compute psitilde_a
3109
const double psitilde_a_0 = 1;
3110
const double psitilde_a_1 = x;
3112
// Compute psitilde_bs
3113
const double psitilde_bs_0_0 = 1;
3114
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3115
const double psitilde_bs_1_0 = 1;
3117
// Compute basisvalues
3118
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3119
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3120
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3122
// Table(s) of coefficients
3123
static const double coefficients0[3][3] = \
3124
{{0.471404521, -0.288675135, -0.166666667},
3125
{0.471404521, 0.288675135, -0.166666667},
3126
{0.471404521, 0, 0.333333333}};
3128
// Extract relevant coefficients
3129
const double coeff0_0 = coefficients0[dof][0];
3130
const double coeff0_1 = coefficients0[dof][1];
3131
const double coeff0_2 = coefficients0[dof][2];
3134
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3137
/// Evaluate all basis functions at given point in cell
3138
virtual void evaluate_basis_all(double* values,
3139
const double* coordinates,
3140
const ufc::cell& c) const
3142
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3145
/// Evaluate order n derivatives of basis function i at given point in cell
3146
virtual void evaluate_basis_derivatives(unsigned int i,
3149
const double* coordinates,
3150
const ufc::cell& c) const
3152
// Extract vertex coordinates
3153
const double * const * element_coordinates = c.coordinates;
3155
// Compute Jacobian of affine map from reference cell
3156
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3157
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3158
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3159
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3161
// Compute determinant of Jacobian
3162
const double detJ = J_00*J_11 - J_01*J_10;
3164
// Compute inverse of Jacobian
3166
// Get coordinates and map to the reference (UFC) element
3167
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3168
element_coordinates[0][0]*element_coordinates[2][1] +\
3169
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3170
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3171
element_coordinates[1][0]*element_coordinates[0][1] -\
3172
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3174
// Map coordinates to the reference square
3175
if (std::abs(y - 1.0) < 1e-08)
3178
x = 2.0 *x/(1.0 - y) - 1.0;
3181
// Compute number of derivatives
3182
unsigned int num_derivatives = 1;
3184
for (unsigned int j = 0; j < n; j++)
3185
num_derivatives *= 2;
3188
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3189
unsigned int **combinations = new unsigned int *[num_derivatives];
3191
for (unsigned int j = 0; j < num_derivatives; j++)
3193
combinations[j] = new unsigned int [n];
3194
for (unsigned int k = 0; k < n; k++)
3195
combinations[j][k] = 0;
3198
// Generate combinations of derivatives
3199
for (unsigned int row = 1; row < num_derivatives; row++)
3201
for (unsigned int num = 0; num < row; num++)
3203
for (unsigned int col = n-1; col+1 > 0; col--)
3205
if (combinations[row][col] + 1 > 1)
3206
combinations[row][col] = 0;
3209
combinations[row][col] += 1;
3216
// Compute inverse of Jacobian
3217
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3219
// Declare transformation matrix
3220
// Declare pointer to two dimensional array and initialise
3221
double **transform = new double *[num_derivatives];
3223
for (unsigned int j = 0; j < num_derivatives; j++)
3225
transform[j] = new double [num_derivatives];
3226
for (unsigned int k = 0; k < num_derivatives; k++)
3227
transform[j][k] = 1;
3230
// Construct transformation matrix
3231
for (unsigned int row = 0; row < num_derivatives; row++)
3233
for (unsigned int col = 0; col < num_derivatives; col++)
3235
for (unsigned int k = 0; k < n; k++)
3236
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3241
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3244
// Map degree of freedom to element degree of freedom
3245
const unsigned int dof = i;
3247
// Generate scalings
3248
const double scalings_y_0 = 1;
3249
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3251
// Compute psitilde_a
3252
const double psitilde_a_0 = 1;
3253
const double psitilde_a_1 = x;
3255
// Compute psitilde_bs
3256
const double psitilde_bs_0_0 = 1;
3257
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3258
const double psitilde_bs_1_0 = 1;
3260
// Compute basisvalues
3261
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3262
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3263
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3265
// Table(s) of coefficients
3266
static const double coefficients0[3][3] = \
3267
{{0.471404521, -0.288675135, -0.166666667},
3268
{0.471404521, 0.288675135, -0.166666667},
3269
{0.471404521, 0, 0.333333333}};
3271
// Interesting (new) part
3272
// Tables of derivatives of the polynomial base (transpose)
3273
static const double dmats0[3][3] = \
3278
static const double dmats1[3][3] = \
3281
{4.24264069, 0, 0}};
3283
// Compute reference derivatives
3284
// Declare pointer to array of derivatives on FIAT element
3285
double *derivatives = new double [num_derivatives];
3287
// Declare coefficients
3288
double coeff0_0 = 0;
3289
double coeff0_1 = 0;
3290
double coeff0_2 = 0;
3292
// Declare new coefficients
3293
double new_coeff0_0 = 0;
3294
double new_coeff0_1 = 0;
3295
double new_coeff0_2 = 0;
3297
// Loop possible derivatives
3298
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3300
// Get values from coefficients array
3301
new_coeff0_0 = coefficients0[dof][0];
3302
new_coeff0_1 = coefficients0[dof][1];
3303
new_coeff0_2 = coefficients0[dof][2];
3305
// Loop derivative order
3306
for (unsigned int j = 0; j < n; j++)
3308
// Update old coefficients
3309
coeff0_0 = new_coeff0_0;
3310
coeff0_1 = new_coeff0_1;
3311
coeff0_2 = new_coeff0_2;
3313
if(combinations[deriv_num][j] == 0)
3315
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3316
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3317
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3319
if(combinations[deriv_num][j] == 1)
3321
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3322
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3323
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3327
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3328
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3331
// Transform derivatives back to physical element
3332
for (unsigned int row = 0; row < num_derivatives; row++)
3334
for (unsigned int col = 0; col < num_derivatives; col++)
3336
values[row] += transform[row][col]*derivatives[col];
3339
// Delete pointer to array of derivatives on FIAT element
3340
delete [] derivatives;
3342
// Delete pointer to array of combinations of derivatives and transform
3343
for (unsigned int row = 0; row < num_derivatives; row++)
3345
delete [] combinations[row];
3346
delete [] transform[row];
3349
delete [] combinations;
3350
delete [] transform;
3353
/// Evaluate order n derivatives of all basis functions at given point in cell
3354
virtual void evaluate_basis_derivatives_all(unsigned int n,
3356
const double* coordinates,
3357
const ufc::cell& c) const
3359
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3362
/// Evaluate linear functional for dof i on the function f
3363
virtual double evaluate_dof(unsigned int i,
3364
const ufc::function& f,
3365
const ufc::cell& c) const
3367
// The reference points, direction and weights:
3368
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3369
static const double W[3][1] = {{1}, {1}, {1}};
3370
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3372
const double * const * x = c.coordinates;
3373
double result = 0.0;
3374
// Iterate over the points:
3375
// Evaluate basis functions for affine mapping
3376
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3377
const double w1 = X[i][0][0];
3378
const double w2 = X[i][0][1];
3380
// Compute affine mapping y = F(X)
3382
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3383
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3385
// Evaluate function at physical points
3387
f.evaluate(values, y, c);
3389
// Map function values using appropriate mapping
3390
// Affine map: Do nothing
3392
// Note that we do not map the weights (yet).
3394
// Take directional components
3395
for(int k = 0; k < 1; k++)
3396
result += values[k]*D[i][0][k];
3397
// Multiply by weights
3403
/// Evaluate linear functionals for all dofs on the function f
3404
virtual void evaluate_dofs(double* values,
3405
const ufc::function& f,
3406
const ufc::cell& c) const
3408
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3411
/// Interpolate vertex values from dof values
3412
virtual void interpolate_vertex_values(double* vertex_values,
3413
const double* dof_values,
3414
const ufc::cell& c) const
3416
// Evaluate at vertices and use affine mapping
3417
vertex_values[0] = dof_values[0];
3418
vertex_values[1] = dof_values[1];
3419
vertex_values[2] = dof_values[2];
3422
/// Return the number of sub elements (for a mixed element)
3423
virtual unsigned int num_sub_elements() const
3428
/// Create a new finite element for sub element i (for a mixed element)
3429
virtual ufc::finite_element* create_sub_element(unsigned int i) const
3431
return new poissondg_1_finite_element_1();
3436
/// This class defines the interface for a finite element.
3438
class poissondg_1_finite_element_2: public ufc::finite_element
3443
poissondg_1_finite_element_2() : ufc::finite_element()
3449
virtual ~poissondg_1_finite_element_2()
3454
/// Return a string identifying the finite element
3455
virtual const char* signature() const
3457
return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
3460
/// Return the cell shape
3461
virtual ufc::shape cell_shape() const
3463
return ufc::triangle;
3466
/// Return the dimension of the finite element function space
3467
virtual unsigned int space_dimension() const
3472
/// Return the rank of the value space
3473
virtual unsigned int value_rank() const
3478
/// Return the dimension of the value space for axis i
3479
virtual unsigned int value_dimension(unsigned int i) const
3484
/// Evaluate basis function i at given point in cell
3485
virtual void evaluate_basis(unsigned int i,
3487
const double* coordinates,
3488
const ufc::cell& c) const
3490
// Extract vertex coordinates
3491
const double * const * element_coordinates = c.coordinates;
3493
// Compute Jacobian of affine map from reference cell
3494
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3495
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3496
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3497
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3499
// Compute determinant of Jacobian
3500
const double detJ = J_00*J_11 - J_01*J_10;
3502
// Compute inverse of Jacobian
3504
// Get coordinates and map to the reference (UFC) element
3505
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3506
element_coordinates[0][0]*element_coordinates[2][1] +\
3507
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3508
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3509
element_coordinates[1][0]*element_coordinates[0][1] -\
3510
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3512
// Map coordinates to the reference square
3513
if (std::abs(y - 1.0) < 1e-08)
3516
x = 2.0 *x/(1.0 - y) - 1.0;
3522
// Map degree of freedom to element degree of freedom
3523
const unsigned int dof = i;
3525
// Generate scalings
3526
const double scalings_y_0 = 1;
3527
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3529
// Compute psitilde_a
3530
const double psitilde_a_0 = 1;
3531
const double psitilde_a_1 = x;
3533
// Compute psitilde_bs
3534
const double psitilde_bs_0_0 = 1;
3535
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3536
const double psitilde_bs_1_0 = 1;
3538
// Compute basisvalues
3539
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3540
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3541
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3543
// Table(s) of coefficients
3544
static const double coefficients0[3][3] = \
3545
{{0.471404521, -0.288675135, -0.166666667},
3546
{0.471404521, 0.288675135, -0.166666667},
3547
{0.471404521, 0, 0.333333333}};
3549
// Extract relevant coefficients
3550
const double coeff0_0 = coefficients0[dof][0];
3551
const double coeff0_1 = coefficients0[dof][1];
3552
const double coeff0_2 = coefficients0[dof][2];
3555
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3558
/// Evaluate all basis functions at given point in cell
3559
virtual void evaluate_basis_all(double* values,
3560
const double* coordinates,
3561
const ufc::cell& c) const
3563
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3566
/// Evaluate order n derivatives of basis function i at given point in cell
3567
virtual void evaluate_basis_derivatives(unsigned int i,
3570
const double* coordinates,
3571
const ufc::cell& c) const
3573
// Extract vertex coordinates
3574
const double * const * element_coordinates = c.coordinates;
3576
// Compute Jacobian of affine map from reference cell
3577
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3578
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3579
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3580
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3582
// Compute determinant of Jacobian
3583
const double detJ = J_00*J_11 - J_01*J_10;
3585
// Compute inverse of Jacobian
3587
// Get coordinates and map to the reference (UFC) element
3588
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3589
element_coordinates[0][0]*element_coordinates[2][1] +\
3590
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3591
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3592
element_coordinates[1][0]*element_coordinates[0][1] -\
3593
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3595
// Map coordinates to the reference square
3596
if (std::abs(y - 1.0) < 1e-08)
3599
x = 2.0 *x/(1.0 - y) - 1.0;
3602
// Compute number of derivatives
3603
unsigned int num_derivatives = 1;
3605
for (unsigned int j = 0; j < n; j++)
3606
num_derivatives *= 2;
3609
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3610
unsigned int **combinations = new unsigned int *[num_derivatives];
3612
for (unsigned int j = 0; j < num_derivatives; j++)
3614
combinations[j] = new unsigned int [n];
3615
for (unsigned int k = 0; k < n; k++)
3616
combinations[j][k] = 0;
3619
// Generate combinations of derivatives
3620
for (unsigned int row = 1; row < num_derivatives; row++)
3622
for (unsigned int num = 0; num < row; num++)
3624
for (unsigned int col = n-1; col+1 > 0; col--)
3626
if (combinations[row][col] + 1 > 1)
3627
combinations[row][col] = 0;
3630
combinations[row][col] += 1;
3637
// Compute inverse of Jacobian
3638
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3640
// Declare transformation matrix
3641
// Declare pointer to two dimensional array and initialise
3642
double **transform = new double *[num_derivatives];
3644
for (unsigned int j = 0; j < num_derivatives; j++)
3646
transform[j] = new double [num_derivatives];
3647
for (unsigned int k = 0; k < num_derivatives; k++)
3648
transform[j][k] = 1;
3651
// Construct transformation matrix
3652
for (unsigned int row = 0; row < num_derivatives; row++)
3654
for (unsigned int col = 0; col < num_derivatives; col++)
3656
for (unsigned int k = 0; k < n; k++)
3657
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3662
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3665
// Map degree of freedom to element degree of freedom
3666
const unsigned int dof = i;
3668
// Generate scalings
3669
const double scalings_y_0 = 1;
3670
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3672
// Compute psitilde_a
3673
const double psitilde_a_0 = 1;
3674
const double psitilde_a_1 = x;
3676
// Compute psitilde_bs
3677
const double psitilde_bs_0_0 = 1;
3678
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3679
const double psitilde_bs_1_0 = 1;
3681
// Compute basisvalues
3682
const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3683
const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3684
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3686
// Table(s) of coefficients
3687
static const double coefficients0[3][3] = \
3688
{{0.471404521, -0.288675135, -0.166666667},
3689
{0.471404521, 0.288675135, -0.166666667},
3690
{0.471404521, 0, 0.333333333}};
3692
// Interesting (new) part
3693
// Tables of derivatives of the polynomial base (transpose)
3694
static const double dmats0[3][3] = \
3699
static const double dmats1[3][3] = \
3702
{4.24264069, 0, 0}};
3704
// Compute reference derivatives
3705
// Declare pointer to array of derivatives on FIAT element
3706
double *derivatives = new double [num_derivatives];
3708
// Declare coefficients
3709
double coeff0_0 = 0;
3710
double coeff0_1 = 0;
3711
double coeff0_2 = 0;
3713
// Declare new coefficients
3714
double new_coeff0_0 = 0;
3715
double new_coeff0_1 = 0;
3716
double new_coeff0_2 = 0;
3718
// Loop possible derivatives
3719
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3721
// Get values from coefficients array
3722
new_coeff0_0 = coefficients0[dof][0];
3723
new_coeff0_1 = coefficients0[dof][1];
3724
new_coeff0_2 = coefficients0[dof][2];
3726
// Loop derivative order
3727
for (unsigned int j = 0; j < n; j++)
3729
// Update old coefficients
3730
coeff0_0 = new_coeff0_0;
3731
coeff0_1 = new_coeff0_1;
3732
coeff0_2 = new_coeff0_2;
3734
if(combinations[deriv_num][j] == 0)
3736
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3737
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3738
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3740
if(combinations[deriv_num][j] == 1)
3742
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3743
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3744
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3748
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3749
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3752
// Transform derivatives back to physical element
3753
for (unsigned int row = 0; row < num_derivatives; row++)
3755
for (unsigned int col = 0; col < num_derivatives; col++)
3757
values[row] += transform[row][col]*derivatives[col];
3760
// Delete pointer to array of derivatives on FIAT element
3761
delete [] derivatives;
3763
// Delete pointer to array of combinations of derivatives and transform
3764
for (unsigned int row = 0; row < num_derivatives; row++)
3766
delete [] combinations[row];
3767
delete [] transform[row];
3770
delete [] combinations;
3771
delete [] transform;
3774
/// Evaluate order n derivatives of all basis functions at given point in cell
3775
virtual void evaluate_basis_derivatives_all(unsigned int n,
3777
const double* coordinates,
3778
const ufc::cell& c) const
3780
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3783
/// Evaluate linear functional for dof i on the function f
3784
virtual double evaluate_dof(unsigned int i,
3785
const ufc::function& f,
3786
const ufc::cell& c) const
3788
// The reference points, direction and weights:
3789
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3790
static const double W[3][1] = {{1}, {1}, {1}};
3791
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3793
const double * const * x = c.coordinates;
3794
double result = 0.0;
3795
// Iterate over the points:
3796
// Evaluate basis functions for affine mapping
3797
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3798
const double w1 = X[i][0][0];
3799
const double w2 = X[i][0][1];
3801
// Compute affine mapping y = F(X)
3803
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3804
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3806
// Evaluate function at physical points
3808
f.evaluate(values, y, c);
3810
// Map function values using appropriate mapping
3811
// Affine map: Do nothing
3813
// Note that we do not map the weights (yet).
3815
// Take directional components
3816
for(int k = 0; k < 1; k++)
3817
result += values[k]*D[i][0][k];
3818
// Multiply by weights
3824
/// Evaluate linear functionals for all dofs on the function f
3825
virtual void evaluate_dofs(double* values,
3826
const ufc::function& f,
3827
const ufc::cell& c) const
3829
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3832
/// Interpolate vertex values from dof values
3833
virtual void interpolate_vertex_values(double* vertex_values,
3834
const double* dof_values,
3835
const ufc::cell& c) const
3837
// Evaluate at vertices and use affine mapping
3838
vertex_values[0] = dof_values[0];
3839
vertex_values[1] = dof_values[1];
3840
vertex_values[2] = dof_values[2];
3843
/// Return the number of sub elements (for a mixed element)
3844
virtual unsigned int num_sub_elements() const
3849
/// Create a new finite element for sub element i (for a mixed element)
3850
virtual ufc::finite_element* create_sub_element(unsigned int i) const
3852
return new poissondg_1_finite_element_2();
3857
/// This class defines the interface for a local-to-global mapping of
3858
/// degrees of freedom (dofs).
3860
class poissondg_1_dof_map_0: public ufc::dof_map
3864
unsigned int __global_dimension;
3869
poissondg_1_dof_map_0() : ufc::dof_map()
3871
__global_dimension = 0;
3875
virtual ~poissondg_1_dof_map_0()
3880
/// Return a string identifying the dof map
3881
virtual const char* signature() const
3883
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
3886
/// Return true iff mesh entities of topological dimension d are needed
3887
virtual bool needs_mesh_entities(unsigned int d) const
3904
/// Initialize dof map for mesh (return true iff init_cell() is needed)
3905
virtual bool init_mesh(const ufc::mesh& m)
3907
__global_dimension = 3*m.num_entities[2];
3911
/// Initialize dof map for given cell
3912
virtual void init_cell(const ufc::mesh& m,
3918
/// Finish initialization of dof map for cells
3919
virtual void init_cell_finalize()
3924
/// Return the dimension of the global finite element function space
3925
virtual unsigned int global_dimension() const
3927
return __global_dimension;
3930
/// Return the dimension of the local finite element function space for a cell
3931
virtual unsigned int local_dimension(const ufc::cell& c) const
3936
/// Return the maximum dimension of the local finite element function space
3937
virtual unsigned int max_local_dimension() const
3942
// Return the geometric dimension of the coordinates this dof map provides
3943
virtual unsigned int geometric_dimension() const
3948
/// Return the number of dofs on each cell facet
3949
virtual unsigned int num_facet_dofs() const
3954
/// Return the number of dofs associated with each cell entity of dimension d
3955
virtual unsigned int num_entity_dofs(unsigned int d) const
3957
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3960
/// Tabulate the local-to-global mapping of dofs on a cell
3961
virtual void tabulate_dofs(unsigned int* dofs,
3963
const ufc::cell& c) const
3965
dofs[0] = 3*c.entity_indices[2][0];
3966
dofs[1] = 3*c.entity_indices[2][0] + 1;
3967
dofs[2] = 3*c.entity_indices[2][0] + 2;
3970
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
3971
virtual void tabulate_facet_dofs(unsigned int* dofs,
3972
unsigned int facet) const
3988
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
3989
virtual void tabulate_entity_dofs(unsigned int* dofs,
3990
unsigned int d, unsigned int i) const
3992
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3995
/// Tabulate the coordinates of all dofs on a cell
3996
virtual void tabulate_coordinates(double** coordinates,
3997
const ufc::cell& c) const
3999
const double * const * x = c.coordinates;
4000
coordinates[0][0] = x[0][0];
4001
coordinates[0][1] = x[0][1];
4002
coordinates[1][0] = x[1][0];
4003
coordinates[1][1] = x[1][1];
4004
coordinates[2][0] = x[2][0];
4005
coordinates[2][1] = x[2][1];
4008
/// Return the number of sub dof maps (for a mixed element)
4009
virtual unsigned int num_sub_dof_maps() const
4014
/// Create a new dof_map for sub dof map i (for a mixed element)
4015
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
4017
return new poissondg_1_dof_map_0();
4022
/// This class defines the interface for a local-to-global mapping of
4023
/// degrees of freedom (dofs).
4025
class poissondg_1_dof_map_1: public ufc::dof_map
4029
unsigned int __global_dimension;
4034
poissondg_1_dof_map_1() : ufc::dof_map()
4036
__global_dimension = 0;
4040
virtual ~poissondg_1_dof_map_1()
4045
/// Return a string identifying the dof map
4046
virtual const char* signature() const
4048
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
4051
/// Return true iff mesh entities of topological dimension d are needed
4052
virtual bool needs_mesh_entities(unsigned int d) const
4069
/// Initialize dof map for mesh (return true iff init_cell() is needed)
4070
virtual bool init_mesh(const ufc::mesh& m)
4072
__global_dimension = 3*m.num_entities[2];
4076
/// Initialize dof map for given cell
4077
virtual void init_cell(const ufc::mesh& m,
4083
/// Finish initialization of dof map for cells
4084
virtual void init_cell_finalize()
4089
/// Return the dimension of the global finite element function space
4090
virtual unsigned int global_dimension() const
4092
return __global_dimension;
4095
/// Return the dimension of the local finite element function space for a cell
4096
virtual unsigned int local_dimension(const ufc::cell& c) const
4101
/// Return the maximum dimension of the local finite element function space
4102
virtual unsigned int max_local_dimension() const
4107
// Return the geometric dimension of the coordinates this dof map provides
4108
virtual unsigned int geometric_dimension() const
4113
/// Return the number of dofs on each cell facet
4114
virtual unsigned int num_facet_dofs() const
4119
/// Return the number of dofs associated with each cell entity of dimension d
4120
virtual unsigned int num_entity_dofs(unsigned int d) const
4122
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4125
/// Tabulate the local-to-global mapping of dofs on a cell
4126
virtual void tabulate_dofs(unsigned int* dofs,
4128
const ufc::cell& c) const
4130
dofs[0] = 3*c.entity_indices[2][0];
4131
dofs[1] = 3*c.entity_indices[2][0] + 1;
4132
dofs[2] = 3*c.entity_indices[2][0] + 2;
4135
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
4136
virtual void tabulate_facet_dofs(unsigned int* dofs,
4137
unsigned int facet) const
4153
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
4154
virtual void tabulate_entity_dofs(unsigned int* dofs,
4155
unsigned int d, unsigned int i) const
4157
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4160
/// Tabulate the coordinates of all dofs on a cell
4161
virtual void tabulate_coordinates(double** coordinates,
4162
const ufc::cell& c) const
4164
const double * const * x = c.coordinates;
4165
coordinates[0][0] = x[0][0];
4166
coordinates[0][1] = x[0][1];
4167
coordinates[1][0] = x[1][0];
4168
coordinates[1][1] = x[1][1];
4169
coordinates[2][0] = x[2][0];
4170
coordinates[2][1] = x[2][1];
4173
/// Return the number of sub dof maps (for a mixed element)
4174
virtual unsigned int num_sub_dof_maps() const
4179
/// Create a new dof_map for sub dof map i (for a mixed element)
4180
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
4182
return new poissondg_1_dof_map_1();
4187
/// This class defines the interface for a local-to-global mapping of
4188
/// degrees of freedom (dofs).
4190
class poissondg_1_dof_map_2: public ufc::dof_map
4194
unsigned int __global_dimension;
4199
poissondg_1_dof_map_2() : ufc::dof_map()
4201
__global_dimension = 0;
4205
virtual ~poissondg_1_dof_map_2()
4210
/// Return a string identifying the dof map
4211
virtual const char* signature() const
4213
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1)";
4216
/// Return true iff mesh entities of topological dimension d are needed
4217
virtual bool needs_mesh_entities(unsigned int d) const
4234
/// Initialize dof map for mesh (return true iff init_cell() is needed)
4235
virtual bool init_mesh(const ufc::mesh& m)
4237
__global_dimension = 3*m.num_entities[2];
4241
/// Initialize dof map for given cell
4242
virtual void init_cell(const ufc::mesh& m,
4248
/// Finish initialization of dof map for cells
4249
virtual void init_cell_finalize()
4254
/// Return the dimension of the global finite element function space
4255
virtual unsigned int global_dimension() const
4257
return __global_dimension;
4260
/// Return the dimension of the local finite element function space for a cell
4261
virtual unsigned int local_dimension(const ufc::cell& c) const
4266
/// Return the maximum dimension of the local finite element function space
4267
virtual unsigned int max_local_dimension() const
4272
// Return the geometric dimension of the coordinates this dof map provides
4273
virtual unsigned int geometric_dimension() const
4278
/// Return the number of dofs on each cell facet
4279
virtual unsigned int num_facet_dofs() const
4284
/// Return the number of dofs associated with each cell entity of dimension d
4285
virtual unsigned int num_entity_dofs(unsigned int d) const
4287
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4290
/// Tabulate the local-to-global mapping of dofs on a cell
4291
virtual void tabulate_dofs(unsigned int* dofs,
4293
const ufc::cell& c) const
4295
dofs[0] = 3*c.entity_indices[2][0];
4296
dofs[1] = 3*c.entity_indices[2][0] + 1;
4297
dofs[2] = 3*c.entity_indices[2][0] + 2;
4300
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
4301
virtual void tabulate_facet_dofs(unsigned int* dofs,
4302
unsigned int facet) const
4318
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
4319
virtual void tabulate_entity_dofs(unsigned int* dofs,
4320
unsigned int d, unsigned int i) const
4322
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4325
/// Tabulate the coordinates of all dofs on a cell
4326
virtual void tabulate_coordinates(double** coordinates,
4327
const ufc::cell& c) const
4329
const double * const * x = c.coordinates;
4330
coordinates[0][0] = x[0][0];
4331
coordinates[0][1] = x[0][1];
4332
coordinates[1][0] = x[1][0];
4333
coordinates[1][1] = x[1][1];
4334
coordinates[2][0] = x[2][0];
4335
coordinates[2][1] = x[2][1];
4338
/// Return the number of sub dof maps (for a mixed element)
4339
virtual unsigned int num_sub_dof_maps() const
4344
/// Create a new dof_map for sub dof map i (for a mixed element)
4345
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
4347
return new poissondg_1_dof_map_2();
4352
/// This class defines the interface for the tabulation of the cell
4353
/// tensor corresponding to the local contribution to a form from
4354
/// the integral over a cell.
4356
class poissondg_1_cell_integral_0_quadrature: public ufc::cell_integral
4361
poissondg_1_cell_integral_0_quadrature() : ufc::cell_integral()
4367
virtual ~poissondg_1_cell_integral_0_quadrature()
4372
/// Tabulate the tensor for the contribution from a local cell
4373
virtual void tabulate_tensor(double* A,
4374
const double * const * w,
4375
const ufc::cell& c) const
4377
// Extract vertex coordinates
4378
const double * const * x = c.coordinates;
4380
// Compute Jacobian of affine map from reference cell
4381
const double J_00 = x[1][0] - x[0][0];
4382
const double J_01 = x[2][0] - x[0][0];
4383
const double J_10 = x[1][1] - x[0][1];
4384
const double J_11 = x[2][1] - x[0][1];
4386
// Compute determinant of Jacobian
4387
double detJ = J_00*J_11 - J_01*J_10;
4389
// Compute inverse of Jacobian
4392
const double det = std::abs(detJ);
4395
// Array of quadrature weights
4396
static const double W4[4] = {0.159020691, 0.0909793091, 0.159020691, 0.0909793091};
4397
// Quadrature points on the UFC reference element: (0.178558728, 0.155051026), (0.0750311102, 0.644948974), (0.666390246, 0.155051026), (0.280019915, 0.644948974)
4399
// Value of basis functions at quadrature points.
4400
static const double FE0[4][3] = \
4401
{{0.666390246, 0.178558728, 0.155051026},
4402
{0.280019915, 0.0750311102, 0.644948974},
4403
{0.178558728, 0.666390246, 0.155051026},
4404
{0.0750311102, 0.280019915, 0.644948974}};
4407
// Compute element tensor using UFL quadrature representation
4408
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
4409
// Total number of operations to compute element tensor: 72
4411
// Loop quadrature points for integral
4412
// Number of operations to compute element tensor for following IP loop = 72
4413
for (unsigned int ip = 0; ip < 4; ip++)
4416
// Function declarations
4419
// Total number of operations to compute function values = 6
4420
for (unsigned int r = 0; r < 3; r++)
4422
F0 += FE0[ip][r]*w[0][r];
4423
}// end loop over 'r'
4425
// Number of operations for primary indices: 12
4426
for (unsigned int j = 0; j < 3; j++)
4428
// Number of operations to compute entry: 4
4429
A[j] += FE0[ip][j]*F0*W4[ip]*det;
4430
}// end loop over 'j'
4431
}// end loop over 'ip'
4436
/// This class defines the interface for the tabulation of the cell
4437
/// tensor corresponding to the local contribution to a form from
4438
/// the integral over a cell.
4440
class poissondg_1_cell_integral_0: public ufc::cell_integral
4444
poissondg_1_cell_integral_0_quadrature integral_0_quadrature;
4449
poissondg_1_cell_integral_0() : ufc::cell_integral()
4455
virtual ~poissondg_1_cell_integral_0()
4460
/// Tabulate the tensor for the contribution from a local cell
4461
virtual void tabulate_tensor(double* A,
4462
const double * const * w,
4463
const ufc::cell& c) const
4465
// Reset values of the element tensor block
4466
for (unsigned int j = 0; j < 3; j++)
4469
// Add all contributions to element tensor
4470
integral_0_quadrature.tabulate_tensor(A, w, c);
4475
/// This class defines the interface for the tabulation of the
4476
/// exterior facet tensor corresponding to the local contribution to
4477
/// a form from the integral over an exterior facet.
4479
class poissondg_1_exterior_facet_integral_0_quadrature: public ufc::exterior_facet_integral
4484
poissondg_1_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
4490
virtual ~poissondg_1_exterior_facet_integral_0_quadrature()
4495
/// Tabulate the tensor for the contribution from a local exterior facet
4496
virtual void tabulate_tensor(double* A,
4497
const double * const * w,
4499
unsigned int facet) const
4501
// Extract vertex coordinates
4502
const double * const * x = c.coordinates;
4504
// Compute Jacobian of affine map from reference cell
4506
// Compute determinant of Jacobian
4508
// Compute inverse of Jacobian
4510
// Vertices on edges
4511
static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
4514
const unsigned int v0 = edge_vertices[facet][0];
4515
const unsigned int v1 = edge_vertices[facet][1];
4517
// Compute scale factor (length of edge scaled by length of reference interval)
4518
const double dx0 = x[v1][0] - x[v0][0];
4519
const double dx1 = x[v1][1] - x[v0][1];
4520
const double det = std::sqrt(dx0*dx0 + dx1*dx1);
4523
// Compute facet normals from the facet scale factor constants
4526
// Array of quadrature weights
4527
static const double W2[2] = {0.5, 0.5};
4528
// Quadrature points on the UFC reference element: (0.211324865), (0.788675135)
4530
// Value of basis functions at quadrature points.
4531
static const double FE0_f0[2][3] = \
4532
{{0, 0.788675135, 0.211324865},
4533
{0, 0.211324865, 0.788675135}};
4535
static const double FE0_f1[2][3] = \
4536
{{0.788675135, 0, 0.211324865},
4537
{0.211324865, 0, 0.788675135}};
4539
static const double FE0_f2[2][3] = \
4540
{{0.788675135, 0.211324865, 0},
4541
{0.211324865, 0.788675135, 0}};
4544
// Compute element tensor using UFL quadrature representation
4545
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
4550
// Total number of operations to compute element tensor (from this point): 36
4552
// Loop quadrature points for integral
4553
// Number of operations to compute element tensor for following IP loop = 36
4554
for (unsigned int ip = 0; ip < 2; ip++)
4557
// Function declarations
4560
// Total number of operations to compute function values = 6
4561
for (unsigned int r = 0; r < 3; r++)
4563
F0 += FE0_f0[ip][r]*w[1][r];
4564
}// end loop over 'r'
4566
// Number of operations for primary indices: 12
4567
for (unsigned int j = 0; j < 3; j++)
4569
// Number of operations to compute entry: 4
4570
A[j] += FE0_f0[ip][j]*F0*W2[ip]*det;
4571
}// end loop over 'j'
4572
}// end loop over 'ip'
4577
// Total number of operations to compute element tensor (from this point): 36
4579
// Loop quadrature points for integral
4580
// Number of operations to compute element tensor for following IP loop = 36
4581
for (unsigned int ip = 0; ip < 2; ip++)
4584
// Function declarations
4587
// Total number of operations to compute function values = 6
4588
for (unsigned int r = 0; r < 3; r++)
4590
F0 += FE0_f1[ip][r]*w[1][r];
4591
}// end loop over 'r'
4593
// Number of operations for primary indices: 12
4594
for (unsigned int j = 0; j < 3; j++)
4596
// Number of operations to compute entry: 4
4597
A[j] += FE0_f1[ip][j]*F0*W2[ip]*det;
4598
}// end loop over 'j'
4599
}// end loop over 'ip'
4604
// Total number of operations to compute element tensor (from this point): 36
4606
// Loop quadrature points for integral
4607
// Number of operations to compute element tensor for following IP loop = 36
4608
for (unsigned int ip = 0; ip < 2; ip++)
4611
// Function declarations
4614
// Total number of operations to compute function values = 6
4615
for (unsigned int r = 0; r < 3; r++)
4617
F0 += FE0_f2[ip][r]*w[1][r];
4618
}// end loop over 'r'
4620
// Number of operations for primary indices: 12
4621
for (unsigned int j = 0; j < 3; j++)
4623
// Number of operations to compute entry: 4
4624
A[j] += FE0_f2[ip][j]*F0*W2[ip]*det;
4625
}// end loop over 'j'
4626
}// end loop over 'ip'
4634
/// This class defines the interface for the tabulation of the
4635
/// exterior facet tensor corresponding to the local contribution to
4636
/// a form from the integral over an exterior facet.
4638
class poissondg_1_exterior_facet_integral_0: public ufc::exterior_facet_integral
4642
poissondg_1_exterior_facet_integral_0_quadrature integral_0_quadrature;
4647
poissondg_1_exterior_facet_integral_0() : ufc::exterior_facet_integral()
4653
virtual ~poissondg_1_exterior_facet_integral_0()
4658
/// Tabulate the tensor for the contribution from a local exterior facet
4659
virtual void tabulate_tensor(double* A,
4660
const double * const * w,
4662
unsigned int facet) const
4664
// Reset values of the element tensor block
4665
for (unsigned int j = 0; j < 3; j++)
4668
// Add all contributions to element tensor
4669
integral_0_quadrature.tabulate_tensor(A, w, c, facet);
4674
/// This class defines the interface for the assembly of the global
4675
/// tensor corresponding to a form with r + n arguments, that is, a
4678
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
4680
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
4681
/// global tensor A is defined by
4683
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
4685
/// where each argument Vj represents the application to the
4686
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
4687
/// fixed functions (coefficients).
4689
class poissondg_form_1: public ufc::form
4694
poissondg_form_1() : ufc::form()
4700
virtual ~poissondg_form_1()
4705
/// Return a string identifying the form
4706
virtual const char* signature() const
4708
return "Form([Integral(Product(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), Function(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0)), Measure('cell', 0, None)), Integral(Product(BasisFunction(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 0), Function(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 1), 1)), Measure('exterior_facet', 0, None))])";
4711
/// Return the rank of the global tensor (r)
4712
virtual unsigned int rank() const
4717
/// Return the number of coefficients (n)
4718
virtual unsigned int num_coefficients() const
4723
/// Return the number of cell integrals
4724
virtual unsigned int num_cell_integrals() const
4729
/// Return the number of exterior facet integrals
4730
virtual unsigned int num_exterior_facet_integrals() const
4735
/// Return the number of interior facet integrals
4736
virtual unsigned int num_interior_facet_integrals() const
4741
/// Create a new finite element for argument function i
4742
virtual ufc::finite_element* create_finite_element(unsigned int i) const
4747
return new poissondg_1_finite_element_0();
4750
return new poissondg_1_finite_element_1();
4753
return new poissondg_1_finite_element_2();
4759
/// Create a new dof map for argument function i
4760
virtual ufc::dof_map* create_dof_map(unsigned int i) const
4765
return new poissondg_1_dof_map_0();
4768
return new poissondg_1_dof_map_1();
4771
return new poissondg_1_dof_map_2();
4777
/// Create a new cell integral on sub domain i
4778
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
4780
return new poissondg_1_cell_integral_0();
4783
/// Create a new exterior facet integral on sub domain i
4784
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
4786
return new poissondg_1_exterior_facet_integral_0();
4789
/// Create a new interior facet integral on sub domain i
4790
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const