1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.7.0.
4
// Warning: This code was generated with the option '-l dolfin'
5
// and contains DOLFIN-specific wrappers that depend on DOLFIN.
15
/// This class defines the interface for a finite element.
17
class p1_0_finite_element_0: public ufc::finite_element
22
p1_0_finite_element_0() : ufc::finite_element()
28
virtual ~p1_0_finite_element_0()
33
/// Return a string identifying the finite element
34
virtual const char* signature() const
36
return "FiniteElement('Lagrange', 'triangle', 1)";
39
/// Return the cell shape
40
virtual ufc::shape cell_shape() const
45
/// Return the dimension of the finite element function space
46
virtual unsigned int space_dimension() const
51
/// Return the rank of the value space
52
virtual unsigned int value_rank() const
57
/// Return the dimension of the value space for axis i
58
virtual unsigned int value_dimension(unsigned int i) const
63
/// Evaluate basis function i at given point in cell
64
virtual void evaluate_basis(unsigned int i,
66
const double* coordinates,
67
const ufc::cell& c) const
69
// Extract vertex coordinates
70
const double * const * element_coordinates = c.coordinates;
72
// Compute Jacobian of affine map from reference cell
73
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
74
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
75
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
76
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
78
// Compute determinant of Jacobian
79
const double detJ = J_00*J_11 - J_01*J_10;
81
// Compute inverse of Jacobian
83
// Get coordinates and map to the reference (UFC) element
84
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
85
element_coordinates[0][0]*element_coordinates[2][1] +\
86
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
87
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
88
element_coordinates[1][0]*element_coordinates[0][1] -\
89
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
91
// Map coordinates to the reference square
92
if (std::abs(y - 1.0) < 1e-14)
95
x = 2.0 *x/(1.0 - y) - 1.0;
101
// Map degree of freedom to element degree of freedom
102
const unsigned int dof = i;
105
const double scalings_y_0 = 1;
106
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
108
// Compute psitilde_a
109
const double psitilde_a_0 = 1;
110
const double psitilde_a_1 = x;
112
// Compute psitilde_bs
113
const double psitilde_bs_0_0 = 1;
114
const double psitilde_bs_0_1 = 1.5*y + 0.5;
115
const double psitilde_bs_1_0 = 1;
117
// Compute basisvalues
118
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
119
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
120
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
122
// Table(s) of coefficients
123
static const double coefficients0[3][3] = \
124
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
125
{0.471404520791032, 0.288675134594813, -0.166666666666667},
126
{0.471404520791032, 0, 0.333333333333333}};
128
// Extract relevant coefficients
129
const double coeff0_0 = coefficients0[dof][0];
130
const double coeff0_1 = coefficients0[dof][1];
131
const double coeff0_2 = coefficients0[dof][2];
134
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
137
/// Evaluate all basis functions at given point in cell
138
virtual void evaluate_basis_all(double* values,
139
const double* coordinates,
140
const ufc::cell& c) const
142
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
145
/// Evaluate order n derivatives of basis function i at given point in cell
146
virtual void evaluate_basis_derivatives(unsigned int i,
149
const double* coordinates,
150
const ufc::cell& c) const
152
// Extract vertex coordinates
153
const double * const * element_coordinates = c.coordinates;
155
// Compute Jacobian of affine map from reference cell
156
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
157
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
158
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
159
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
161
// Compute determinant of Jacobian
162
const double detJ = J_00*J_11 - J_01*J_10;
164
// Compute inverse of Jacobian
166
// Get coordinates and map to the reference (UFC) element
167
double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
168
element_coordinates[0][0]*element_coordinates[2][1] +\
169
J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
170
double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
171
element_coordinates[1][0]*element_coordinates[0][1] -\
172
J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
174
// Map coordinates to the reference square
175
if (std::abs(y - 1.0) < 1e-14)
178
x = 2.0 *x/(1.0 - y) - 1.0;
181
// Compute number of derivatives
182
unsigned int num_derivatives = 1;
184
for (unsigned int j = 0; j < n; j++)
185
num_derivatives *= 2;
188
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
189
unsigned int **combinations = new unsigned int *[num_derivatives];
191
for (unsigned int j = 0; j < num_derivatives; j++)
193
combinations[j] = new unsigned int [n];
194
for (unsigned int k = 0; k < n; k++)
195
combinations[j][k] = 0;
198
// Generate combinations of derivatives
199
for (unsigned int row = 1; row < num_derivatives; row++)
201
for (unsigned int num = 0; num < row; num++)
203
for (unsigned int col = n-1; col+1 > 0; col--)
205
if (combinations[row][col] + 1 > 1)
206
combinations[row][col] = 0;
209
combinations[row][col] += 1;
216
// Compute inverse of Jacobian
217
const double Jinv[2][2] = {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
219
// Declare transformation matrix
220
// Declare pointer to two dimensional array and initialise
221
double **transform = new double *[num_derivatives];
223
for (unsigned int j = 0; j < num_derivatives; j++)
225
transform[j] = new double [num_derivatives];
226
for (unsigned int k = 0; k < num_derivatives; k++)
230
// Construct transformation matrix
231
for (unsigned int row = 0; row < num_derivatives; row++)
233
for (unsigned int col = 0; col < num_derivatives; col++)
235
for (unsigned int k = 0; k < n; k++)
236
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
241
for (unsigned int j = 0; j < 1*num_derivatives; j++)
244
// Map degree of freedom to element degree of freedom
245
const unsigned int dof = i;
248
const double scalings_y_0 = 1;
249
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
251
// Compute psitilde_a
252
const double psitilde_a_0 = 1;
253
const double psitilde_a_1 = x;
255
// Compute psitilde_bs
256
const double psitilde_bs_0_0 = 1;
257
const double psitilde_bs_0_1 = 1.5*y + 0.5;
258
const double psitilde_bs_1_0 = 1;
260
// Compute basisvalues
261
const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
262
const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
263
const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
265
// Table(s) of coefficients
266
static const double coefficients0[3][3] = \
267
{{0.471404520791032, -0.288675134594813, -0.166666666666667},
268
{0.471404520791032, 0.288675134594813, -0.166666666666667},
269
{0.471404520791032, 0, 0.333333333333333}};
271
// Interesting (new) part
272
// Tables of derivatives of the polynomial base (transpose)
273
static const double dmats0[3][3] = \
275
{4.89897948556636, 0, 0},
278
static const double dmats1[3][3] = \
280
{2.44948974278318, 0, 0},
281
{4.24264068711928, 0, 0}};
283
// Compute reference derivatives
284
// Declare pointer to array of derivatives on FIAT element
285
double *derivatives = new double [num_derivatives];
287
// Declare coefficients
292
// Declare new coefficients
293
double new_coeff0_0 = 0;
294
double new_coeff0_1 = 0;
295
double new_coeff0_2 = 0;
297
// Loop possible derivatives
298
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
300
// Get values from coefficients array
301
new_coeff0_0 = coefficients0[dof][0];
302
new_coeff0_1 = coefficients0[dof][1];
303
new_coeff0_2 = coefficients0[dof][2];
305
// Loop derivative order
306
for (unsigned int j = 0; j < n; j++)
308
// Update old coefficients
309
coeff0_0 = new_coeff0_0;
310
coeff0_1 = new_coeff0_1;
311
coeff0_2 = new_coeff0_2;
313
if(combinations[deriv_num][j] == 0)
315
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
316
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
317
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
319
if(combinations[deriv_num][j] == 1)
321
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
322
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
323
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
327
// Compute derivatives on reference element as dot product of coefficients and basisvalues
328
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
331
// Transform derivatives back to physical element
332
for (unsigned int row = 0; row < num_derivatives; row++)
334
for (unsigned int col = 0; col < num_derivatives; col++)
336
values[row] += transform[row][col]*derivatives[col];
339
// Delete pointer to array of derivatives on FIAT element
340
delete [] derivatives;
342
// Delete pointer to array of combinations of derivatives and transform
343
for (unsigned int row = 0; row < num_derivatives; row++)
345
delete [] combinations[row];
346
delete [] transform[row];
349
delete [] combinations;
353
/// Evaluate order n derivatives of all basis functions at given point in cell
354
virtual void evaluate_basis_derivatives_all(unsigned int n,
356
const double* coordinates,
357
const ufc::cell& c) const
359
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
362
/// Evaluate linear functional for dof i on the function f
363
virtual double evaluate_dof(unsigned int i,
364
const ufc::function& f,
365
const ufc::cell& c) const
367
// The reference points, direction and weights:
368
static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
369
static const double W[3][1] = {{1}, {1}, {1}};
370
static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
372
const double * const * x = c.coordinates;
374
// Iterate over the points:
375
// Evaluate basis functions for affine mapping
376
const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
377
const double w1 = X[i][0][0];
378
const double w2 = X[i][0][1];
380
// Compute affine mapping y = F(X)
382
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
383
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
385
// Evaluate function at physical points
387
f.evaluate(values, y, c);
389
// Map function values using appropriate mapping
390
// Affine map: Do nothing
392
// Note that we do not map the weights (yet).
394
// Take directional components
395
for(int k = 0; k < 1; k++)
396
result += values[k]*D[i][0][k];
397
// Multiply by weights
403
/// Evaluate linear functionals for all dofs on the function f
404
virtual void evaluate_dofs(double* values,
405
const ufc::function& f,
406
const ufc::cell& c) const
408
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
411
/// Interpolate vertex values from dof values
412
virtual void interpolate_vertex_values(double* vertex_values,
413
const double* dof_values,
414
const ufc::cell& c) const
416
// Evaluate at vertices and use affine mapping
417
vertex_values[0] = dof_values[0];
418
vertex_values[1] = dof_values[1];
419
vertex_values[2] = dof_values[2];
422
/// Return the number of sub elements (for a mixed element)
423
virtual unsigned int num_sub_elements() const
428
/// Create a new finite element for sub element i (for a mixed element)
429
virtual ufc::finite_element* create_sub_element(unsigned int i) const
431
return new p1_0_finite_element_0();
436
/// This class defines the interface for a local-to-global mapping of
437
/// degrees of freedom (dofs).
439
class p1_0_dof_map_0: public ufc::dof_map
443
unsigned int __global_dimension;
448
p1_0_dof_map_0() : ufc::dof_map()
450
__global_dimension = 0;
454
virtual ~p1_0_dof_map_0()
459
/// Return a string identifying the dof map
460
virtual const char* signature() const
462
return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
465
/// Return true iff mesh entities of topological dimension d are needed
466
virtual bool needs_mesh_entities(unsigned int d) const
483
/// Initialize dof map for mesh (return true iff init_cell() is needed)
484
virtual bool init_mesh(const ufc::mesh& m)
486
__global_dimension = m.num_entities[0];
490
/// Initialize dof map for given cell
491
virtual void init_cell(const ufc::mesh& m,
497
/// Finish initialization of dof map for cells
498
virtual void init_cell_finalize()
503
/// Return the dimension of the global finite element function space
504
virtual unsigned int global_dimension() const
506
return __global_dimension;
509
/// Return the dimension of the local finite element function space for a cell
510
virtual unsigned int local_dimension(const ufc::cell& c) const
515
/// Return the maximum dimension of the local finite element function space
516
virtual unsigned int max_local_dimension() const
521
// Return the geometric dimension of the coordinates this dof map provides
522
virtual unsigned int geometric_dimension() const
527
/// Return the number of dofs on each cell facet
528
virtual unsigned int num_facet_dofs() const
533
/// Return the number of dofs associated with each cell entity of dimension d
534
virtual unsigned int num_entity_dofs(unsigned int d) const
536
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
539
/// Tabulate the local-to-global mapping of dofs on a cell
540
virtual void tabulate_dofs(unsigned int* dofs,
542
const ufc::cell& c) const
544
dofs[0] = c.entity_indices[0][0];
545
dofs[1] = c.entity_indices[0][1];
546
dofs[2] = c.entity_indices[0][2];
549
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
550
virtual void tabulate_facet_dofs(unsigned int* dofs,
551
unsigned int facet) const
570
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
571
virtual void tabulate_entity_dofs(unsigned int* dofs,
572
unsigned int d, unsigned int i) const
574
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
577
/// Tabulate the coordinates of all dofs on a cell
578
virtual void tabulate_coordinates(double** coordinates,
579
const ufc::cell& c) const
581
const double * const * x = c.coordinates;
582
coordinates[0][0] = x[0][0];
583
coordinates[0][1] = x[0][1];
584
coordinates[1][0] = x[1][0];
585
coordinates[1][1] = x[1][1];
586
coordinates[2][0] = x[2][0];
587
coordinates[2][1] = x[2][1];
590
/// Return the number of sub dof maps (for a mixed element)
591
virtual unsigned int num_sub_dof_maps() const
596
/// Create a new dof_map for sub dof map i (for a mixed element)
597
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
599
return new p1_0_dof_map_0();
604
/// This class defines the interface for the assembly of the global
605
/// tensor corresponding to a form with r + n arguments, that is, a
608
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
610
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
611
/// global tensor A is defined by
613
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
615
/// where each argument Vj represents the application to the
616
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
617
/// fixed functions (coefficients).
619
class p1_form_0: public ufc::form
624
p1_form_0() : ufc::form()
635
/// Return a string identifying the form
636
virtual const char* signature() const
641
/// Return the rank of the global tensor (r)
642
virtual unsigned int rank() const
647
/// Return the number of coefficients (n)
648
virtual unsigned int num_coefficients() const
653
/// Return the number of cell integrals
654
virtual unsigned int num_cell_integrals() const
659
/// Return the number of exterior facet integrals
660
virtual unsigned int num_exterior_facet_integrals() const
665
/// Return the number of interior facet integrals
666
virtual unsigned int num_interior_facet_integrals() const
671
/// Create a new finite element for argument function i
672
virtual ufc::finite_element* create_finite_element(unsigned int i) const
677
/// Create a new dof map for argument function i
678
virtual ufc::dof_map* create_dof_map(unsigned int i) const
683
/// Create a new cell integral on sub domain i
684
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
689
/// Create a new exterior facet integral on sub domain i
690
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
695
/// Create a new interior facet integral on sub domain i
696
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
705
// Standard library includes
709
#include <dolfin/common/NoDeleter.h>
710
#include <dolfin/fem/FiniteElement.h>
711
#include <dolfin/fem/DofMap.h>
712
#include <dolfin/fem/Form.h>
713
#include <dolfin/function/FunctionSpace.h>
714
#include <dolfin/function/GenericFunction.h>
715
#include <dolfin/function/CoefficientAssigner.h>
720
class Form_0_FunctionSpace_0: public dolfin::FunctionSpace
724
Form_0_FunctionSpace_0(const dolfin::Mesh& mesh):
725
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
726
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new p1_0_finite_element_0()))),
727
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new p1_0_dof_map_0()), dolfin::reference_to_no_delete_pointer(mesh))))
732
Form_0_FunctionSpace_0(dolfin::Mesh& mesh):
733
dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
734
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new p1_0_finite_element_0()))),
735
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new p1_0_dof_map_0()), dolfin::reference_to_no_delete_pointer(mesh))))
740
Form_0_FunctionSpace_0(boost::shared_ptr<dolfin::Mesh> mesh):
741
dolfin::FunctionSpace(mesh,
742
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new p1_0_finite_element_0()))),
743
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new p1_0_dof_map_0()), mesh)))
748
Form_0_FunctionSpace_0(boost::shared_ptr<const dolfin::Mesh> mesh):
749
dolfin::FunctionSpace(mesh,
750
boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new p1_0_finite_element_0()))),
751
boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new p1_0_dof_map_0()), mesh)))
757
~Form_0_FunctionSpace_0()
763
class Form_0: public dolfin::Form
768
Form_0(const dolfin::FunctionSpace& V0):
771
_function_spaces[0] = reference_to_no_delete_pointer(V0);
773
_ufc_form = boost::shared_ptr<const ufc::form>(new p1_form_0());
777
Form_0(boost::shared_ptr<const dolfin::FunctionSpace> V0):
780
_function_spaces[0] = V0;
782
_ufc_form = boost::shared_ptr<const ufc::form>(new p1_form_0());
789
/// Return the number of the coefficient with this name
790
virtual dolfin::uint coefficient_number(const std::string& name) const
793
dolfin::error("No coefficients.");
797
/// Return the name of the coefficient with this number
798
virtual std::string coefficient_name(dolfin::uint i) const
801
dolfin::error("No coefficients.");
806
typedef Form_0_FunctionSpace_0 TestSpace;
812
typedef Form_0 LinearForm;
813
typedef Form_0::TestSpace FunctionSpace;