1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.6.0.
4
// Warning: This code was generated with the option '-l dolfin'
5
// and contains DOLFIN-specific wrappers that depend on DOLFIN.
7
#ifndef __POISSON2D_2_H
8
#define __POISSON2D_2_H
15
/// This class defines the interface for a finite element.
17
class UFC_Poisson2D_2BilinearForm_finite_element_0: public ufc::finite_element
22
UFC_Poisson2D_2BilinearForm_finite_element_0() : ufc::finite_element()
28
virtual ~UFC_Poisson2D_2BilinearForm_finite_element_0()
33
/// Return a string identifying the finite element
34
virtual const char* signature() const
36
return "FiniteElement('Lagrange', 'triangle', 2)";
39
/// Return the cell shape
40
virtual ufc::shape cell_shape() const
45
/// Return the dimension of the finite element function space
46
virtual unsigned int space_dimension() const
51
/// Return the rank of the value space
52
virtual unsigned int value_rank() const
57
/// Return the dimension of the value space for axis i
58
virtual unsigned int value_dimension(unsigned int i) const
63
/// Evaluate basis function i at given point in cell
64
virtual void evaluate_basis(unsigned int i,
66
const double* coordinates,
67
const ufc::cell& c) const
69
// Extract vertex coordinates
70
const double * const * element_coordinates = c.coordinates;
72
// Compute Jacobian of affine map from reference cell
73
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
74
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
75
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
76
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
78
// Compute determinant of Jacobian
79
const double detJ = J_00*J_11 - J_01*J_10;
81
// Compute inverse of Jacobian
83
// Get coordinates and map to the reference (UFC) element
84
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
85
element_coordinates[0][0]*element_coordinates[2][1] +\
86
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
87
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
88
element_coordinates[1][0]*element_coordinates[0][1] -\
89
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
91
// Map coordinates to the reference square
92
if (std::abs(y - 1.0) < 1e-14)
95
x = 2.0 *x/(1.0 - y) - 1.0;
101
// Map degree of freedom to element degree of freedom
102
const unsigned int dof = i;
105
const double scalings_y_0 = 1;
106
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
107
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
109
// Compute psitilde_a
110
const double psitilde_a_0 = 1;
111
const double psitilde_a_1 = x;
112
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
114
// Compute psitilde_bs
115
const double psitilde_bs_0_0 = 1;
116
const double psitilde_bs_0_1 = 1.5*y + 0.5;
117
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
118
const double psitilde_bs_1_0 = 1;
119
const double psitilde_bs_1_1 = 2.5*y + 1.5;
120
const double psitilde_bs_2_0 = 1;
122
// Compute basisvalues
123
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
124
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
125
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
126
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
127
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
128
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
130
// Table(s) of coefficients
131
const static double coefficients0[6][6] = \
132
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
133
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
134
{0, 0, 0.2, 0, 0, 0.163299316185545},
135
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
136
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
137
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
139
// Extract relevant coefficients
140
const double coeff0_0 = coefficients0[dof][0];
141
const double coeff0_1 = coefficients0[dof][1];
142
const double coeff0_2 = coefficients0[dof][2];
143
const double coeff0_3 = coefficients0[dof][3];
144
const double coeff0_4 = coefficients0[dof][4];
145
const double coeff0_5 = coefficients0[dof][5];
148
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
151
/// Evaluate all basis functions at given point in cell
152
virtual void evaluate_basis_all(double* values,
153
const double* coordinates,
154
const ufc::cell& c) const
156
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
159
/// Evaluate order n derivatives of basis function i at given point in cell
160
virtual void evaluate_basis_derivatives(unsigned int i,
163
const double* coordinates,
164
const ufc::cell& c) const
166
// Extract vertex coordinates
167
const double * const * element_coordinates = c.coordinates;
169
// Compute Jacobian of affine map from reference cell
170
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
171
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
172
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
173
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
175
// Compute determinant of Jacobian
176
const double detJ = J_00*J_11 - J_01*J_10;
178
// Compute inverse of Jacobian
180
// Get coordinates and map to the reference (UFC) element
181
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
182
element_coordinates[0][0]*element_coordinates[2][1] +\
183
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
184
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
185
element_coordinates[1][0]*element_coordinates[0][1] -\
186
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
188
// Map coordinates to the reference square
189
if (std::abs(y - 1.0) < 1e-14)
192
x = 2.0 *x/(1.0 - y) - 1.0;
195
// Compute number of derivatives
196
unsigned int num_derivatives = 1;
198
for (unsigned int j = 0; j < n; j++)
199
num_derivatives *= 2;
202
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
203
unsigned int **combinations = new unsigned int *[num_derivatives];
205
for (unsigned int j = 0; j < num_derivatives; j++)
207
combinations[j] = new unsigned int [n];
208
for (unsigned int k = 0; k < n; k++)
209
combinations[j][k] = 0;
212
// Generate combinations of derivatives
213
for (unsigned int row = 1; row < num_derivatives; row++)
215
for (unsigned int num = 0; num < row; num++)
217
for (unsigned int col = n-1; col+1 > 0; col--)
219
if (combinations[row][col] + 1 > 1)
220
combinations[row][col] = 0;
223
combinations[row][col] += 1;
230
// Compute inverse of Jacobian
231
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
233
// Declare transformation matrix
234
// Declare pointer to two dimensional array and initialise
235
double **transform = new double *[num_derivatives];
237
for (unsigned int j = 0; j < num_derivatives; j++)
239
transform[j] = new double [num_derivatives];
240
for (unsigned int k = 0; k < num_derivatives; k++)
244
// Construct transformation matrix
245
for (unsigned int row = 0; row < num_derivatives; row++)
247
for (unsigned int col = 0; col < num_derivatives; col++)
249
for (unsigned int k = 0; k < n; k++)
250
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
255
for (unsigned int j = 0; j < 1*num_derivatives; j++)
258
// Map degree of freedom to element degree of freedom
259
const unsigned int dof = i;
262
const double scalings_y_0 = 1;
263
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
264
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
266
// Compute psitilde_a
267
const double psitilde_a_0 = 1;
268
const double psitilde_a_1 = x;
269
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
271
// Compute psitilde_bs
272
const double psitilde_bs_0_0 = 1;
273
const double psitilde_bs_0_1 = 1.5*y + 0.5;
274
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
275
const double psitilde_bs_1_0 = 1;
276
const double psitilde_bs_1_1 = 2.5*y + 1.5;
277
const double psitilde_bs_2_0 = 1;
279
// Compute basisvalues
280
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
281
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
282
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
283
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
284
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
285
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
287
// Table(s) of coefficients
288
const static double coefficients0[6][6] = \
289
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
290
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
291
{0, 0, 0.2, 0, 0, 0.163299316185545},
292
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
293
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
294
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
296
// Interesting (new) part
297
// Tables of derivatives of the polynomial base (transpose)
298
const static double dmats0[6][6] = \
300
{4.89897948556636, 0, 0, 0, 0, 0},
302
{0, 9.48683298050514, 0, 0, 0, 0},
303
{4, 0, 7.07106781186548, 0, 0, 0},
306
const static double dmats1[6][6] = \
308
{2.44948974278318, 0, 0, 0, 0, 0},
309
{4.24264068711928, 0, 0, 0, 0, 0},
310
{2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
311
{2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
312
{-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
314
// Compute reference derivatives
315
// Declare pointer to array of derivatives on FIAT element
316
double *derivatives = new double [num_derivatives];
318
// Declare coefficients
326
// Declare new coefficients
327
double new_coeff0_0 = 0;
328
double new_coeff0_1 = 0;
329
double new_coeff0_2 = 0;
330
double new_coeff0_3 = 0;
331
double new_coeff0_4 = 0;
332
double new_coeff0_5 = 0;
334
// Loop possible derivatives
335
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
337
// Get values from coefficients array
338
new_coeff0_0 = coefficients0[dof][0];
339
new_coeff0_1 = coefficients0[dof][1];
340
new_coeff0_2 = coefficients0[dof][2];
341
new_coeff0_3 = coefficients0[dof][3];
342
new_coeff0_4 = coefficients0[dof][4];
343
new_coeff0_5 = coefficients0[dof][5];
345
// Loop derivative order
346
for (unsigned int j = 0; j < n; j++)
348
// Update old coefficients
349
coeff0_0 = new_coeff0_0;
350
coeff0_1 = new_coeff0_1;
351
coeff0_2 = new_coeff0_2;
352
coeff0_3 = new_coeff0_3;
353
coeff0_4 = new_coeff0_4;
354
coeff0_5 = new_coeff0_5;
356
if(combinations[deriv_num][j] == 0)
358
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
359
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
360
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
361
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
362
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
363
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
365
if(combinations[deriv_num][j] == 1)
367
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
368
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
369
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
370
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
371
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
372
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
376
// Compute derivatives on reference element as dot product of coefficients and basisvalues
377
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
380
// Transform derivatives back to physical element
381
for (unsigned int row = 0; row < num_derivatives; row++)
383
for (unsigned int col = 0; col < num_derivatives; col++)
385
values[row] += transform[row][col]*derivatives[col];
388
// Delete pointer to array of derivatives on FIAT element
389
delete [] derivatives;
391
// Delete pointer to array of combinations of derivatives and transform
392
for (unsigned int row = 0; row < num_derivatives; row++)
394
delete [] combinations[row];
395
delete [] transform[row];
398
delete [] combinations;
402
/// Evaluate order n derivatives of all basis functions at given point in cell
403
virtual void evaluate_basis_derivatives_all(unsigned int n,
405
const double* coordinates,
406
const ufc::cell& c) const
408
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
411
/// Evaluate linear functional for dof i on the function f
412
virtual double evaluate_dof(unsigned int i,
413
const ufc::function& f,
414
const ufc::cell& c) const
416
// The reference points, direction and weights:
417
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
418
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
419
const static double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
421
const double * const * x = c.coordinates;
423
// Iterate over the points:
424
// Evaluate basis functions for affine mapping
425
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
426
const double w1 = X[i][0][0];
427
const double w2 = X[i][0][1];
429
// Compute affine mapping y = F(X)
431
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
432
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
434
// Evaluate function at physical points
436
f.evaluate(values, y, c);
438
// Map function values using appropriate mapping
439
// Affine map: Do nothing
441
// Note that we do not map the weights (yet).
443
// Take directional components
444
for(int k = 0; k < 1; k++)
445
result += values[k]*D[i][0][k];
446
// Multiply by weights
452
/// Evaluate linear functionals for all dofs on the function f
453
virtual void evaluate_dofs(double* values,
454
const ufc::function& f,
455
const ufc::cell& c) const
457
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
460
/// Interpolate vertex values from dof values
461
virtual void interpolate_vertex_values(double* vertex_values,
462
const double* dof_values,
463
const ufc::cell& c) const
465
// Evaluate at vertices and use affine mapping
466
vertex_values[0] = dof_values[0];
467
vertex_values[1] = dof_values[1];
468
vertex_values[2] = dof_values[2];
471
/// Return the number of sub elements (for a mixed element)
472
virtual unsigned int num_sub_elements() const
477
/// Create a new finite element for sub element i (for a mixed element)
478
virtual ufc::finite_element* create_sub_element(unsigned int i) const
480
return new UFC_Poisson2D_2BilinearForm_finite_element_0();
485
/// This class defines the interface for a finite element.
487
class UFC_Poisson2D_2BilinearForm_finite_element_1: public ufc::finite_element
492
UFC_Poisson2D_2BilinearForm_finite_element_1() : ufc::finite_element()
498
virtual ~UFC_Poisson2D_2BilinearForm_finite_element_1()
503
/// Return a string identifying the finite element
504
virtual const char* signature() const
506
return "FiniteElement('Lagrange', 'triangle', 2)";
509
/// Return the cell shape
510
virtual ufc::shape cell_shape() const
512
return ufc::triangle;
515
/// Return the dimension of the finite element function space
516
virtual unsigned int space_dimension() const
521
/// Return the rank of the value space
522
virtual unsigned int value_rank() const
527
/// Return the dimension of the value space for axis i
528
virtual unsigned int value_dimension(unsigned int i) const
533
/// Evaluate basis function i at given point in cell
534
virtual void evaluate_basis(unsigned int i,
536
const double* coordinates,
537
const ufc::cell& c) const
539
// Extract vertex coordinates
540
const double * const * element_coordinates = c.coordinates;
542
// Compute Jacobian of affine map from reference cell
543
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
544
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
545
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
546
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
548
// Compute determinant of Jacobian
549
const double detJ = J_00*J_11 - J_01*J_10;
551
// Compute inverse of Jacobian
553
// Get coordinates and map to the reference (UFC) element
554
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
555
element_coordinates[0][0]*element_coordinates[2][1] +\
556
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
557
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
558
element_coordinates[1][0]*element_coordinates[0][1] -\
559
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
561
// Map coordinates to the reference square
562
if (std::abs(y - 1.0) < 1e-14)
565
x = 2.0 *x/(1.0 - y) - 1.0;
571
// Map degree of freedom to element degree of freedom
572
const unsigned int dof = i;
575
const double scalings_y_0 = 1;
576
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
577
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
579
// Compute psitilde_a
580
const double psitilde_a_0 = 1;
581
const double psitilde_a_1 = x;
582
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
584
// Compute psitilde_bs
585
const double psitilde_bs_0_0 = 1;
586
const double psitilde_bs_0_1 = 1.5*y + 0.5;
587
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
588
const double psitilde_bs_1_0 = 1;
589
const double psitilde_bs_1_1 = 2.5*y + 1.5;
590
const double psitilde_bs_2_0 = 1;
592
// Compute basisvalues
593
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
594
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
595
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
596
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
597
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
598
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
600
// Table(s) of coefficients
601
const static double coefficients0[6][6] = \
602
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
603
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
604
{0, 0, 0.2, 0, 0, 0.163299316185545},
605
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
606
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
607
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
609
// Extract relevant coefficients
610
const double coeff0_0 = coefficients0[dof][0];
611
const double coeff0_1 = coefficients0[dof][1];
612
const double coeff0_2 = coefficients0[dof][2];
613
const double coeff0_3 = coefficients0[dof][3];
614
const double coeff0_4 = coefficients0[dof][4];
615
const double coeff0_5 = coefficients0[dof][5];
618
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
621
/// Evaluate all basis functions at given point in cell
622
virtual void evaluate_basis_all(double* values,
623
const double* coordinates,
624
const ufc::cell& c) const
626
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
629
/// Evaluate order n derivatives of basis function i at given point in cell
630
virtual void evaluate_basis_derivatives(unsigned int i,
633
const double* coordinates,
634
const ufc::cell& c) const
636
// Extract vertex coordinates
637
const double * const * element_coordinates = c.coordinates;
639
// Compute Jacobian of affine map from reference cell
640
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
641
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
642
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
643
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
645
// Compute determinant of Jacobian
646
const double detJ = J_00*J_11 - J_01*J_10;
648
// Compute inverse of Jacobian
650
// Get coordinates and map to the reference (UFC) element
651
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
652
element_coordinates[0][0]*element_coordinates[2][1] +\
653
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
654
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
655
element_coordinates[1][0]*element_coordinates[0][1] -\
656
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
658
// Map coordinates to the reference square
659
if (std::abs(y - 1.0) < 1e-14)
662
x = 2.0 *x/(1.0 - y) - 1.0;
665
// Compute number of derivatives
666
unsigned int num_derivatives = 1;
668
for (unsigned int j = 0; j < n; j++)
669
num_derivatives *= 2;
672
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
673
unsigned int **combinations = new unsigned int *[num_derivatives];
675
for (unsigned int j = 0; j < num_derivatives; j++)
677
combinations[j] = new unsigned int [n];
678
for (unsigned int k = 0; k < n; k++)
679
combinations[j][k] = 0;
682
// Generate combinations of derivatives
683
for (unsigned int row = 1; row < num_derivatives; row++)
685
for (unsigned int num = 0; num < row; num++)
687
for (unsigned int col = n-1; col+1 > 0; col--)
689
if (combinations[row][col] + 1 > 1)
690
combinations[row][col] = 0;
693
combinations[row][col] += 1;
700
// Compute inverse of Jacobian
701
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
703
// Declare transformation matrix
704
// Declare pointer to two dimensional array and initialise
705
double **transform = new double *[num_derivatives];
707
for (unsigned int j = 0; j < num_derivatives; j++)
709
transform[j] = new double [num_derivatives];
710
for (unsigned int k = 0; k < num_derivatives; k++)
714
// Construct transformation matrix
715
for (unsigned int row = 0; row < num_derivatives; row++)
717
for (unsigned int col = 0; col < num_derivatives; col++)
719
for (unsigned int k = 0; k < n; k++)
720
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
725
for (unsigned int j = 0; j < 1*num_derivatives; j++)
728
// Map degree of freedom to element degree of freedom
729
const unsigned int dof = i;
732
const double scalings_y_0 = 1;
733
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
734
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
736
// Compute psitilde_a
737
const double psitilde_a_0 = 1;
738
const double psitilde_a_1 = x;
739
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
741
// Compute psitilde_bs
742
const double psitilde_bs_0_0 = 1;
743
const double psitilde_bs_0_1 = 1.5*y + 0.5;
744
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
745
const double psitilde_bs_1_0 = 1;
746
const double psitilde_bs_1_1 = 2.5*y + 1.5;
747
const double psitilde_bs_2_0 = 1;
749
// Compute basisvalues
750
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
751
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
752
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
753
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
754
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
755
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
757
// Table(s) of coefficients
758
const static double coefficients0[6][6] = \
759
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
760
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
761
{0, 0, 0.2, 0, 0, 0.163299316185545},
762
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
763
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
764
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
766
// Interesting (new) part
767
// Tables of derivatives of the polynomial base (transpose)
768
const static double dmats0[6][6] = \
770
{4.89897948556636, 0, 0, 0, 0, 0},
772
{0, 9.48683298050514, 0, 0, 0, 0},
773
{4, 0, 7.07106781186548, 0, 0, 0},
776
const static double dmats1[6][6] = \
778
{2.44948974278318, 0, 0, 0, 0, 0},
779
{4.24264068711928, 0, 0, 0, 0, 0},
780
{2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
781
{2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
782
{-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
784
// Compute reference derivatives
785
// Declare pointer to array of derivatives on FIAT element
786
double *derivatives = new double [num_derivatives];
788
// Declare coefficients
796
// Declare new coefficients
797
double new_coeff0_0 = 0;
798
double new_coeff0_1 = 0;
799
double new_coeff0_2 = 0;
800
double new_coeff0_3 = 0;
801
double new_coeff0_4 = 0;
802
double new_coeff0_5 = 0;
804
// Loop possible derivatives
805
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
807
// Get values from coefficients array
808
new_coeff0_0 = coefficients0[dof][0];
809
new_coeff0_1 = coefficients0[dof][1];
810
new_coeff0_2 = coefficients0[dof][2];
811
new_coeff0_3 = coefficients0[dof][3];
812
new_coeff0_4 = coefficients0[dof][4];
813
new_coeff0_5 = coefficients0[dof][5];
815
// Loop derivative order
816
for (unsigned int j = 0; j < n; j++)
818
// Update old coefficients
819
coeff0_0 = new_coeff0_0;
820
coeff0_1 = new_coeff0_1;
821
coeff0_2 = new_coeff0_2;
822
coeff0_3 = new_coeff0_3;
823
coeff0_4 = new_coeff0_4;
824
coeff0_5 = new_coeff0_5;
826
if(combinations[deriv_num][j] == 0)
828
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
829
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
830
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
831
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
832
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
833
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
835
if(combinations[deriv_num][j] == 1)
837
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
838
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
839
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
840
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
841
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
842
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
846
// Compute derivatives on reference element as dot product of coefficients and basisvalues
847
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
850
// Transform derivatives back to physical element
851
for (unsigned int row = 0; row < num_derivatives; row++)
853
for (unsigned int col = 0; col < num_derivatives; col++)
855
values[row] += transform[row][col]*derivatives[col];
858
// Delete pointer to array of derivatives on FIAT element
859
delete [] derivatives;
861
// Delete pointer to array of combinations of derivatives and transform
862
for (unsigned int row = 0; row < num_derivatives; row++)
864
delete [] combinations[row];
865
delete [] transform[row];
868
delete [] combinations;
872
/// Evaluate order n derivatives of all basis functions at given point in cell
873
virtual void evaluate_basis_derivatives_all(unsigned int n,
875
const double* coordinates,
876
const ufc::cell& c) const
878
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
881
/// Evaluate linear functional for dof i on the function f
882
virtual double evaluate_dof(unsigned int i,
883
const ufc::function& f,
884
const ufc::cell& c) const
886
// The reference points, direction and weights:
887
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
888
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
889
const static double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
891
const double * const * x = c.coordinates;
893
// Iterate over the points:
894
// Evaluate basis functions for affine mapping
895
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
896
const double w1 = X[i][0][0];
897
const double w2 = X[i][0][1];
899
// Compute affine mapping y = F(X)
901
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
902
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
904
// Evaluate function at physical points
906
f.evaluate(values, y, c);
908
// Map function values using appropriate mapping
909
// Affine map: Do nothing
911
// Note that we do not map the weights (yet).
913
// Take directional components
914
for(int k = 0; k < 1; k++)
915
result += values[k]*D[i][0][k];
916
// Multiply by weights
922
/// Evaluate linear functionals for all dofs on the function f
923
virtual void evaluate_dofs(double* values,
924
const ufc::function& f,
925
const ufc::cell& c) const
927
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
930
/// Interpolate vertex values from dof values
931
virtual void interpolate_vertex_values(double* vertex_values,
932
const double* dof_values,
933
const ufc::cell& c) const
935
// Evaluate at vertices and use affine mapping
936
vertex_values[0] = dof_values[0];
937
vertex_values[1] = dof_values[1];
938
vertex_values[2] = dof_values[2];
941
/// Return the number of sub elements (for a mixed element)
942
virtual unsigned int num_sub_elements() const
947
/// Create a new finite element for sub element i (for a mixed element)
948
virtual ufc::finite_element* create_sub_element(unsigned int i) const
950
return new UFC_Poisson2D_2BilinearForm_finite_element_1();
955
/// This class defines the interface for a local-to-global mapping of
956
/// degrees of freedom (dofs).
958
class UFC_Poisson2D_2BilinearForm_dof_map_0: public ufc::dof_map
962
unsigned int __global_dimension;
967
UFC_Poisson2D_2BilinearForm_dof_map_0() : ufc::dof_map()
969
__global_dimension = 0;
973
virtual ~UFC_Poisson2D_2BilinearForm_dof_map_0()
978
/// Return a string identifying the dof map
979
virtual const char* signature() const
981
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
984
/// Return true iff mesh entities of topological dimension d are needed
985
virtual bool needs_mesh_entities(unsigned int d) const
1002
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1003
virtual bool init_mesh(const ufc::mesh& m)
1005
__global_dimension = m.num_entities[0] + m.num_entities[1];
1009
/// Initialize dof map for given cell
1010
virtual void init_cell(const ufc::mesh& m,
1016
/// Finish initialization of dof map for cells
1017
virtual void init_cell_finalize()
1022
/// Return the dimension of the global finite element function space
1023
virtual unsigned int global_dimension() const
1025
return __global_dimension;
1028
/// Return the dimension of the local finite element function space
1029
virtual unsigned int local_dimension() const
1034
// Return the geometric dimension of the coordinates this dof map provides
1035
virtual unsigned int geometric_dimension() const
1040
/// Return the number of dofs on each cell facet
1041
virtual unsigned int num_facet_dofs() const
1046
/// Return the number of dofs associated with each cell entity of dimension d
1047
virtual unsigned int num_entity_dofs(unsigned int d) const
1049
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1052
/// Tabulate the local-to-global mapping of dofs on a cell
1053
virtual void tabulate_dofs(unsigned int* dofs,
1055
const ufc::cell& c) const
1057
dofs[0] = c.entity_indices[0][0];
1058
dofs[1] = c.entity_indices[0][1];
1059
dofs[2] = c.entity_indices[0][2];
1060
unsigned int offset = m.num_entities[0];
1061
dofs[3] = offset + c.entity_indices[1][0];
1062
dofs[4] = offset + c.entity_indices[1][1];
1063
dofs[5] = offset + c.entity_indices[1][2];
1066
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1067
virtual void tabulate_facet_dofs(unsigned int* dofs,
1068
unsigned int facet) const
1090
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1091
virtual void tabulate_entity_dofs(unsigned int* dofs,
1092
unsigned int d, unsigned int i) const
1094
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1097
/// Tabulate the coordinates of all dofs on a cell
1098
virtual void tabulate_coordinates(double** coordinates,
1099
const ufc::cell& c) const
1101
const double * const * x = c.coordinates;
1102
coordinates[0][0] = x[0][0];
1103
coordinates[0][1] = x[0][1];
1104
coordinates[1][0] = x[1][0];
1105
coordinates[1][1] = x[1][1];
1106
coordinates[2][0] = x[2][0];
1107
coordinates[2][1] = x[2][1];
1108
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
1109
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
1110
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
1111
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
1112
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
1113
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
1116
/// Return the number of sub dof maps (for a mixed element)
1117
virtual unsigned int num_sub_dof_maps() const
1122
/// Create a new dof_map for sub dof map i (for a mixed element)
1123
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1125
return new UFC_Poisson2D_2BilinearForm_dof_map_0();
1130
/// This class defines the interface for a local-to-global mapping of
1131
/// degrees of freedom (dofs).
1133
class UFC_Poisson2D_2BilinearForm_dof_map_1: public ufc::dof_map
1137
unsigned int __global_dimension;
1142
UFC_Poisson2D_2BilinearForm_dof_map_1() : ufc::dof_map()
1144
__global_dimension = 0;
1148
virtual ~UFC_Poisson2D_2BilinearForm_dof_map_1()
1153
/// Return a string identifying the dof map
1154
virtual const char* signature() const
1156
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
1159
/// Return true iff mesh entities of topological dimension d are needed
1160
virtual bool needs_mesh_entities(unsigned int d) const
1177
/// Initialize dof map for mesh (return true iff init_cell() is needed)
1178
virtual bool init_mesh(const ufc::mesh& m)
1180
__global_dimension = m.num_entities[0] + m.num_entities[1];
1184
/// Initialize dof map for given cell
1185
virtual void init_cell(const ufc::mesh& m,
1191
/// Finish initialization of dof map for cells
1192
virtual void init_cell_finalize()
1197
/// Return the dimension of the global finite element function space
1198
virtual unsigned int global_dimension() const
1200
return __global_dimension;
1203
/// Return the dimension of the local finite element function space
1204
virtual unsigned int local_dimension() const
1209
// Return the geometric dimension of the coordinates this dof map provides
1210
virtual unsigned int geometric_dimension() const
1215
/// Return the number of dofs on each cell facet
1216
virtual unsigned int num_facet_dofs() const
1221
/// Return the number of dofs associated with each cell entity of dimension d
1222
virtual unsigned int num_entity_dofs(unsigned int d) const
1224
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1227
/// Tabulate the local-to-global mapping of dofs on a cell
1228
virtual void tabulate_dofs(unsigned int* dofs,
1230
const ufc::cell& c) const
1232
dofs[0] = c.entity_indices[0][0];
1233
dofs[1] = c.entity_indices[0][1];
1234
dofs[2] = c.entity_indices[0][2];
1235
unsigned int offset = m.num_entities[0];
1236
dofs[3] = offset + c.entity_indices[1][0];
1237
dofs[4] = offset + c.entity_indices[1][1];
1238
dofs[5] = offset + c.entity_indices[1][2];
1241
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
1242
virtual void tabulate_facet_dofs(unsigned int* dofs,
1243
unsigned int facet) const
1265
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
1266
virtual void tabulate_entity_dofs(unsigned int* dofs,
1267
unsigned int d, unsigned int i) const
1269
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1272
/// Tabulate the coordinates of all dofs on a cell
1273
virtual void tabulate_coordinates(double** coordinates,
1274
const ufc::cell& c) const
1276
const double * const * x = c.coordinates;
1277
coordinates[0][0] = x[0][0];
1278
coordinates[0][1] = x[0][1];
1279
coordinates[1][0] = x[1][0];
1280
coordinates[1][1] = x[1][1];
1281
coordinates[2][0] = x[2][0];
1282
coordinates[2][1] = x[2][1];
1283
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
1284
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
1285
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
1286
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
1287
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
1288
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
1291
/// Return the number of sub dof maps (for a mixed element)
1292
virtual unsigned int num_sub_dof_maps() const
1297
/// Create a new dof_map for sub dof map i (for a mixed element)
1298
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1300
return new UFC_Poisson2D_2BilinearForm_dof_map_1();
1305
/// This class defines the interface for the tabulation of the cell
1306
/// tensor corresponding to the local contribution to a form from
1307
/// the integral over a cell.
1309
class UFC_Poisson2D_2BilinearForm_cell_integral_0: public ufc::cell_integral
1314
UFC_Poisson2D_2BilinearForm_cell_integral_0() : ufc::cell_integral()
1320
virtual ~UFC_Poisson2D_2BilinearForm_cell_integral_0()
1325
/// Tabulate the tensor for the contribution from a local cell
1326
virtual void tabulate_tensor(double* A,
1327
const double * const * w,
1328
const ufc::cell& c) const
1330
// Extract vertex coordinates
1331
const double * const * x = c.coordinates;
1333
// Compute Jacobian of affine map from reference cell
1334
const double J_00 = x[1][0] - x[0][0];
1335
const double J_01 = x[2][0] - x[0][0];
1336
const double J_10 = x[1][1] - x[0][1];
1337
const double J_11 = x[2][1] - x[0][1];
1339
// Compute determinant of Jacobian
1340
double detJ = J_00*J_11 - J_01*J_10;
1342
// Compute inverse of Jacobian
1343
const double Jinv_00 = J_11 / detJ;
1344
const double Jinv_01 = -J_01 / detJ;
1345
const double Jinv_10 = -J_10 / detJ;
1346
const double Jinv_11 = J_00 / detJ;
1349
const double det = std::abs(detJ);
1351
// Number of operations to compute element tensor = 114
1352
// Compute geometry tensors
1353
// Number of operations to compute decalrations = 16
1354
const double G0_0_0 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
1355
const double G0_0_1 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
1356
const double G0_1_0 = det*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
1357
const double G0_1_1 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
1359
// Compute element tensor
1360
// Number of operations to compute tensor = 98
1361
A[0] = 0.499999999999999*G0_0_0 + 0.499999999999999*G0_0_1 + 0.499999999999999*G0_1_0 + 0.499999999999999*G0_1_1;
1362
A[1] = 0.166666666666666*G0_0_0 + 0.166666666666666*G0_1_0;
1363
A[2] = 0.166666666666666*G0_0_1 + 0.166666666666666*G0_1_1;
1365
A[4] = -0.666666666666665*G0_0_1 - 0.666666666666665*G0_1_1;
1366
A[5] = -0.666666666666666*G0_0_0 - 0.666666666666666*G0_1_0;
1367
A[6] = 0.166666666666666*G0_0_0 + 0.166666666666666*G0_0_1;
1368
A[7] = 0.499999999999999*G0_0_0;
1369
A[8] = -0.166666666666666*G0_0_1;
1370
A[9] = 0.666666666666665*G0_0_1;
1372
A[11] = -0.666666666666666*G0_0_0 - 0.666666666666665*G0_0_1;
1373
A[12] = 0.166666666666666*G0_1_0 + 0.166666666666666*G0_1_1;
1374
A[13] = -0.166666666666666*G0_1_0;
1375
A[14] = 0.499999999999999*G0_1_1;
1376
A[15] = 0.666666666666666*G0_1_0;
1377
A[16] = -0.666666666666665*G0_1_0 - 0.666666666666665*G0_1_1;
1380
A[19] = 0.666666666666665*G0_1_0;
1381
A[20] = 0.666666666666666*G0_0_1;
1382
A[21] = 1.33333333333333*G0_0_0 + 0.666666666666665*G0_0_1 + 0.666666666666665*G0_1_0 + 1.33333333333333*G0_1_1;
1383
A[22] = -1.33333333333333*G0_0_0 - 0.666666666666665*G0_0_1 - 0.666666666666665*G0_1_0;
1384
A[23] = -0.666666666666666*G0_0_1 - 0.666666666666665*G0_1_0 - 1.33333333333333*G0_1_1;
1385
A[24] = -0.666666666666665*G0_1_0 - 0.666666666666665*G0_1_1;
1387
A[26] = -0.666666666666665*G0_0_1 - 0.666666666666665*G0_1_1;
1388
A[27] = -1.33333333333333*G0_0_0 - 0.666666666666665*G0_0_1 - 0.666666666666665*G0_1_0;
1389
A[28] = 1.33333333333333*G0_0_0 + 0.666666666666665*G0_0_1 + 0.666666666666665*G0_1_0 + 1.33333333333333*G0_1_1;
1390
A[29] = 0.666666666666666*G0_0_1 + 0.666666666666665*G0_1_0;
1391
A[30] = -0.666666666666665*G0_0_0 - 0.666666666666666*G0_0_1;
1392
A[31] = -0.666666666666665*G0_0_0 - 0.666666666666665*G0_1_0;
1394
A[33] = -0.666666666666665*G0_0_1 - 0.666666666666666*G0_1_0 - 1.33333333333333*G0_1_1;
1395
A[34] = 0.666666666666665*G0_0_1 + 0.666666666666666*G0_1_0;
1396
A[35] = 1.33333333333333*G0_0_0 + 0.666666666666666*G0_0_1 + 0.666666666666666*G0_1_0 + 1.33333333333333*G0_1_1;
1401
/// This class defines the interface for the assembly of the global
1402
/// tensor corresponding to a form with r + n arguments, that is, a
1405
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
1407
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
1408
/// global tensor A is defined by
1410
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
1412
/// where each argument Vj represents the application to the
1413
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
1414
/// fixed functions (coefficients).
1416
class UFC_Poisson2D_2BilinearForm: public ufc::form
1421
UFC_Poisson2D_2BilinearForm() : ufc::form()
1427
virtual ~UFC_Poisson2D_2BilinearForm()
1432
/// Return a string identifying the form
1433
virtual const char* signature() const
1435
return "(dXa0[0, 1]/dxb0[0, 1])(dXa1[0, 1]/dxb0[0, 1]) | ((d/dXa0[0, 1])vi0[0, 1, 2, 3, 4, 5])*((d/dXa1[0, 1])vi1[0, 1, 2, 3, 4, 5])*dX(0)";
1438
/// Return the rank of the global tensor (r)
1439
virtual unsigned int rank() const
1444
/// Return the number of coefficients (n)
1445
virtual unsigned int num_coefficients() const
1450
/// Return the number of cell integrals
1451
virtual unsigned int num_cell_integrals() const
1456
/// Return the number of exterior facet integrals
1457
virtual unsigned int num_exterior_facet_integrals() const
1462
/// Return the number of interior facet integrals
1463
virtual unsigned int num_interior_facet_integrals() const
1468
/// Create a new finite element for argument function i
1469
virtual ufc::finite_element* create_finite_element(unsigned int i) const
1474
return new UFC_Poisson2D_2BilinearForm_finite_element_0();
1477
return new UFC_Poisson2D_2BilinearForm_finite_element_1();
1483
/// Create a new dof map for argument function i
1484
virtual ufc::dof_map* create_dof_map(unsigned int i) const
1489
return new UFC_Poisson2D_2BilinearForm_dof_map_0();
1492
return new UFC_Poisson2D_2BilinearForm_dof_map_1();
1498
/// Create a new cell integral on sub domain i
1499
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
1501
return new UFC_Poisson2D_2BilinearForm_cell_integral_0();
1504
/// Create a new exterior facet integral on sub domain i
1505
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
1510
/// Create a new interior facet integral on sub domain i
1511
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
1518
/// This class defines the interface for a finite element.
1520
class UFC_Poisson2D_2LinearForm_finite_element_0: public ufc::finite_element
1525
UFC_Poisson2D_2LinearForm_finite_element_0() : ufc::finite_element()
1531
virtual ~UFC_Poisson2D_2LinearForm_finite_element_0()
1536
/// Return a string identifying the finite element
1537
virtual const char* signature() const
1539
return "FiniteElement('Lagrange', 'triangle', 2)";
1542
/// Return the cell shape
1543
virtual ufc::shape cell_shape() const
1545
return ufc::triangle;
1548
/// Return the dimension of the finite element function space
1549
virtual unsigned int space_dimension() const
1554
/// Return the rank of the value space
1555
virtual unsigned int value_rank() const
1560
/// Return the dimension of the value space for axis i
1561
virtual unsigned int value_dimension(unsigned int i) const
1566
/// Evaluate basis function i at given point in cell
1567
virtual void evaluate_basis(unsigned int i,
1569
const double* coordinates,
1570
const ufc::cell& c) const
1572
// Extract vertex coordinates
1573
const double * const * element_coordinates = c.coordinates;
1575
// Compute Jacobian of affine map from reference cell
1576
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1577
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1578
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1579
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1581
// Compute determinant of Jacobian
1582
const double detJ = J_00*J_11 - J_01*J_10;
1584
// Compute inverse of Jacobian
1586
// Get coordinates and map to the reference (UFC) element
1587
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1588
element_coordinates[0][0]*element_coordinates[2][1] +\
1589
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1590
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1591
element_coordinates[1][0]*element_coordinates[0][1] -\
1592
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1594
// Map coordinates to the reference square
1595
if (std::abs(y - 1.0) < 1e-14)
1598
x = 2.0 *x/(1.0 - y) - 1.0;
1604
// Map degree of freedom to element degree of freedom
1605
const unsigned int dof = i;
1607
// Generate scalings
1608
const double scalings_y_0 = 1;
1609
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1610
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
1612
// Compute psitilde_a
1613
const double psitilde_a_0 = 1;
1614
const double psitilde_a_1 = x;
1615
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
1617
// Compute psitilde_bs
1618
const double psitilde_bs_0_0 = 1;
1619
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1620
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
1621
const double psitilde_bs_1_0 = 1;
1622
const double psitilde_bs_1_1 = 2.5*y + 1.5;
1623
const double psitilde_bs_2_0 = 1;
1625
// Compute basisvalues
1626
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1627
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1628
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1629
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
1630
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
1631
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1633
// Table(s) of coefficients
1634
const static double coefficients0[6][6] = \
1635
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
1636
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
1637
{0, 0, 0.2, 0, 0, 0.163299316185545},
1638
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
1639
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
1640
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
1642
// Extract relevant coefficients
1643
const double coeff0_0 = coefficients0[dof][0];
1644
const double coeff0_1 = coefficients0[dof][1];
1645
const double coeff0_2 = coefficients0[dof][2];
1646
const double coeff0_3 = coefficients0[dof][3];
1647
const double coeff0_4 = coefficients0[dof][4];
1648
const double coeff0_5 = coefficients0[dof][5];
1651
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
1654
/// Evaluate all basis functions at given point in cell
1655
virtual void evaluate_basis_all(double* values,
1656
const double* coordinates,
1657
const ufc::cell& c) const
1659
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1662
/// Evaluate order n derivatives of basis function i at given point in cell
1663
virtual void evaluate_basis_derivatives(unsigned int i,
1666
const double* coordinates,
1667
const ufc::cell& c) const
1669
// Extract vertex coordinates
1670
const double * const * element_coordinates = c.coordinates;
1672
// Compute Jacobian of affine map from reference cell
1673
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1674
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1675
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1676
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1678
// Compute determinant of Jacobian
1679
const double detJ = J_00*J_11 - J_01*J_10;
1681
// Compute inverse of Jacobian
1683
// Get coordinates and map to the reference (UFC) element
1684
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1685
element_coordinates[0][0]*element_coordinates[2][1] +\
1686
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1687
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1688
element_coordinates[1][0]*element_coordinates[0][1] -\
1689
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1691
// Map coordinates to the reference square
1692
if (std::abs(y - 1.0) < 1e-14)
1695
x = 2.0 *x/(1.0 - y) - 1.0;
1698
// Compute number of derivatives
1699
unsigned int num_derivatives = 1;
1701
for (unsigned int j = 0; j < n; j++)
1702
num_derivatives *= 2;
1705
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1706
unsigned int **combinations = new unsigned int *[num_derivatives];
1708
for (unsigned int j = 0; j < num_derivatives; j++)
1710
combinations[j] = new unsigned int [n];
1711
for (unsigned int k = 0; k < n; k++)
1712
combinations[j][k] = 0;
1715
// Generate combinations of derivatives
1716
for (unsigned int row = 1; row < num_derivatives; row++)
1718
for (unsigned int num = 0; num < row; num++)
1720
for (unsigned int col = n-1; col+1 > 0; col--)
1722
if (combinations[row][col] + 1 > 1)
1723
combinations[row][col] = 0;
1726
combinations[row][col] += 1;
1733
// Compute inverse of Jacobian
1734
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1736
// Declare transformation matrix
1737
// Declare pointer to two dimensional array and initialise
1738
double **transform = new double *[num_derivatives];
1740
for (unsigned int j = 0; j < num_derivatives; j++)
1742
transform[j] = new double [num_derivatives];
1743
for (unsigned int k = 0; k < num_derivatives; k++)
1744
transform[j][k] = 1;
1747
// Construct transformation matrix
1748
for (unsigned int row = 0; row < num_derivatives; row++)
1750
for (unsigned int col = 0; col < num_derivatives; col++)
1752
for (unsigned int k = 0; k < n; k++)
1753
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1758
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1761
// Map degree of freedom to element degree of freedom
1762
const unsigned int dof = i;
1764
// Generate scalings
1765
const double scalings_y_0 = 1;
1766
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1767
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
1769
// Compute psitilde_a
1770
const double psitilde_a_0 = 1;
1771
const double psitilde_a_1 = x;
1772
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
1774
// Compute psitilde_bs
1775
const double psitilde_bs_0_0 = 1;
1776
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1777
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
1778
const double psitilde_bs_1_0 = 1;
1779
const double psitilde_bs_1_1 = 2.5*y + 1.5;
1780
const double psitilde_bs_2_0 = 1;
1782
// Compute basisvalues
1783
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1784
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1785
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1786
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
1787
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
1788
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1790
// Table(s) of coefficients
1791
const static double coefficients0[6][6] = \
1792
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
1793
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
1794
{0, 0, 0.2, 0, 0, 0.163299316185545},
1795
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
1796
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
1797
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
1799
// Interesting (new) part
1800
// Tables of derivatives of the polynomial base (transpose)
1801
const static double dmats0[6][6] = \
1802
{{0, 0, 0, 0, 0, 0},
1803
{4.89897948556636, 0, 0, 0, 0, 0},
1805
{0, 9.48683298050514, 0, 0, 0, 0},
1806
{4, 0, 7.07106781186548, 0, 0, 0},
1807
{0, 0, 0, 0, 0, 0}};
1809
const static double dmats1[6][6] = \
1810
{{0, 0, 0, 0, 0, 0},
1811
{2.44948974278318, 0, 0, 0, 0, 0},
1812
{4.24264068711928, 0, 0, 0, 0, 0},
1813
{2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
1814
{2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
1815
{-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
1817
// Compute reference derivatives
1818
// Declare pointer to array of derivatives on FIAT element
1819
double *derivatives = new double [num_derivatives];
1821
// Declare coefficients
1822
double coeff0_0 = 0;
1823
double coeff0_1 = 0;
1824
double coeff0_2 = 0;
1825
double coeff0_3 = 0;
1826
double coeff0_4 = 0;
1827
double coeff0_5 = 0;
1829
// Declare new coefficients
1830
double new_coeff0_0 = 0;
1831
double new_coeff0_1 = 0;
1832
double new_coeff0_2 = 0;
1833
double new_coeff0_3 = 0;
1834
double new_coeff0_4 = 0;
1835
double new_coeff0_5 = 0;
1837
// Loop possible derivatives
1838
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1840
// Get values from coefficients array
1841
new_coeff0_0 = coefficients0[dof][0];
1842
new_coeff0_1 = coefficients0[dof][1];
1843
new_coeff0_2 = coefficients0[dof][2];
1844
new_coeff0_3 = coefficients0[dof][3];
1845
new_coeff0_4 = coefficients0[dof][4];
1846
new_coeff0_5 = coefficients0[dof][5];
1848
// Loop derivative order
1849
for (unsigned int j = 0; j < n; j++)
1851
// Update old coefficients
1852
coeff0_0 = new_coeff0_0;
1853
coeff0_1 = new_coeff0_1;
1854
coeff0_2 = new_coeff0_2;
1855
coeff0_3 = new_coeff0_3;
1856
coeff0_4 = new_coeff0_4;
1857
coeff0_5 = new_coeff0_5;
1859
if(combinations[deriv_num][j] == 0)
1861
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
1862
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
1863
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
1864
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
1865
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
1866
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
1868
if(combinations[deriv_num][j] == 1)
1870
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
1871
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
1872
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
1873
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
1874
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
1875
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
1879
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1880
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
1883
// Transform derivatives back to physical element
1884
for (unsigned int row = 0; row < num_derivatives; row++)
1886
for (unsigned int col = 0; col < num_derivatives; col++)
1888
values[row] += transform[row][col]*derivatives[col];
1891
// Delete pointer to array of derivatives on FIAT element
1892
delete [] derivatives;
1894
// Delete pointer to array of combinations of derivatives and transform
1895
for (unsigned int row = 0; row < num_derivatives; row++)
1897
delete [] combinations[row];
1898
delete [] transform[row];
1901
delete [] combinations;
1902
delete [] transform;
1905
/// Evaluate order n derivatives of all basis functions at given point in cell
1906
virtual void evaluate_basis_derivatives_all(unsigned int n,
1908
const double* coordinates,
1909
const ufc::cell& c) const
1911
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1914
/// Evaluate linear functional for dof i on the function f
1915
virtual double evaluate_dof(unsigned int i,
1916
const ufc::function& f,
1917
const ufc::cell& c) const
1919
// The reference points, direction and weights:
1920
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
1921
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
1922
const static double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
1924
const double * const * x = c.coordinates;
1925
double result = 0.0;
1926
// Iterate over the points:
1927
// Evaluate basis functions for affine mapping
1928
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1929
const double w1 = X[i][0][0];
1930
const double w2 = X[i][0][1];
1932
// Compute affine mapping y = F(X)
1934
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1935
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1937
// Evaluate function at physical points
1939
f.evaluate(values, y, c);
1941
// Map function values using appropriate mapping
1942
// Affine map: Do nothing
1944
// Note that we do not map the weights (yet).
1946
// Take directional components
1947
for(int k = 0; k < 1; k++)
1948
result += values[k]*D[i][0][k];
1949
// Multiply by weights
1955
/// Evaluate linear functionals for all dofs on the function f
1956
virtual void evaluate_dofs(double* values,
1957
const ufc::function& f,
1958
const ufc::cell& c) const
1960
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1963
/// Interpolate vertex values from dof values
1964
virtual void interpolate_vertex_values(double* vertex_values,
1965
const double* dof_values,
1966
const ufc::cell& c) const
1968
// Evaluate at vertices and use affine mapping
1969
vertex_values[0] = dof_values[0];
1970
vertex_values[1] = dof_values[1];
1971
vertex_values[2] = dof_values[2];
1974
/// Return the number of sub elements (for a mixed element)
1975
virtual unsigned int num_sub_elements() const
1980
/// Create a new finite element for sub element i (for a mixed element)
1981
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1983
return new UFC_Poisson2D_2LinearForm_finite_element_0();
1988
/// This class defines the interface for a finite element.
1990
class UFC_Poisson2D_2LinearForm_finite_element_1: public ufc::finite_element
1995
UFC_Poisson2D_2LinearForm_finite_element_1() : ufc::finite_element()
2001
virtual ~UFC_Poisson2D_2LinearForm_finite_element_1()
2006
/// Return a string identifying the finite element
2007
virtual const char* signature() const
2009
return "FiniteElement('Lagrange', 'triangle', 2)";
2012
/// Return the cell shape
2013
virtual ufc::shape cell_shape() const
2015
return ufc::triangle;
2018
/// Return the dimension of the finite element function space
2019
virtual unsigned int space_dimension() const
2024
/// Return the rank of the value space
2025
virtual unsigned int value_rank() const
2030
/// Return the dimension of the value space for axis i
2031
virtual unsigned int value_dimension(unsigned int i) const
2036
/// Evaluate basis function i at given point in cell
2037
virtual void evaluate_basis(unsigned int i,
2039
const double* coordinates,
2040
const ufc::cell& c) const
2042
// Extract vertex coordinates
2043
const double * const * element_coordinates = c.coordinates;
2045
// Compute Jacobian of affine map from reference cell
2046
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2047
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2048
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2049
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2051
// Compute determinant of Jacobian
2052
const double detJ = J_00*J_11 - J_01*J_10;
2054
// Compute inverse of Jacobian
2056
// Get coordinates and map to the reference (UFC) element
2057
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2058
element_coordinates[0][0]*element_coordinates[2][1] +\
2059
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2060
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2061
element_coordinates[1][0]*element_coordinates[0][1] -\
2062
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2064
// Map coordinates to the reference square
2065
if (std::abs(y - 1.0) < 1e-14)
2068
x = 2.0 *x/(1.0 - y) - 1.0;
2074
// Map degree of freedom to element degree of freedom
2075
const unsigned int dof = i;
2077
// Generate scalings
2078
const double scalings_y_0 = 1;
2079
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2080
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
2082
// Compute psitilde_a
2083
const double psitilde_a_0 = 1;
2084
const double psitilde_a_1 = x;
2085
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
2087
// Compute psitilde_bs
2088
const double psitilde_bs_0_0 = 1;
2089
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2090
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
2091
const double psitilde_bs_1_0 = 1;
2092
const double psitilde_bs_1_1 = 2.5*y + 1.5;
2093
const double psitilde_bs_2_0 = 1;
2095
// Compute basisvalues
2096
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2097
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2098
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2099
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
2100
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
2101
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
2103
// Table(s) of coefficients
2104
const static double coefficients0[6][6] = \
2105
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
2106
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
2107
{0, 0, 0.2, 0, 0, 0.163299316185545},
2108
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
2109
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
2110
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
2112
// Extract relevant coefficients
2113
const double coeff0_0 = coefficients0[dof][0];
2114
const double coeff0_1 = coefficients0[dof][1];
2115
const double coeff0_2 = coefficients0[dof][2];
2116
const double coeff0_3 = coefficients0[dof][3];
2117
const double coeff0_4 = coefficients0[dof][4];
2118
const double coeff0_5 = coefficients0[dof][5];
2121
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
2124
/// Evaluate all basis functions at given point in cell
2125
virtual void evaluate_basis_all(double* values,
2126
const double* coordinates,
2127
const ufc::cell& c) const
2129
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2132
/// Evaluate order n derivatives of basis function i at given point in cell
2133
virtual void evaluate_basis_derivatives(unsigned int i,
2136
const double* coordinates,
2137
const ufc::cell& c) const
2139
// Extract vertex coordinates
2140
const double * const * element_coordinates = c.coordinates;
2142
// Compute Jacobian of affine map from reference cell
2143
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2144
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2145
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2146
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2148
// Compute determinant of Jacobian
2149
const double detJ = J_00*J_11 - J_01*J_10;
2151
// Compute inverse of Jacobian
2153
// Get coordinates and map to the reference (UFC) element
2154
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2155
element_coordinates[0][0]*element_coordinates[2][1] +\
2156
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2157
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2158
element_coordinates[1][0]*element_coordinates[0][1] -\
2159
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2161
// Map coordinates to the reference square
2162
if (std::abs(y - 1.0) < 1e-14)
2165
x = 2.0 *x/(1.0 - y) - 1.0;
2168
// Compute number of derivatives
2169
unsigned int num_derivatives = 1;
2171
for (unsigned int j = 0; j < n; j++)
2172
num_derivatives *= 2;
2175
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2176
unsigned int **combinations = new unsigned int *[num_derivatives];
2178
for (unsigned int j = 0; j < num_derivatives; j++)
2180
combinations[j] = new unsigned int [n];
2181
for (unsigned int k = 0; k < n; k++)
2182
combinations[j][k] = 0;
2185
// Generate combinations of derivatives
2186
for (unsigned int row = 1; row < num_derivatives; row++)
2188
for (unsigned int num = 0; num < row; num++)
2190
for (unsigned int col = n-1; col+1 > 0; col--)
2192
if (combinations[row][col] + 1 > 1)
2193
combinations[row][col] = 0;
2196
combinations[row][col] += 1;
2203
// Compute inverse of Jacobian
2204
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2206
// Declare transformation matrix
2207
// Declare pointer to two dimensional array and initialise
2208
double **transform = new double *[num_derivatives];
2210
for (unsigned int j = 0; j < num_derivatives; j++)
2212
transform[j] = new double [num_derivatives];
2213
for (unsigned int k = 0; k < num_derivatives; k++)
2214
transform[j][k] = 1;
2217
// Construct transformation matrix
2218
for (unsigned int row = 0; row < num_derivatives; row++)
2220
for (unsigned int col = 0; col < num_derivatives; col++)
2222
for (unsigned int k = 0; k < n; k++)
2223
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2228
for (unsigned int j = 0; j < 1*num_derivatives; j++)
2231
// Map degree of freedom to element degree of freedom
2232
const unsigned int dof = i;
2234
// Generate scalings
2235
const double scalings_y_0 = 1;
2236
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2237
const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
2239
// Compute psitilde_a
2240
const double psitilde_a_0 = 1;
2241
const double psitilde_a_1 = x;
2242
const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
2244
// Compute psitilde_bs
2245
const double psitilde_bs_0_0 = 1;
2246
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2247
const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
2248
const double psitilde_bs_1_0 = 1;
2249
const double psitilde_bs_1_1 = 2.5*y + 1.5;
2250
const double psitilde_bs_2_0 = 1;
2252
// Compute basisvalues
2253
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2254
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2255
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2256
const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
2257
const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
2258
const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
2260
// Table(s) of coefficients
2261
const static double coefficients0[6][6] = \
2262
{{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582063, 0.0544331053951817},
2263
{0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582064, 0.0544331053951818},
2264
{0, 0, 0.2, 0, 0, 0.163299316185545},
2265
{0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
2266
{0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
2267
{0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
2269
// Interesting (new) part
2270
// Tables of derivatives of the polynomial base (transpose)
2271
const static double dmats0[6][6] = \
2272
{{0, 0, 0, 0, 0, 0},
2273
{4.89897948556636, 0, 0, 0, 0, 0},
2275
{0, 9.48683298050514, 0, 0, 0, 0},
2276
{4, 0, 7.07106781186548, 0, 0, 0},
2277
{0, 0, 0, 0, 0, 0}};
2279
const static double dmats1[6][6] = \
2280
{{0, 0, 0, 0, 0, 0},
2281
{2.44948974278318, 0, 0, 0, 0, 0},
2282
{4.24264068711928, 0, 0, 0, 0, 0},
2283
{2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
2284
{2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
2285
{-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
2287
// Compute reference derivatives
2288
// Declare pointer to array of derivatives on FIAT element
2289
double *derivatives = new double [num_derivatives];
2291
// Declare coefficients
2292
double coeff0_0 = 0;
2293
double coeff0_1 = 0;
2294
double coeff0_2 = 0;
2295
double coeff0_3 = 0;
2296
double coeff0_4 = 0;
2297
double coeff0_5 = 0;
2299
// Declare new coefficients
2300
double new_coeff0_0 = 0;
2301
double new_coeff0_1 = 0;
2302
double new_coeff0_2 = 0;
2303
double new_coeff0_3 = 0;
2304
double new_coeff0_4 = 0;
2305
double new_coeff0_5 = 0;
2307
// Loop possible derivatives
2308
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2310
// Get values from coefficients array
2311
new_coeff0_0 = coefficients0[dof][0];
2312
new_coeff0_1 = coefficients0[dof][1];
2313
new_coeff0_2 = coefficients0[dof][2];
2314
new_coeff0_3 = coefficients0[dof][3];
2315
new_coeff0_4 = coefficients0[dof][4];
2316
new_coeff0_5 = coefficients0[dof][5];
2318
// Loop derivative order
2319
for (unsigned int j = 0; j < n; j++)
2321
// Update old coefficients
2322
coeff0_0 = new_coeff0_0;
2323
coeff0_1 = new_coeff0_1;
2324
coeff0_2 = new_coeff0_2;
2325
coeff0_3 = new_coeff0_3;
2326
coeff0_4 = new_coeff0_4;
2327
coeff0_5 = new_coeff0_5;
2329
if(combinations[deriv_num][j] == 0)
2331
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
2332
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
2333
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
2334
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
2335
new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
2336
new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
2338
if(combinations[deriv_num][j] == 1)
2340
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
2341
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
2342
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
2343
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
2344
new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
2345
new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
2349
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2350
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
2353
// Transform derivatives back to physical element
2354
for (unsigned int row = 0; row < num_derivatives; row++)
2356
for (unsigned int col = 0; col < num_derivatives; col++)
2358
values[row] += transform[row][col]*derivatives[col];
2361
// Delete pointer to array of derivatives on FIAT element
2362
delete [] derivatives;
2364
// Delete pointer to array of combinations of derivatives and transform
2365
for (unsigned int row = 0; row < num_derivatives; row++)
2367
delete [] combinations[row];
2368
delete [] transform[row];
2371
delete [] combinations;
2372
delete [] transform;
2375
/// Evaluate order n derivatives of all basis functions at given point in cell
2376
virtual void evaluate_basis_derivatives_all(unsigned int n,
2378
const double* coordinates,
2379
const ufc::cell& c) const
2381
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2384
/// Evaluate linear functional for dof i on the function f
2385
virtual double evaluate_dof(unsigned int i,
2386
const ufc::function& f,
2387
const ufc::cell& c) const
2389
// The reference points, direction and weights:
2390
const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
2391
const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
2392
const static double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
2394
const double * const * x = c.coordinates;
2395
double result = 0.0;
2396
// Iterate over the points:
2397
// Evaluate basis functions for affine mapping
2398
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2399
const double w1 = X[i][0][0];
2400
const double w2 = X[i][0][1];
2402
// Compute affine mapping y = F(X)
2404
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2405
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2407
// Evaluate function at physical points
2409
f.evaluate(values, y, c);
2411
// Map function values using appropriate mapping
2412
// Affine map: Do nothing
2414
// Note that we do not map the weights (yet).
2416
// Take directional components
2417
for(int k = 0; k < 1; k++)
2418
result += values[k]*D[i][0][k];
2419
// Multiply by weights
2425
/// Evaluate linear functionals for all dofs on the function f
2426
virtual void evaluate_dofs(double* values,
2427
const ufc::function& f,
2428
const ufc::cell& c) const
2430
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2433
/// Interpolate vertex values from dof values
2434
virtual void interpolate_vertex_values(double* vertex_values,
2435
const double* dof_values,
2436
const ufc::cell& c) const
2438
// Evaluate at vertices and use affine mapping
2439
vertex_values[0] = dof_values[0];
2440
vertex_values[1] = dof_values[1];
2441
vertex_values[2] = dof_values[2];
2444
/// Return the number of sub elements (for a mixed element)
2445
virtual unsigned int num_sub_elements() const
2450
/// Create a new finite element for sub element i (for a mixed element)
2451
virtual ufc::finite_element* create_sub_element(unsigned int i) const
2453
return new UFC_Poisson2D_2LinearForm_finite_element_1();
2458
/// This class defines the interface for a local-to-global mapping of
2459
/// degrees of freedom (dofs).
2461
class UFC_Poisson2D_2LinearForm_dof_map_0: public ufc::dof_map
2465
unsigned int __global_dimension;
2470
UFC_Poisson2D_2LinearForm_dof_map_0() : ufc::dof_map()
2472
__global_dimension = 0;
2476
virtual ~UFC_Poisson2D_2LinearForm_dof_map_0()
2481
/// Return a string identifying the dof map
2482
virtual const char* signature() const
2484
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
2487
/// Return true iff mesh entities of topological dimension d are needed
2488
virtual bool needs_mesh_entities(unsigned int d) const
2505
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2506
virtual bool init_mesh(const ufc::mesh& m)
2508
__global_dimension = m.num_entities[0] + m.num_entities[1];
2512
/// Initialize dof map for given cell
2513
virtual void init_cell(const ufc::mesh& m,
2519
/// Finish initialization of dof map for cells
2520
virtual void init_cell_finalize()
2525
/// Return the dimension of the global finite element function space
2526
virtual unsigned int global_dimension() const
2528
return __global_dimension;
2531
/// Return the dimension of the local finite element function space
2532
virtual unsigned int local_dimension() const
2537
// Return the geometric dimension of the coordinates this dof map provides
2538
virtual unsigned int geometric_dimension() const
2543
/// Return the number of dofs on each cell facet
2544
virtual unsigned int num_facet_dofs() const
2549
/// Return the number of dofs associated with each cell entity of dimension d
2550
virtual unsigned int num_entity_dofs(unsigned int d) const
2552
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2555
/// Tabulate the local-to-global mapping of dofs on a cell
2556
virtual void tabulate_dofs(unsigned int* dofs,
2558
const ufc::cell& c) const
2560
dofs[0] = c.entity_indices[0][0];
2561
dofs[1] = c.entity_indices[0][1];
2562
dofs[2] = c.entity_indices[0][2];
2563
unsigned int offset = m.num_entities[0];
2564
dofs[3] = offset + c.entity_indices[1][0];
2565
dofs[4] = offset + c.entity_indices[1][1];
2566
dofs[5] = offset + c.entity_indices[1][2];
2569
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2570
virtual void tabulate_facet_dofs(unsigned int* dofs,
2571
unsigned int facet) const
2593
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2594
virtual void tabulate_entity_dofs(unsigned int* dofs,
2595
unsigned int d, unsigned int i) const
2597
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2600
/// Tabulate the coordinates of all dofs on a cell
2601
virtual void tabulate_coordinates(double** coordinates,
2602
const ufc::cell& c) const
2604
const double * const * x = c.coordinates;
2605
coordinates[0][0] = x[0][0];
2606
coordinates[0][1] = x[0][1];
2607
coordinates[1][0] = x[1][0];
2608
coordinates[1][1] = x[1][1];
2609
coordinates[2][0] = x[2][0];
2610
coordinates[2][1] = x[2][1];
2611
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
2612
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
2613
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
2614
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
2615
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
2616
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
2619
/// Return the number of sub dof maps (for a mixed element)
2620
virtual unsigned int num_sub_dof_maps() const
2625
/// Create a new dof_map for sub dof map i (for a mixed element)
2626
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2628
return new UFC_Poisson2D_2LinearForm_dof_map_0();
2633
/// This class defines the interface for a local-to-global mapping of
2634
/// degrees of freedom (dofs).
2636
class UFC_Poisson2D_2LinearForm_dof_map_1: public ufc::dof_map
2640
unsigned int __global_dimension;
2645
UFC_Poisson2D_2LinearForm_dof_map_1() : ufc::dof_map()
2647
__global_dimension = 0;
2651
virtual ~UFC_Poisson2D_2LinearForm_dof_map_1()
2656
/// Return a string identifying the dof map
2657
virtual const char* signature() const
2659
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
2662
/// Return true iff mesh entities of topological dimension d are needed
2663
virtual bool needs_mesh_entities(unsigned int d) const
2680
/// Initialize dof map for mesh (return true iff init_cell() is needed)
2681
virtual bool init_mesh(const ufc::mesh& m)
2683
__global_dimension = m.num_entities[0] + m.num_entities[1];
2687
/// Initialize dof map for given cell
2688
virtual void init_cell(const ufc::mesh& m,
2694
/// Finish initialization of dof map for cells
2695
virtual void init_cell_finalize()
2700
/// Return the dimension of the global finite element function space
2701
virtual unsigned int global_dimension() const
2703
return __global_dimension;
2706
/// Return the dimension of the local finite element function space
2707
virtual unsigned int local_dimension() const
2712
// Return the geometric dimension of the coordinates this dof map provides
2713
virtual unsigned int geometric_dimension() const
2718
/// Return the number of dofs on each cell facet
2719
virtual unsigned int num_facet_dofs() const
2724
/// Return the number of dofs associated with each cell entity of dimension d
2725
virtual unsigned int num_entity_dofs(unsigned int d) const
2727
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2730
/// Tabulate the local-to-global mapping of dofs on a cell
2731
virtual void tabulate_dofs(unsigned int* dofs,
2733
const ufc::cell& c) const
2735
dofs[0] = c.entity_indices[0][0];
2736
dofs[1] = c.entity_indices[0][1];
2737
dofs[2] = c.entity_indices[0][2];
2738
unsigned int offset = m.num_entities[0];
2739
dofs[3] = offset + c.entity_indices[1][0];
2740
dofs[4] = offset + c.entity_indices[1][1];
2741
dofs[5] = offset + c.entity_indices[1][2];
2744
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
2745
virtual void tabulate_facet_dofs(unsigned int* dofs,
2746
unsigned int facet) const
2768
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
2769
virtual void tabulate_entity_dofs(unsigned int* dofs,
2770
unsigned int d, unsigned int i) const
2772
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2775
/// Tabulate the coordinates of all dofs on a cell
2776
virtual void tabulate_coordinates(double** coordinates,
2777
const ufc::cell& c) const
2779
const double * const * x = c.coordinates;
2780
coordinates[0][0] = x[0][0];
2781
coordinates[0][1] = x[0][1];
2782
coordinates[1][0] = x[1][0];
2783
coordinates[1][1] = x[1][1];
2784
coordinates[2][0] = x[2][0];
2785
coordinates[2][1] = x[2][1];
2786
coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
2787
coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
2788
coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
2789
coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
2790
coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
2791
coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
2794
/// Return the number of sub dof maps (for a mixed element)
2795
virtual unsigned int num_sub_dof_maps() const
2800
/// Create a new dof_map for sub dof map i (for a mixed element)
2801
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
2803
return new UFC_Poisson2D_2LinearForm_dof_map_1();
2808
/// This class defines the interface for the tabulation of the cell
2809
/// tensor corresponding to the local contribution to a form from
2810
/// the integral over a cell.
2812
class UFC_Poisson2D_2LinearForm_cell_integral_0: public ufc::cell_integral
2817
UFC_Poisson2D_2LinearForm_cell_integral_0() : ufc::cell_integral()
2823
virtual ~UFC_Poisson2D_2LinearForm_cell_integral_0()
2828
/// Tabulate the tensor for the contribution from a local cell
2829
virtual void tabulate_tensor(double* A,
2830
const double * const * w,
2831
const ufc::cell& c) const
2833
// Extract vertex coordinates
2834
const double * const * x = c.coordinates;
2836
// Compute Jacobian of affine map from reference cell
2837
const double J_00 = x[1][0] - x[0][0];
2838
const double J_01 = x[2][0] - x[0][0];
2839
const double J_10 = x[1][1] - x[0][1];
2840
const double J_11 = x[2][1] - x[0][1];
2842
// Compute determinant of Jacobian
2843
double detJ = J_00*J_11 - J_01*J_10;
2845
// Compute inverse of Jacobian
2848
const double det = std::abs(detJ);
2850
// Number of operations to compute element tensor = 48
2851
// Compute coefficients
2852
const double c0_0_0_0 = w[0][0];
2853
const double c0_0_0_1 = w[0][1];
2854
const double c0_0_0_2 = w[0][2];
2855
const double c0_0_0_3 = w[0][3];
2856
const double c0_0_0_4 = w[0][4];
2857
const double c0_0_0_5 = w[0][5];
2859
// Compute geometry tensors
2860
// Number of operations to compute decalrations = 6
2861
const double G0_0 = det*c0_0_0_0;
2862
const double G0_1 = det*c0_0_0_1;
2863
const double G0_2 = det*c0_0_0_2;
2864
const double G0_3 = det*c0_0_0_3;
2865
const double G0_4 = det*c0_0_0_4;
2866
const double G0_5 = det*c0_0_0_5;
2868
// Compute element tensor
2869
// Number of operations to compute tensor = 42
2870
A[0] = 0.0166666666666666*G0_0 - 0.00277777777777777*G0_1 - 0.00277777777777778*G0_2 - 0.0111111111111111*G0_3;
2871
A[1] = -0.00277777777777777*G0_0 + 0.0166666666666666*G0_1 - 0.00277777777777777*G0_2 - 0.0111111111111111*G0_4;
2872
A[2] = -0.00277777777777778*G0_0 - 0.00277777777777777*G0_1 + 0.0166666666666666*G0_2 - 0.0111111111111111*G0_5;
2873
A[3] = -0.0111111111111111*G0_0 + 0.0888888888888888*G0_3 + 0.0444444444444444*G0_4 + 0.0444444444444444*G0_5;
2874
A[4] = -0.0111111111111111*G0_1 + 0.0444444444444444*G0_3 + 0.0888888888888888*G0_4 + 0.0444444444444444*G0_5;
2875
A[5] = -0.0111111111111111*G0_2 + 0.0444444444444444*G0_3 + 0.0444444444444444*G0_4 + 0.0888888888888888*G0_5;
2880
/// This class defines the interface for the assembly of the global
2881
/// tensor corresponding to a form with r + n arguments, that is, a
2884
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2886
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2887
/// global tensor A is defined by
2889
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2891
/// where each argument Vj represents the application to the
2892
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2893
/// fixed functions (coefficients).
2895
class UFC_Poisson2D_2LinearForm: public ufc::form
2900
UFC_Poisson2D_2LinearForm() : ufc::form()
2906
virtual ~UFC_Poisson2D_2LinearForm()
2911
/// Return a string identifying the form
2912
virtual const char* signature() const
2914
return "w0_a0[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5]*va0[0, 1, 2, 3, 4, 5]*dX(0)";
2917
/// Return the rank of the global tensor (r)
2918
virtual unsigned int rank() const
2923
/// Return the number of coefficients (n)
2924
virtual unsigned int num_coefficients() const
2929
/// Return the number of cell integrals
2930
virtual unsigned int num_cell_integrals() const
2935
/// Return the number of exterior facet integrals
2936
virtual unsigned int num_exterior_facet_integrals() const
2941
/// Return the number of interior facet integrals
2942
virtual unsigned int num_interior_facet_integrals() const
2947
/// Create a new finite element for argument function i
2948
virtual ufc::finite_element* create_finite_element(unsigned int i) const
2953
return new UFC_Poisson2D_2LinearForm_finite_element_0();
2956
return new UFC_Poisson2D_2LinearForm_finite_element_1();
2962
/// Create a new dof map for argument function i
2963
virtual ufc::dof_map* create_dof_map(unsigned int i) const
2968
return new UFC_Poisson2D_2LinearForm_dof_map_0();
2971
return new UFC_Poisson2D_2LinearForm_dof_map_1();
2977
/// Create a new cell integral on sub domain i
2978
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
2980
return new UFC_Poisson2D_2LinearForm_cell_integral_0();
2983
/// Create a new exterior facet integral on sub domain i
2984
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
2989
/// Create a new interior facet integral on sub domain i
2990
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
2999
#include <dolfin/fem/Form.h>
3000
#include <dolfin/fem/FiniteElement.h>
3001
#include <dolfin/fem/DofMap.h>
3002
#include <dolfin/function/Coefficient.h>
3003
#include <dolfin/function/Function.h>
3004
#include <dolfin/function/FunctionSpace.h>
3006
class Poisson2D_2BilinearFormFunctionSpace0 : public dolfin::FunctionSpace
3010
Poisson2D_2BilinearFormFunctionSpace0(const dolfin::Mesh& mesh)
3011
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3012
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3013
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3020
class Poisson2D_2BilinearFormFunctionSpace1 : public dolfin::FunctionSpace
3024
Poisson2D_2BilinearFormFunctionSpace1(const dolfin::Mesh& mesh)
3025
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3026
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3027
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3034
class Poisson2D_2LinearFormFunctionSpace0 : public dolfin::FunctionSpace
3038
Poisson2D_2LinearFormFunctionSpace0(const dolfin::Mesh& mesh)
3039
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3040
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3041
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3048
class Poisson2D_2LinearFormCoefficientSpace0 : public dolfin::FunctionSpace
3052
Poisson2D_2LinearFormCoefficientSpace0(const dolfin::Mesh& mesh)
3053
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3054
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3055
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3062
class Poisson2D_2TestSpace : public dolfin::FunctionSpace
3066
Poisson2D_2TestSpace(const dolfin::Mesh& mesh)
3067
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3068
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3069
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3076
class Poisson2D_2TrialSpace : public dolfin::FunctionSpace
3080
Poisson2D_2TrialSpace(const dolfin::Mesh& mesh)
3081
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3082
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3083
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3090
class Poisson2D_2CoefficientSpace : public dolfin::FunctionSpace
3094
Poisson2D_2CoefficientSpace(const dolfin::Mesh& mesh)
3095
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3096
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3097
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3104
class Poisson2D_2FunctionSpace : public dolfin::FunctionSpace
3108
Poisson2D_2FunctionSpace(const dolfin::Mesh& mesh)
3109
: dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
3110
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Poisson2D_2LinearForm_finite_element_1()))),
3111
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Poisson2D_2LinearForm_dof_map_1()), mesh)))
3118
class Poisson2D_2BilinearForm : public dolfin::Form
3122
// Create form on given function space(s)
3123
Poisson2D_2BilinearForm(const dolfin::FunctionSpace& V0, const dolfin::FunctionSpace& V1) : dolfin::Form()
3125
boost::shared_ptr<const dolfin::FunctionSpace> _V0(&V0, dolfin::NoDeleter<const dolfin::FunctionSpace>());
3126
_function_spaces.push_back(_V0);
3127
boost::shared_ptr<const dolfin::FunctionSpace> _V1(&V1, dolfin::NoDeleter<const dolfin::FunctionSpace>());
3128
_function_spaces.push_back(_V1);
3130
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_Poisson2D_2BilinearForm());
3133
// Create form on given function space(s) (shared data)
3134
Poisson2D_2BilinearForm(boost::shared_ptr<const dolfin::FunctionSpace> V0, boost::shared_ptr<const dolfin::FunctionSpace> V1) : dolfin::Form()
3136
_function_spaces.push_back(V0);
3137
_function_spaces.push_back(V1);
3139
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_Poisson2D_2BilinearForm());
3143
~Poisson2D_2BilinearForm() {}
3147
class Poisson2D_2LinearFormCoefficient0 : public dolfin::Coefficient
3152
Poisson2D_2LinearFormCoefficient0(dolfin::Form& form) : dolfin::Coefficient(form) {}
3155
~Poisson2D_2LinearFormCoefficient0() {}
3157
// Attach function to coefficient
3158
const Poisson2D_2LinearFormCoefficient0& operator= (dolfin::Function& v)
3164
/// Create function space for coefficient
3165
const dolfin::FunctionSpace* create_function_space() const
3167
return new Poisson2D_2LinearFormCoefficientSpace0(form.mesh());
3170
/// Return coefficient number
3171
dolfin::uint number() const
3176
/// Return coefficient name
3177
virtual std::string name() const
3183
class Poisson2D_2LinearForm : public dolfin::Form
3187
// Create form on given function space(s)
3188
Poisson2D_2LinearForm(const dolfin::FunctionSpace& V0) : dolfin::Form(), f(*this)
3190
boost::shared_ptr<const dolfin::FunctionSpace> _V0(&V0, dolfin::NoDeleter<const dolfin::FunctionSpace>());
3191
_function_spaces.push_back(_V0);
3193
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
3195
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_Poisson2D_2LinearForm());
3198
// Create form on given function space(s) (shared data)
3199
Poisson2D_2LinearForm(boost::shared_ptr<const dolfin::FunctionSpace> V0) : dolfin::Form(), f(*this)
3201
_function_spaces.push_back(V0);
3203
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
3205
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_Poisson2D_2LinearForm());
3208
// Create form on given function space(s) with given coefficient(s)
3209
Poisson2D_2LinearForm(const dolfin::FunctionSpace& V0, dolfin::Function& w0) : dolfin::Form(), f(*this)
3211
boost::shared_ptr<const dolfin::FunctionSpace> _V0(&V0, dolfin::NoDeleter<const dolfin::FunctionSpace>());
3212
_function_spaces.push_back(_V0);
3214
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
3218
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_Poisson2D_2LinearForm());
3221
// Create form on given function space(s) with given coefficient(s) (shared data)
3222
Poisson2D_2LinearForm(boost::shared_ptr<const dolfin::FunctionSpace> V0, dolfin::Function& w0) : dolfin::Form(), f(*this)
3224
_function_spaces.push_back(V0);
3226
_coefficients.push_back(boost::shared_ptr<const dolfin::Function>(static_cast<const dolfin::Function*>(0)));
3230
_ufc_form = boost::shared_ptr<const ufc::form>(new UFC_Poisson2D_2LinearForm());
3234
~Poisson2D_2LinearForm() {}
3237
Poisson2D_2LinearFormCoefficient0 f;