1
// This code conforms with the UFC specification version 1.0
2
// and was automatically generated by FFC version 0.7.0.
4
#ifndef __HYPERELASTICITY_H
5
#define __HYPERELASTICITY_H
11
/// This class defines the interface for a finite element.
13
class hyperelasticity_0_finite_element_0_0: public ufc::finite_element
18
hyperelasticity_0_finite_element_0_0() : ufc::finite_element()
24
virtual ~hyperelasticity_0_finite_element_0_0()
29
/// Return a string identifying the finite element
30
virtual const char* signature() const
32
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
35
/// Return the cell shape
36
virtual ufc::shape cell_shape() const
38
return ufc::tetrahedron;
41
/// Return the dimension of the finite element function space
42
virtual unsigned int space_dimension() const
47
/// Return the rank of the value space
48
virtual unsigned int value_rank() const
53
/// Return the dimension of the value space for axis i
54
virtual unsigned int value_dimension(unsigned int i) const
59
/// Evaluate basis function i at given point in cell
60
virtual void evaluate_basis(unsigned int i,
62
const double* coordinates,
63
const ufc::cell& c) const
65
// Extract vertex coordinates
66
const double * const * element_coordinates = c.coordinates;
68
// Compute Jacobian of affine map from reference cell
69
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
70
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
71
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
72
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
73
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
74
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
75
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
76
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
77
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
79
// Compute sub determinants
80
const double d00 = J_11*J_22 - J_12*J_21;
81
const double d01 = J_12*J_20 - J_10*J_22;
82
const double d02 = J_10*J_21 - J_11*J_20;
84
const double d10 = J_02*J_21 - J_01*J_22;
85
const double d11 = J_00*J_22 - J_02*J_20;
86
const double d12 = J_01*J_20 - J_00*J_21;
88
const double d20 = J_01*J_12 - J_02*J_11;
89
const double d21 = J_02*J_10 - J_00*J_12;
90
const double d22 = J_00*J_11 - J_01*J_10;
92
// Compute determinant of Jacobian
93
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
95
// Compute inverse of Jacobian
98
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
99
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
100
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
102
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
103
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
104
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
106
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
107
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
108
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
110
// Get coordinates and map to the UFC reference element
111
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
112
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
113
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
115
// Map coordinates to the reference cube
116
if (std::abs(y + z - 1.0) < 1e-08)
119
x = -2.0 * x/(y + z - 1.0) - 1.0;
120
if (std::abs(z - 1.0) < 1e-08)
123
y = 2.0 * y/(1.0 - z) - 1.0;
129
// Map degree of freedom to element degree of freedom
130
const unsigned int dof = i;
133
const double scalings_y_0 = 1;
134
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
135
const double scalings_z_0 = 1;
136
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
138
// Compute psitilde_a
139
const double psitilde_a_0 = 1;
140
const double psitilde_a_1 = x;
142
// Compute psitilde_bs
143
const double psitilde_bs_0_0 = 1;
144
const double psitilde_bs_0_1 = 1.5*y + 0.5;
145
const double psitilde_bs_1_0 = 1;
147
// Compute psitilde_cs
148
const double psitilde_cs_00_0 = 1;
149
const double psitilde_cs_00_1 = 2*z + 1;
150
const double psitilde_cs_01_0 = 1;
151
const double psitilde_cs_10_0 = 1;
153
// Compute basisvalues
154
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
155
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
156
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
157
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
159
// Table(s) of coefficients
160
static const double coefficients0[4][4] = \
161
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
162
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
163
{0.288675135, 0, 0.210818511, -0.0745355992},
164
{0.288675135, 0, 0, 0.223606798}};
166
// Extract relevant coefficients
167
const double coeff0_0 = coefficients0[dof][0];
168
const double coeff0_1 = coefficients0[dof][1];
169
const double coeff0_2 = coefficients0[dof][2];
170
const double coeff0_3 = coefficients0[dof][3];
173
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
176
/// Evaluate all basis functions at given point in cell
177
virtual void evaluate_basis_all(double* values,
178
const double* coordinates,
179
const ufc::cell& c) const
181
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
184
/// Evaluate order n derivatives of basis function i at given point in cell
185
virtual void evaluate_basis_derivatives(unsigned int i,
188
const double* coordinates,
189
const ufc::cell& c) const
191
// Extract vertex coordinates
192
const double * const * element_coordinates = c.coordinates;
194
// Compute Jacobian of affine map from reference cell
195
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
196
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
197
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
198
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
199
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
200
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
201
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
202
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
203
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
205
// Compute sub determinants
206
const double d00 = J_11*J_22 - J_12*J_21;
207
const double d01 = J_12*J_20 - J_10*J_22;
208
const double d02 = J_10*J_21 - J_11*J_20;
210
const double d10 = J_02*J_21 - J_01*J_22;
211
const double d11 = J_00*J_22 - J_02*J_20;
212
const double d12 = J_01*J_20 - J_00*J_21;
214
const double d20 = J_01*J_12 - J_02*J_11;
215
const double d21 = J_02*J_10 - J_00*J_12;
216
const double d22 = J_00*J_11 - J_01*J_10;
218
// Compute determinant of Jacobian
219
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
221
// Compute inverse of Jacobian
224
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
225
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
226
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
228
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
229
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
230
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
232
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
233
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
234
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
236
// Get coordinates and map to the UFC reference element
237
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
238
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
239
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
241
// Map coordinates to the reference cube
242
if (std::abs(y + z - 1.0) < 1e-08)
245
x = -2.0 * x/(y + z - 1.0) - 1.0;
246
if (std::abs(z - 1.0) < 1e-08)
249
y = 2.0 * y/(1.0 - z) - 1.0;
252
// Compute number of derivatives
253
unsigned int num_derivatives = 1;
255
for (unsigned int j = 0; j < n; j++)
256
num_derivatives *= 3;
259
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
260
unsigned int **combinations = new unsigned int *[num_derivatives];
262
for (unsigned int j = 0; j < num_derivatives; j++)
264
combinations[j] = new unsigned int [n];
265
for (unsigned int k = 0; k < n; k++)
266
combinations[j][k] = 0;
269
// Generate combinations of derivatives
270
for (unsigned int row = 1; row < num_derivatives; row++)
272
for (unsigned int num = 0; num < row; num++)
274
for (unsigned int col = n-1; col+1 > 0; col--)
276
if (combinations[row][col] + 1 > 2)
277
combinations[row][col] = 0;
280
combinations[row][col] += 1;
287
// Compute inverse of Jacobian
288
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
290
// Declare transformation matrix
291
// Declare pointer to two dimensional array and initialise
292
double **transform = new double *[num_derivatives];
294
for (unsigned int j = 0; j < num_derivatives; j++)
296
transform[j] = new double [num_derivatives];
297
for (unsigned int k = 0; k < num_derivatives; k++)
301
// Construct transformation matrix
302
for (unsigned int row = 0; row < num_derivatives; row++)
304
for (unsigned int col = 0; col < num_derivatives; col++)
306
for (unsigned int k = 0; k < n; k++)
307
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
312
for (unsigned int j = 0; j < 1*num_derivatives; j++)
315
// Map degree of freedom to element degree of freedom
316
const unsigned int dof = i;
319
const double scalings_y_0 = 1;
320
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
321
const double scalings_z_0 = 1;
322
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
324
// Compute psitilde_a
325
const double psitilde_a_0 = 1;
326
const double psitilde_a_1 = x;
328
// Compute psitilde_bs
329
const double psitilde_bs_0_0 = 1;
330
const double psitilde_bs_0_1 = 1.5*y + 0.5;
331
const double psitilde_bs_1_0 = 1;
333
// Compute psitilde_cs
334
const double psitilde_cs_00_0 = 1;
335
const double psitilde_cs_00_1 = 2*z + 1;
336
const double psitilde_cs_01_0 = 1;
337
const double psitilde_cs_10_0 = 1;
339
// Compute basisvalues
340
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
341
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
342
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
343
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
345
// Table(s) of coefficients
346
static const double coefficients0[4][4] = \
347
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
348
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
349
{0.288675135, 0, 0.210818511, -0.0745355992},
350
{0.288675135, 0, 0, 0.223606798}};
352
// Interesting (new) part
353
// Tables of derivatives of the polynomial base (transpose)
354
static const double dmats0[4][4] = \
356
{6.32455532, 0, 0, 0},
360
static const double dmats1[4][4] = \
362
{3.16227766, 0, 0, 0},
363
{5.47722558, 0, 0, 0},
366
static const double dmats2[4][4] = \
368
{3.16227766, 0, 0, 0},
369
{1.82574186, 0, 0, 0},
370
{5.16397779, 0, 0, 0}};
372
// Compute reference derivatives
373
// Declare pointer to array of derivatives on FIAT element
374
double *derivatives = new double [num_derivatives];
376
// Declare coefficients
382
// Declare new coefficients
383
double new_coeff0_0 = 0;
384
double new_coeff0_1 = 0;
385
double new_coeff0_2 = 0;
386
double new_coeff0_3 = 0;
388
// Loop possible derivatives
389
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
391
// Get values from coefficients array
392
new_coeff0_0 = coefficients0[dof][0];
393
new_coeff0_1 = coefficients0[dof][1];
394
new_coeff0_2 = coefficients0[dof][2];
395
new_coeff0_3 = coefficients0[dof][3];
397
// Loop derivative order
398
for (unsigned int j = 0; j < n; j++)
400
// Update old coefficients
401
coeff0_0 = new_coeff0_0;
402
coeff0_1 = new_coeff0_1;
403
coeff0_2 = new_coeff0_2;
404
coeff0_3 = new_coeff0_3;
406
if(combinations[deriv_num][j] == 0)
408
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
409
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
410
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
411
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
413
if(combinations[deriv_num][j] == 1)
415
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
416
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
417
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
418
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
420
if(combinations[deriv_num][j] == 2)
422
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
423
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
424
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
425
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
429
// Compute derivatives on reference element as dot product of coefficients and basisvalues
430
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
433
// Transform derivatives back to physical element
434
for (unsigned int row = 0; row < num_derivatives; row++)
436
for (unsigned int col = 0; col < num_derivatives; col++)
438
values[row] += transform[row][col]*derivatives[col];
441
// Delete pointer to array of derivatives on FIAT element
442
delete [] derivatives;
444
// Delete pointer to array of combinations of derivatives and transform
445
for (unsigned int row = 0; row < num_derivatives; row++)
447
delete [] combinations[row];
448
delete [] transform[row];
451
delete [] combinations;
455
/// Evaluate order n derivatives of all basis functions at given point in cell
456
virtual void evaluate_basis_derivatives_all(unsigned int n,
458
const double* coordinates,
459
const ufc::cell& c) const
461
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
464
/// Evaluate linear functional for dof i on the function f
465
virtual double evaluate_dof(unsigned int i,
466
const ufc::function& f,
467
const ufc::cell& c) const
469
// The reference points, direction and weights:
470
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
471
static const double W[4][1] = {{1}, {1}, {1}, {1}};
472
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
474
const double * const * x = c.coordinates;
476
// Iterate over the points:
477
// Evaluate basis functions for affine mapping
478
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
479
const double w1 = X[i][0][0];
480
const double w2 = X[i][0][1];
481
const double w3 = X[i][0][2];
483
// Compute affine mapping y = F(X)
485
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
486
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
487
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
489
// Evaluate function at physical points
491
f.evaluate(values, y, c);
493
// Map function values using appropriate mapping
494
// Affine map: Do nothing
496
// Note that we do not map the weights (yet).
498
// Take directional components
499
for(int k = 0; k < 1; k++)
500
result += values[k]*D[i][0][k];
501
// Multiply by weights
507
/// Evaluate linear functionals for all dofs on the function f
508
virtual void evaluate_dofs(double* values,
509
const ufc::function& f,
510
const ufc::cell& c) const
512
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
515
/// Interpolate vertex values from dof values
516
virtual void interpolate_vertex_values(double* vertex_values,
517
const double* dof_values,
518
const ufc::cell& c) const
520
// Evaluate at vertices and use affine mapping
521
vertex_values[0] = dof_values[0];
522
vertex_values[1] = dof_values[1];
523
vertex_values[2] = dof_values[2];
524
vertex_values[3] = dof_values[3];
527
/// Return the number of sub elements (for a mixed element)
528
virtual unsigned int num_sub_elements() const
533
/// Create a new finite element for sub element i (for a mixed element)
534
virtual ufc::finite_element* create_sub_element(unsigned int i) const
536
return new hyperelasticity_0_finite_element_0_0();
541
/// This class defines the interface for a finite element.
543
class hyperelasticity_0_finite_element_0_1: public ufc::finite_element
548
hyperelasticity_0_finite_element_0_1() : ufc::finite_element()
554
virtual ~hyperelasticity_0_finite_element_0_1()
559
/// Return a string identifying the finite element
560
virtual const char* signature() const
562
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
565
/// Return the cell shape
566
virtual ufc::shape cell_shape() const
568
return ufc::tetrahedron;
571
/// Return the dimension of the finite element function space
572
virtual unsigned int space_dimension() const
577
/// Return the rank of the value space
578
virtual unsigned int value_rank() const
583
/// Return the dimension of the value space for axis i
584
virtual unsigned int value_dimension(unsigned int i) const
589
/// Evaluate basis function i at given point in cell
590
virtual void evaluate_basis(unsigned int i,
592
const double* coordinates,
593
const ufc::cell& c) const
595
// Extract vertex coordinates
596
const double * const * element_coordinates = c.coordinates;
598
// Compute Jacobian of affine map from reference cell
599
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
600
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
601
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
602
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
603
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
604
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
605
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
606
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
607
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
609
// Compute sub determinants
610
const double d00 = J_11*J_22 - J_12*J_21;
611
const double d01 = J_12*J_20 - J_10*J_22;
612
const double d02 = J_10*J_21 - J_11*J_20;
614
const double d10 = J_02*J_21 - J_01*J_22;
615
const double d11 = J_00*J_22 - J_02*J_20;
616
const double d12 = J_01*J_20 - J_00*J_21;
618
const double d20 = J_01*J_12 - J_02*J_11;
619
const double d21 = J_02*J_10 - J_00*J_12;
620
const double d22 = J_00*J_11 - J_01*J_10;
622
// Compute determinant of Jacobian
623
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
625
// Compute inverse of Jacobian
628
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
629
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
630
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
632
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
633
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
634
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
636
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
637
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
638
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
640
// Get coordinates and map to the UFC reference element
641
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
642
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
643
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
645
// Map coordinates to the reference cube
646
if (std::abs(y + z - 1.0) < 1e-08)
649
x = -2.0 * x/(y + z - 1.0) - 1.0;
650
if (std::abs(z - 1.0) < 1e-08)
653
y = 2.0 * y/(1.0 - z) - 1.0;
659
// Map degree of freedom to element degree of freedom
660
const unsigned int dof = i;
663
const double scalings_y_0 = 1;
664
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
665
const double scalings_z_0 = 1;
666
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
668
// Compute psitilde_a
669
const double psitilde_a_0 = 1;
670
const double psitilde_a_1 = x;
672
// Compute psitilde_bs
673
const double psitilde_bs_0_0 = 1;
674
const double psitilde_bs_0_1 = 1.5*y + 0.5;
675
const double psitilde_bs_1_0 = 1;
677
// Compute psitilde_cs
678
const double psitilde_cs_00_0 = 1;
679
const double psitilde_cs_00_1 = 2*z + 1;
680
const double psitilde_cs_01_0 = 1;
681
const double psitilde_cs_10_0 = 1;
683
// Compute basisvalues
684
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
685
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
686
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
687
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
689
// Table(s) of coefficients
690
static const double coefficients0[4][4] = \
691
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
692
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
693
{0.288675135, 0, 0.210818511, -0.0745355992},
694
{0.288675135, 0, 0, 0.223606798}};
696
// Extract relevant coefficients
697
const double coeff0_0 = coefficients0[dof][0];
698
const double coeff0_1 = coefficients0[dof][1];
699
const double coeff0_2 = coefficients0[dof][2];
700
const double coeff0_3 = coefficients0[dof][3];
703
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
706
/// Evaluate all basis functions at given point in cell
707
virtual void evaluate_basis_all(double* values,
708
const double* coordinates,
709
const ufc::cell& c) const
711
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
714
/// Evaluate order n derivatives of basis function i at given point in cell
715
virtual void evaluate_basis_derivatives(unsigned int i,
718
const double* coordinates,
719
const ufc::cell& c) const
721
// Extract vertex coordinates
722
const double * const * element_coordinates = c.coordinates;
724
// Compute Jacobian of affine map from reference cell
725
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
726
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
727
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
728
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
729
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
730
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
731
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
732
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
733
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
735
// Compute sub determinants
736
const double d00 = J_11*J_22 - J_12*J_21;
737
const double d01 = J_12*J_20 - J_10*J_22;
738
const double d02 = J_10*J_21 - J_11*J_20;
740
const double d10 = J_02*J_21 - J_01*J_22;
741
const double d11 = J_00*J_22 - J_02*J_20;
742
const double d12 = J_01*J_20 - J_00*J_21;
744
const double d20 = J_01*J_12 - J_02*J_11;
745
const double d21 = J_02*J_10 - J_00*J_12;
746
const double d22 = J_00*J_11 - J_01*J_10;
748
// Compute determinant of Jacobian
749
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
751
// Compute inverse of Jacobian
754
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
755
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
756
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
758
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
759
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
760
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
762
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
763
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
764
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
766
// Get coordinates and map to the UFC reference element
767
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
768
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
769
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
771
// Map coordinates to the reference cube
772
if (std::abs(y + z - 1.0) < 1e-08)
775
x = -2.0 * x/(y + z - 1.0) - 1.0;
776
if (std::abs(z - 1.0) < 1e-08)
779
y = 2.0 * y/(1.0 - z) - 1.0;
782
// Compute number of derivatives
783
unsigned int num_derivatives = 1;
785
for (unsigned int j = 0; j < n; j++)
786
num_derivatives *= 3;
789
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
790
unsigned int **combinations = new unsigned int *[num_derivatives];
792
for (unsigned int j = 0; j < num_derivatives; j++)
794
combinations[j] = new unsigned int [n];
795
for (unsigned int k = 0; k < n; k++)
796
combinations[j][k] = 0;
799
// Generate combinations of derivatives
800
for (unsigned int row = 1; row < num_derivatives; row++)
802
for (unsigned int num = 0; num < row; num++)
804
for (unsigned int col = n-1; col+1 > 0; col--)
806
if (combinations[row][col] + 1 > 2)
807
combinations[row][col] = 0;
810
combinations[row][col] += 1;
817
// Compute inverse of Jacobian
818
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
820
// Declare transformation matrix
821
// Declare pointer to two dimensional array and initialise
822
double **transform = new double *[num_derivatives];
824
for (unsigned int j = 0; j < num_derivatives; j++)
826
transform[j] = new double [num_derivatives];
827
for (unsigned int k = 0; k < num_derivatives; k++)
831
// Construct transformation matrix
832
for (unsigned int row = 0; row < num_derivatives; row++)
834
for (unsigned int col = 0; col < num_derivatives; col++)
836
for (unsigned int k = 0; k < n; k++)
837
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
842
for (unsigned int j = 0; j < 1*num_derivatives; j++)
845
// Map degree of freedom to element degree of freedom
846
const unsigned int dof = i;
849
const double scalings_y_0 = 1;
850
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
851
const double scalings_z_0 = 1;
852
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
854
// Compute psitilde_a
855
const double psitilde_a_0 = 1;
856
const double psitilde_a_1 = x;
858
// Compute psitilde_bs
859
const double psitilde_bs_0_0 = 1;
860
const double psitilde_bs_0_1 = 1.5*y + 0.5;
861
const double psitilde_bs_1_0 = 1;
863
// Compute psitilde_cs
864
const double psitilde_cs_00_0 = 1;
865
const double psitilde_cs_00_1 = 2*z + 1;
866
const double psitilde_cs_01_0 = 1;
867
const double psitilde_cs_10_0 = 1;
869
// Compute basisvalues
870
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
871
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
872
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
873
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
875
// Table(s) of coefficients
876
static const double coefficients0[4][4] = \
877
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
878
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
879
{0.288675135, 0, 0.210818511, -0.0745355992},
880
{0.288675135, 0, 0, 0.223606798}};
882
// Interesting (new) part
883
// Tables of derivatives of the polynomial base (transpose)
884
static const double dmats0[4][4] = \
886
{6.32455532, 0, 0, 0},
890
static const double dmats1[4][4] = \
892
{3.16227766, 0, 0, 0},
893
{5.47722558, 0, 0, 0},
896
static const double dmats2[4][4] = \
898
{3.16227766, 0, 0, 0},
899
{1.82574186, 0, 0, 0},
900
{5.16397779, 0, 0, 0}};
902
// Compute reference derivatives
903
// Declare pointer to array of derivatives on FIAT element
904
double *derivatives = new double [num_derivatives];
906
// Declare coefficients
912
// Declare new coefficients
913
double new_coeff0_0 = 0;
914
double new_coeff0_1 = 0;
915
double new_coeff0_2 = 0;
916
double new_coeff0_3 = 0;
918
// Loop possible derivatives
919
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
921
// Get values from coefficients array
922
new_coeff0_0 = coefficients0[dof][0];
923
new_coeff0_1 = coefficients0[dof][1];
924
new_coeff0_2 = coefficients0[dof][2];
925
new_coeff0_3 = coefficients0[dof][3];
927
// Loop derivative order
928
for (unsigned int j = 0; j < n; j++)
930
// Update old coefficients
931
coeff0_0 = new_coeff0_0;
932
coeff0_1 = new_coeff0_1;
933
coeff0_2 = new_coeff0_2;
934
coeff0_3 = new_coeff0_3;
936
if(combinations[deriv_num][j] == 0)
938
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
939
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
940
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
941
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
943
if(combinations[deriv_num][j] == 1)
945
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
946
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
947
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
948
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
950
if(combinations[deriv_num][j] == 2)
952
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
953
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
954
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
955
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
959
// Compute derivatives on reference element as dot product of coefficients and basisvalues
960
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
963
// Transform derivatives back to physical element
964
for (unsigned int row = 0; row < num_derivatives; row++)
966
for (unsigned int col = 0; col < num_derivatives; col++)
968
values[row] += transform[row][col]*derivatives[col];
971
// Delete pointer to array of derivatives on FIAT element
972
delete [] derivatives;
974
// Delete pointer to array of combinations of derivatives and transform
975
for (unsigned int row = 0; row < num_derivatives; row++)
977
delete [] combinations[row];
978
delete [] transform[row];
981
delete [] combinations;
985
/// Evaluate order n derivatives of all basis functions at given point in cell
986
virtual void evaluate_basis_derivatives_all(unsigned int n,
988
const double* coordinates,
989
const ufc::cell& c) const
991
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
994
/// Evaluate linear functional for dof i on the function f
995
virtual double evaluate_dof(unsigned int i,
996
const ufc::function& f,
997
const ufc::cell& c) const
999
// The reference points, direction and weights:
1000
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
1001
static const double W[4][1] = {{1}, {1}, {1}, {1}};
1002
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
1004
const double * const * x = c.coordinates;
1005
double result = 0.0;
1006
// Iterate over the points:
1007
// Evaluate basis functions for affine mapping
1008
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
1009
const double w1 = X[i][0][0];
1010
const double w2 = X[i][0][1];
1011
const double w3 = X[i][0][2];
1013
// Compute affine mapping y = F(X)
1015
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
1016
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
1017
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
1019
// Evaluate function at physical points
1021
f.evaluate(values, y, c);
1023
// Map function values using appropriate mapping
1024
// Affine map: Do nothing
1026
// Note that we do not map the weights (yet).
1028
// Take directional components
1029
for(int k = 0; k < 1; k++)
1030
result += values[k]*D[i][0][k];
1031
// Multiply by weights
1037
/// Evaluate linear functionals for all dofs on the function f
1038
virtual void evaluate_dofs(double* values,
1039
const ufc::function& f,
1040
const ufc::cell& c) const
1042
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1045
/// Interpolate vertex values from dof values
1046
virtual void interpolate_vertex_values(double* vertex_values,
1047
const double* dof_values,
1048
const ufc::cell& c) const
1050
// Evaluate at vertices and use affine mapping
1051
vertex_values[0] = dof_values[0];
1052
vertex_values[1] = dof_values[1];
1053
vertex_values[2] = dof_values[2];
1054
vertex_values[3] = dof_values[3];
1057
/// Return the number of sub elements (for a mixed element)
1058
virtual unsigned int num_sub_elements() const
1063
/// Create a new finite element for sub element i (for a mixed element)
1064
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1066
return new hyperelasticity_0_finite_element_0_1();
1071
/// This class defines the interface for a finite element.
1073
class hyperelasticity_0_finite_element_0_2: public ufc::finite_element
1078
hyperelasticity_0_finite_element_0_2() : ufc::finite_element()
1084
virtual ~hyperelasticity_0_finite_element_0_2()
1089
/// Return a string identifying the finite element
1090
virtual const char* signature() const
1092
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
1095
/// Return the cell shape
1096
virtual ufc::shape cell_shape() const
1098
return ufc::tetrahedron;
1101
/// Return the dimension of the finite element function space
1102
virtual unsigned int space_dimension() const
1107
/// Return the rank of the value space
1108
virtual unsigned int value_rank() const
1113
/// Return the dimension of the value space for axis i
1114
virtual unsigned int value_dimension(unsigned int i) const
1119
/// Evaluate basis function i at given point in cell
1120
virtual void evaluate_basis(unsigned int i,
1122
const double* coordinates,
1123
const ufc::cell& c) const
1125
// Extract vertex coordinates
1126
const double * const * element_coordinates = c.coordinates;
1128
// Compute Jacobian of affine map from reference cell
1129
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1130
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1131
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
1132
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1133
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1134
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
1135
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
1136
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
1137
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
1139
// Compute sub determinants
1140
const double d00 = J_11*J_22 - J_12*J_21;
1141
const double d01 = J_12*J_20 - J_10*J_22;
1142
const double d02 = J_10*J_21 - J_11*J_20;
1144
const double d10 = J_02*J_21 - J_01*J_22;
1145
const double d11 = J_00*J_22 - J_02*J_20;
1146
const double d12 = J_01*J_20 - J_00*J_21;
1148
const double d20 = J_01*J_12 - J_02*J_11;
1149
const double d21 = J_02*J_10 - J_00*J_12;
1150
const double d22 = J_00*J_11 - J_01*J_10;
1152
// Compute determinant of Jacobian
1153
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
1155
// Compute inverse of Jacobian
1157
// Compute constants
1158
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
1159
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
1160
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
1162
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
1163
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
1164
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
1166
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
1167
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
1168
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
1170
// Get coordinates and map to the UFC reference element
1171
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
1172
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
1173
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
1175
// Map coordinates to the reference cube
1176
if (std::abs(y + z - 1.0) < 1e-08)
1179
x = -2.0 * x/(y + z - 1.0) - 1.0;
1180
if (std::abs(z - 1.0) < 1e-08)
1183
y = 2.0 * y/(1.0 - z) - 1.0;
1189
// Map degree of freedom to element degree of freedom
1190
const unsigned int dof = i;
1192
// Generate scalings
1193
const double scalings_y_0 = 1;
1194
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1195
const double scalings_z_0 = 1;
1196
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
1198
// Compute psitilde_a
1199
const double psitilde_a_0 = 1;
1200
const double psitilde_a_1 = x;
1202
// Compute psitilde_bs
1203
const double psitilde_bs_0_0 = 1;
1204
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1205
const double psitilde_bs_1_0 = 1;
1207
// Compute psitilde_cs
1208
const double psitilde_cs_00_0 = 1;
1209
const double psitilde_cs_00_1 = 2*z + 1;
1210
const double psitilde_cs_01_0 = 1;
1211
const double psitilde_cs_10_0 = 1;
1213
// Compute basisvalues
1214
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
1215
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
1216
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
1217
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
1219
// Table(s) of coefficients
1220
static const double coefficients0[4][4] = \
1221
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
1222
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
1223
{0.288675135, 0, 0.210818511, -0.0745355992},
1224
{0.288675135, 0, 0, 0.223606798}};
1226
// Extract relevant coefficients
1227
const double coeff0_0 = coefficients0[dof][0];
1228
const double coeff0_1 = coefficients0[dof][1];
1229
const double coeff0_2 = coefficients0[dof][2];
1230
const double coeff0_3 = coefficients0[dof][3];
1233
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
1236
/// Evaluate all basis functions at given point in cell
1237
virtual void evaluate_basis_all(double* values,
1238
const double* coordinates,
1239
const ufc::cell& c) const
1241
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1244
/// Evaluate order n derivatives of basis function i at given point in cell
1245
virtual void evaluate_basis_derivatives(unsigned int i,
1248
const double* coordinates,
1249
const ufc::cell& c) const
1251
// Extract vertex coordinates
1252
const double * const * element_coordinates = c.coordinates;
1254
// Compute Jacobian of affine map from reference cell
1255
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1256
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1257
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
1258
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1259
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1260
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
1261
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
1262
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
1263
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
1265
// Compute sub determinants
1266
const double d00 = J_11*J_22 - J_12*J_21;
1267
const double d01 = J_12*J_20 - J_10*J_22;
1268
const double d02 = J_10*J_21 - J_11*J_20;
1270
const double d10 = J_02*J_21 - J_01*J_22;
1271
const double d11 = J_00*J_22 - J_02*J_20;
1272
const double d12 = J_01*J_20 - J_00*J_21;
1274
const double d20 = J_01*J_12 - J_02*J_11;
1275
const double d21 = J_02*J_10 - J_00*J_12;
1276
const double d22 = J_00*J_11 - J_01*J_10;
1278
// Compute determinant of Jacobian
1279
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
1281
// Compute inverse of Jacobian
1283
// Compute constants
1284
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
1285
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
1286
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
1288
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
1289
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
1290
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
1292
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
1293
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
1294
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
1296
// Get coordinates and map to the UFC reference element
1297
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
1298
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
1299
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
1301
// Map coordinates to the reference cube
1302
if (std::abs(y + z - 1.0) < 1e-08)
1305
x = -2.0 * x/(y + z - 1.0) - 1.0;
1306
if (std::abs(z - 1.0) < 1e-08)
1309
y = 2.0 * y/(1.0 - z) - 1.0;
1312
// Compute number of derivatives
1313
unsigned int num_derivatives = 1;
1315
for (unsigned int j = 0; j < n; j++)
1316
num_derivatives *= 3;
1319
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1320
unsigned int **combinations = new unsigned int *[num_derivatives];
1322
for (unsigned int j = 0; j < num_derivatives; j++)
1324
combinations[j] = new unsigned int [n];
1325
for (unsigned int k = 0; k < n; k++)
1326
combinations[j][k] = 0;
1329
// Generate combinations of derivatives
1330
for (unsigned int row = 1; row < num_derivatives; row++)
1332
for (unsigned int num = 0; num < row; num++)
1334
for (unsigned int col = n-1; col+1 > 0; col--)
1336
if (combinations[row][col] + 1 > 2)
1337
combinations[row][col] = 0;
1340
combinations[row][col] += 1;
1347
// Compute inverse of Jacobian
1348
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
1350
// Declare transformation matrix
1351
// Declare pointer to two dimensional array and initialise
1352
double **transform = new double *[num_derivatives];
1354
for (unsigned int j = 0; j < num_derivatives; j++)
1356
transform[j] = new double [num_derivatives];
1357
for (unsigned int k = 0; k < num_derivatives; k++)
1358
transform[j][k] = 1;
1361
// Construct transformation matrix
1362
for (unsigned int row = 0; row < num_derivatives; row++)
1364
for (unsigned int col = 0; col < num_derivatives; col++)
1366
for (unsigned int k = 0; k < n; k++)
1367
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1372
for (unsigned int j = 0; j < 1*num_derivatives; j++)
1375
// Map degree of freedom to element degree of freedom
1376
const unsigned int dof = i;
1378
// Generate scalings
1379
const double scalings_y_0 = 1;
1380
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1381
const double scalings_z_0 = 1;
1382
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
1384
// Compute psitilde_a
1385
const double psitilde_a_0 = 1;
1386
const double psitilde_a_1 = x;
1388
// Compute psitilde_bs
1389
const double psitilde_bs_0_0 = 1;
1390
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1391
const double psitilde_bs_1_0 = 1;
1393
// Compute psitilde_cs
1394
const double psitilde_cs_00_0 = 1;
1395
const double psitilde_cs_00_1 = 2*z + 1;
1396
const double psitilde_cs_01_0 = 1;
1397
const double psitilde_cs_10_0 = 1;
1399
// Compute basisvalues
1400
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
1401
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
1402
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
1403
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
1405
// Table(s) of coefficients
1406
static const double coefficients0[4][4] = \
1407
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
1408
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
1409
{0.288675135, 0, 0.210818511, -0.0745355992},
1410
{0.288675135, 0, 0, 0.223606798}};
1412
// Interesting (new) part
1413
// Tables of derivatives of the polynomial base (transpose)
1414
static const double dmats0[4][4] = \
1416
{6.32455532, 0, 0, 0},
1420
static const double dmats1[4][4] = \
1422
{3.16227766, 0, 0, 0},
1423
{5.47722558, 0, 0, 0},
1426
static const double dmats2[4][4] = \
1428
{3.16227766, 0, 0, 0},
1429
{1.82574186, 0, 0, 0},
1430
{5.16397779, 0, 0, 0}};
1432
// Compute reference derivatives
1433
// Declare pointer to array of derivatives on FIAT element
1434
double *derivatives = new double [num_derivatives];
1436
// Declare coefficients
1437
double coeff0_0 = 0;
1438
double coeff0_1 = 0;
1439
double coeff0_2 = 0;
1440
double coeff0_3 = 0;
1442
// Declare new coefficients
1443
double new_coeff0_0 = 0;
1444
double new_coeff0_1 = 0;
1445
double new_coeff0_2 = 0;
1446
double new_coeff0_3 = 0;
1448
// Loop possible derivatives
1449
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1451
// Get values from coefficients array
1452
new_coeff0_0 = coefficients0[dof][0];
1453
new_coeff0_1 = coefficients0[dof][1];
1454
new_coeff0_2 = coefficients0[dof][2];
1455
new_coeff0_3 = coefficients0[dof][3];
1457
// Loop derivative order
1458
for (unsigned int j = 0; j < n; j++)
1460
// Update old coefficients
1461
coeff0_0 = new_coeff0_0;
1462
coeff0_1 = new_coeff0_1;
1463
coeff0_2 = new_coeff0_2;
1464
coeff0_3 = new_coeff0_3;
1466
if(combinations[deriv_num][j] == 0)
1468
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
1469
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
1470
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
1471
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
1473
if(combinations[deriv_num][j] == 1)
1475
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
1476
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
1477
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
1478
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
1480
if(combinations[deriv_num][j] == 2)
1482
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
1483
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
1484
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
1485
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
1489
// Compute derivatives on reference element as dot product of coefficients and basisvalues
1490
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
1493
// Transform derivatives back to physical element
1494
for (unsigned int row = 0; row < num_derivatives; row++)
1496
for (unsigned int col = 0; col < num_derivatives; col++)
1498
values[row] += transform[row][col]*derivatives[col];
1501
// Delete pointer to array of derivatives on FIAT element
1502
delete [] derivatives;
1504
// Delete pointer to array of combinations of derivatives and transform
1505
for (unsigned int row = 0; row < num_derivatives; row++)
1507
delete [] combinations[row];
1508
delete [] transform[row];
1511
delete [] combinations;
1512
delete [] transform;
1515
/// Evaluate order n derivatives of all basis functions at given point in cell
1516
virtual void evaluate_basis_derivatives_all(unsigned int n,
1518
const double* coordinates,
1519
const ufc::cell& c) const
1521
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1524
/// Evaluate linear functional for dof i on the function f
1525
virtual double evaluate_dof(unsigned int i,
1526
const ufc::function& f,
1527
const ufc::cell& c) const
1529
// The reference points, direction and weights:
1530
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
1531
static const double W[4][1] = {{1}, {1}, {1}, {1}};
1532
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
1534
const double * const * x = c.coordinates;
1535
double result = 0.0;
1536
// Iterate over the points:
1537
// Evaluate basis functions for affine mapping
1538
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
1539
const double w1 = X[i][0][0];
1540
const double w2 = X[i][0][1];
1541
const double w3 = X[i][0][2];
1543
// Compute affine mapping y = F(X)
1545
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
1546
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
1547
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
1549
// Evaluate function at physical points
1551
f.evaluate(values, y, c);
1553
// Map function values using appropriate mapping
1554
// Affine map: Do nothing
1556
// Note that we do not map the weights (yet).
1558
// Take directional components
1559
for(int k = 0; k < 1; k++)
1560
result += values[k]*D[i][0][k];
1561
// Multiply by weights
1567
/// Evaluate linear functionals for all dofs on the function f
1568
virtual void evaluate_dofs(double* values,
1569
const ufc::function& f,
1570
const ufc::cell& c) const
1572
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1575
/// Interpolate vertex values from dof values
1576
virtual void interpolate_vertex_values(double* vertex_values,
1577
const double* dof_values,
1578
const ufc::cell& c) const
1580
// Evaluate at vertices and use affine mapping
1581
vertex_values[0] = dof_values[0];
1582
vertex_values[1] = dof_values[1];
1583
vertex_values[2] = dof_values[2];
1584
vertex_values[3] = dof_values[3];
1587
/// Return the number of sub elements (for a mixed element)
1588
virtual unsigned int num_sub_elements() const
1593
/// Create a new finite element for sub element i (for a mixed element)
1594
virtual ufc::finite_element* create_sub_element(unsigned int i) const
1596
return new hyperelasticity_0_finite_element_0_2();
1601
/// This class defines the interface for a finite element.
1603
class hyperelasticity_0_finite_element_0: public ufc::finite_element
1608
hyperelasticity_0_finite_element_0() : ufc::finite_element()
1614
virtual ~hyperelasticity_0_finite_element_0()
1619
/// Return a string identifying the finite element
1620
virtual const char* signature() const
1622
return "VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
1625
/// Return the cell shape
1626
virtual ufc::shape cell_shape() const
1628
return ufc::tetrahedron;
1631
/// Return the dimension of the finite element function space
1632
virtual unsigned int space_dimension() const
1637
/// Return the rank of the value space
1638
virtual unsigned int value_rank() const
1643
/// Return the dimension of the value space for axis i
1644
virtual unsigned int value_dimension(unsigned int i) const
1649
/// Evaluate basis function i at given point in cell
1650
virtual void evaluate_basis(unsigned int i,
1652
const double* coordinates,
1653
const ufc::cell& c) const
1655
// Extract vertex coordinates
1656
const double * const * element_coordinates = c.coordinates;
1658
// Compute Jacobian of affine map from reference cell
1659
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1660
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1661
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
1662
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1663
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1664
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
1665
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
1666
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
1667
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
1669
// Compute sub determinants
1670
const double d00 = J_11*J_22 - J_12*J_21;
1671
const double d01 = J_12*J_20 - J_10*J_22;
1672
const double d02 = J_10*J_21 - J_11*J_20;
1674
const double d10 = J_02*J_21 - J_01*J_22;
1675
const double d11 = J_00*J_22 - J_02*J_20;
1676
const double d12 = J_01*J_20 - J_00*J_21;
1678
const double d20 = J_01*J_12 - J_02*J_11;
1679
const double d21 = J_02*J_10 - J_00*J_12;
1680
const double d22 = J_00*J_11 - J_01*J_10;
1682
// Compute determinant of Jacobian
1683
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
1685
// Compute inverse of Jacobian
1687
// Compute constants
1688
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
1689
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
1690
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
1692
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
1693
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
1694
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
1696
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
1697
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
1698
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
1700
// Get coordinates and map to the UFC reference element
1701
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
1702
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
1703
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
1705
// Map coordinates to the reference cube
1706
if (std::abs(y + z - 1.0) < 1e-08)
1709
x = -2.0 * x/(y + z - 1.0) - 1.0;
1710
if (std::abs(z - 1.0) < 1e-08)
1713
y = 2.0 * y/(1.0 - z) - 1.0;
1721
if (0 <= i && i <= 3)
1723
// Map degree of freedom to element degree of freedom
1724
const unsigned int dof = i;
1726
// Generate scalings
1727
const double scalings_y_0 = 1;
1728
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1729
const double scalings_z_0 = 1;
1730
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
1732
// Compute psitilde_a
1733
const double psitilde_a_0 = 1;
1734
const double psitilde_a_1 = x;
1736
// Compute psitilde_bs
1737
const double psitilde_bs_0_0 = 1;
1738
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1739
const double psitilde_bs_1_0 = 1;
1741
// Compute psitilde_cs
1742
const double psitilde_cs_00_0 = 1;
1743
const double psitilde_cs_00_1 = 2*z + 1;
1744
const double psitilde_cs_01_0 = 1;
1745
const double psitilde_cs_10_0 = 1;
1747
// Compute basisvalues
1748
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
1749
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
1750
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
1751
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
1753
// Table(s) of coefficients
1754
static const double coefficients0[4][4] = \
1755
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
1756
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
1757
{0.288675135, 0, 0.210818511, -0.0745355992},
1758
{0.288675135, 0, 0, 0.223606798}};
1760
// Extract relevant coefficients
1761
const double coeff0_0 = coefficients0[dof][0];
1762
const double coeff0_1 = coefficients0[dof][1];
1763
const double coeff0_2 = coefficients0[dof][2];
1764
const double coeff0_3 = coefficients0[dof][3];
1767
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
1770
if (4 <= i && i <= 7)
1772
// Map degree of freedom to element degree of freedom
1773
const unsigned int dof = i - 4;
1775
// Generate scalings
1776
const double scalings_y_0 = 1;
1777
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1778
const double scalings_z_0 = 1;
1779
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
1781
// Compute psitilde_a
1782
const double psitilde_a_0 = 1;
1783
const double psitilde_a_1 = x;
1785
// Compute psitilde_bs
1786
const double psitilde_bs_0_0 = 1;
1787
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1788
const double psitilde_bs_1_0 = 1;
1790
// Compute psitilde_cs
1791
const double psitilde_cs_00_0 = 1;
1792
const double psitilde_cs_00_1 = 2*z + 1;
1793
const double psitilde_cs_01_0 = 1;
1794
const double psitilde_cs_10_0 = 1;
1796
// Compute basisvalues
1797
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
1798
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
1799
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
1800
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
1802
// Table(s) of coefficients
1803
static const double coefficients0[4][4] = \
1804
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
1805
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
1806
{0.288675135, 0, 0.210818511, -0.0745355992},
1807
{0.288675135, 0, 0, 0.223606798}};
1809
// Extract relevant coefficients
1810
const double coeff0_0 = coefficients0[dof][0];
1811
const double coeff0_1 = coefficients0[dof][1];
1812
const double coeff0_2 = coefficients0[dof][2];
1813
const double coeff0_3 = coefficients0[dof][3];
1816
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
1819
if (8 <= i && i <= 11)
1821
// Map degree of freedom to element degree of freedom
1822
const unsigned int dof = i - 8;
1824
// Generate scalings
1825
const double scalings_y_0 = 1;
1826
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1827
const double scalings_z_0 = 1;
1828
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
1830
// Compute psitilde_a
1831
const double psitilde_a_0 = 1;
1832
const double psitilde_a_1 = x;
1834
// Compute psitilde_bs
1835
const double psitilde_bs_0_0 = 1;
1836
const double psitilde_bs_0_1 = 1.5*y + 0.5;
1837
const double psitilde_bs_1_0 = 1;
1839
// Compute psitilde_cs
1840
const double psitilde_cs_00_0 = 1;
1841
const double psitilde_cs_00_1 = 2*z + 1;
1842
const double psitilde_cs_01_0 = 1;
1843
const double psitilde_cs_10_0 = 1;
1845
// Compute basisvalues
1846
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
1847
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
1848
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
1849
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
1851
// Table(s) of coefficients
1852
static const double coefficients0[4][4] = \
1853
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
1854
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
1855
{0.288675135, 0, 0.210818511, -0.0745355992},
1856
{0.288675135, 0, 0, 0.223606798}};
1858
// Extract relevant coefficients
1859
const double coeff0_0 = coefficients0[dof][0];
1860
const double coeff0_1 = coefficients0[dof][1];
1861
const double coeff0_2 = coefficients0[dof][2];
1862
const double coeff0_3 = coefficients0[dof][3];
1865
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
1870
/// Evaluate all basis functions at given point in cell
1871
virtual void evaluate_basis_all(double* values,
1872
const double* coordinates,
1873
const ufc::cell& c) const
1875
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1878
/// Evaluate order n derivatives of basis function i at given point in cell
1879
virtual void evaluate_basis_derivatives(unsigned int i,
1882
const double* coordinates,
1883
const ufc::cell& c) const
1885
// Extract vertex coordinates
1886
const double * const * element_coordinates = c.coordinates;
1888
// Compute Jacobian of affine map from reference cell
1889
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1890
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1891
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
1892
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1893
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1894
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
1895
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
1896
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
1897
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
1899
// Compute sub determinants
1900
const double d00 = J_11*J_22 - J_12*J_21;
1901
const double d01 = J_12*J_20 - J_10*J_22;
1902
const double d02 = J_10*J_21 - J_11*J_20;
1904
const double d10 = J_02*J_21 - J_01*J_22;
1905
const double d11 = J_00*J_22 - J_02*J_20;
1906
const double d12 = J_01*J_20 - J_00*J_21;
1908
const double d20 = J_01*J_12 - J_02*J_11;
1909
const double d21 = J_02*J_10 - J_00*J_12;
1910
const double d22 = J_00*J_11 - J_01*J_10;
1912
// Compute determinant of Jacobian
1913
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
1915
// Compute inverse of Jacobian
1917
// Compute constants
1918
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
1919
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
1920
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
1922
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
1923
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
1924
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
1926
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
1927
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
1928
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
1930
// Get coordinates and map to the UFC reference element
1931
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
1932
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
1933
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
1935
// Map coordinates to the reference cube
1936
if (std::abs(y + z - 1.0) < 1e-08)
1939
x = -2.0 * x/(y + z - 1.0) - 1.0;
1940
if (std::abs(z - 1.0) < 1e-08)
1943
y = 2.0 * y/(1.0 - z) - 1.0;
1946
// Compute number of derivatives
1947
unsigned int num_derivatives = 1;
1949
for (unsigned int j = 0; j < n; j++)
1950
num_derivatives *= 3;
1953
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1954
unsigned int **combinations = new unsigned int *[num_derivatives];
1956
for (unsigned int j = 0; j < num_derivatives; j++)
1958
combinations[j] = new unsigned int [n];
1959
for (unsigned int k = 0; k < n; k++)
1960
combinations[j][k] = 0;
1963
// Generate combinations of derivatives
1964
for (unsigned int row = 1; row < num_derivatives; row++)
1966
for (unsigned int num = 0; num < row; num++)
1968
for (unsigned int col = n-1; col+1 > 0; col--)
1970
if (combinations[row][col] + 1 > 2)
1971
combinations[row][col] = 0;
1974
combinations[row][col] += 1;
1981
// Compute inverse of Jacobian
1982
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
1984
// Declare transformation matrix
1985
// Declare pointer to two dimensional array and initialise
1986
double **transform = new double *[num_derivatives];
1988
for (unsigned int j = 0; j < num_derivatives; j++)
1990
transform[j] = new double [num_derivatives];
1991
for (unsigned int k = 0; k < num_derivatives; k++)
1992
transform[j][k] = 1;
1995
// Construct transformation matrix
1996
for (unsigned int row = 0; row < num_derivatives; row++)
1998
for (unsigned int col = 0; col < num_derivatives; col++)
2000
for (unsigned int k = 0; k < n; k++)
2001
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2006
for (unsigned int j = 0; j < 3*num_derivatives; j++)
2009
if (0 <= i && i <= 3)
2011
// Map degree of freedom to element degree of freedom
2012
const unsigned int dof = i;
2014
// Generate scalings
2015
const double scalings_y_0 = 1;
2016
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2017
const double scalings_z_0 = 1;
2018
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
2020
// Compute psitilde_a
2021
const double psitilde_a_0 = 1;
2022
const double psitilde_a_1 = x;
2024
// Compute psitilde_bs
2025
const double psitilde_bs_0_0 = 1;
2026
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2027
const double psitilde_bs_1_0 = 1;
2029
// Compute psitilde_cs
2030
const double psitilde_cs_00_0 = 1;
2031
const double psitilde_cs_00_1 = 2*z + 1;
2032
const double psitilde_cs_01_0 = 1;
2033
const double psitilde_cs_10_0 = 1;
2035
// Compute basisvalues
2036
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
2037
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
2038
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
2039
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
2041
// Table(s) of coefficients
2042
static const double coefficients0[4][4] = \
2043
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
2044
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
2045
{0.288675135, 0, 0.210818511, -0.0745355992},
2046
{0.288675135, 0, 0, 0.223606798}};
2048
// Interesting (new) part
2049
// Tables of derivatives of the polynomial base (transpose)
2050
static const double dmats0[4][4] = \
2052
{6.32455532, 0, 0, 0},
2056
static const double dmats1[4][4] = \
2058
{3.16227766, 0, 0, 0},
2059
{5.47722558, 0, 0, 0},
2062
static const double dmats2[4][4] = \
2064
{3.16227766, 0, 0, 0},
2065
{1.82574186, 0, 0, 0},
2066
{5.16397779, 0, 0, 0}};
2068
// Compute reference derivatives
2069
// Declare pointer to array of derivatives on FIAT element
2070
double *derivatives = new double [num_derivatives];
2072
// Declare coefficients
2073
double coeff0_0 = 0;
2074
double coeff0_1 = 0;
2075
double coeff0_2 = 0;
2076
double coeff0_3 = 0;
2078
// Declare new coefficients
2079
double new_coeff0_0 = 0;
2080
double new_coeff0_1 = 0;
2081
double new_coeff0_2 = 0;
2082
double new_coeff0_3 = 0;
2084
// Loop possible derivatives
2085
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2087
// Get values from coefficients array
2088
new_coeff0_0 = coefficients0[dof][0];
2089
new_coeff0_1 = coefficients0[dof][1];
2090
new_coeff0_2 = coefficients0[dof][2];
2091
new_coeff0_3 = coefficients0[dof][3];
2093
// Loop derivative order
2094
for (unsigned int j = 0; j < n; j++)
2096
// Update old coefficients
2097
coeff0_0 = new_coeff0_0;
2098
coeff0_1 = new_coeff0_1;
2099
coeff0_2 = new_coeff0_2;
2100
coeff0_3 = new_coeff0_3;
2102
if(combinations[deriv_num][j] == 0)
2104
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
2105
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
2106
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
2107
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
2109
if(combinations[deriv_num][j] == 1)
2111
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
2112
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
2113
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
2114
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
2116
if(combinations[deriv_num][j] == 2)
2118
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
2119
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
2120
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
2121
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
2125
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2126
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
2129
// Transform derivatives back to physical element
2130
for (unsigned int row = 0; row < num_derivatives; row++)
2132
for (unsigned int col = 0; col < num_derivatives; col++)
2134
values[row] += transform[row][col]*derivatives[col];
2137
// Delete pointer to array of derivatives on FIAT element
2138
delete [] derivatives;
2140
// Delete pointer to array of combinations of derivatives and transform
2141
for (unsigned int row = 0; row < num_derivatives; row++)
2143
delete [] combinations[row];
2144
delete [] transform[row];
2147
delete [] combinations;
2148
delete [] transform;
2151
if (4 <= i && i <= 7)
2153
// Map degree of freedom to element degree of freedom
2154
const unsigned int dof = i - 4;
2156
// Generate scalings
2157
const double scalings_y_0 = 1;
2158
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2159
const double scalings_z_0 = 1;
2160
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
2162
// Compute psitilde_a
2163
const double psitilde_a_0 = 1;
2164
const double psitilde_a_1 = x;
2166
// Compute psitilde_bs
2167
const double psitilde_bs_0_0 = 1;
2168
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2169
const double psitilde_bs_1_0 = 1;
2171
// Compute psitilde_cs
2172
const double psitilde_cs_00_0 = 1;
2173
const double psitilde_cs_00_1 = 2*z + 1;
2174
const double psitilde_cs_01_0 = 1;
2175
const double psitilde_cs_10_0 = 1;
2177
// Compute basisvalues
2178
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
2179
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
2180
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
2181
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
2183
// Table(s) of coefficients
2184
static const double coefficients0[4][4] = \
2185
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
2186
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
2187
{0.288675135, 0, 0.210818511, -0.0745355992},
2188
{0.288675135, 0, 0, 0.223606798}};
2190
// Interesting (new) part
2191
// Tables of derivatives of the polynomial base (transpose)
2192
static const double dmats0[4][4] = \
2194
{6.32455532, 0, 0, 0},
2198
static const double dmats1[4][4] = \
2200
{3.16227766, 0, 0, 0},
2201
{5.47722558, 0, 0, 0},
2204
static const double dmats2[4][4] = \
2206
{3.16227766, 0, 0, 0},
2207
{1.82574186, 0, 0, 0},
2208
{5.16397779, 0, 0, 0}};
2210
// Compute reference derivatives
2211
// Declare pointer to array of derivatives on FIAT element
2212
double *derivatives = new double [num_derivatives];
2214
// Declare coefficients
2215
double coeff0_0 = 0;
2216
double coeff0_1 = 0;
2217
double coeff0_2 = 0;
2218
double coeff0_3 = 0;
2220
// Declare new coefficients
2221
double new_coeff0_0 = 0;
2222
double new_coeff0_1 = 0;
2223
double new_coeff0_2 = 0;
2224
double new_coeff0_3 = 0;
2226
// Loop possible derivatives
2227
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2229
// Get values from coefficients array
2230
new_coeff0_0 = coefficients0[dof][0];
2231
new_coeff0_1 = coefficients0[dof][1];
2232
new_coeff0_2 = coefficients0[dof][2];
2233
new_coeff0_3 = coefficients0[dof][3];
2235
// Loop derivative order
2236
for (unsigned int j = 0; j < n; j++)
2238
// Update old coefficients
2239
coeff0_0 = new_coeff0_0;
2240
coeff0_1 = new_coeff0_1;
2241
coeff0_2 = new_coeff0_2;
2242
coeff0_3 = new_coeff0_3;
2244
if(combinations[deriv_num][j] == 0)
2246
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
2247
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
2248
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
2249
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
2251
if(combinations[deriv_num][j] == 1)
2253
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
2254
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
2255
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
2256
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
2258
if(combinations[deriv_num][j] == 2)
2260
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
2261
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
2262
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
2263
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
2267
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2268
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
2271
// Transform derivatives back to physical element
2272
for (unsigned int row = 0; row < num_derivatives; row++)
2274
for (unsigned int col = 0; col < num_derivatives; col++)
2276
values[num_derivatives + row] += transform[row][col]*derivatives[col];
2279
// Delete pointer to array of derivatives on FIAT element
2280
delete [] derivatives;
2282
// Delete pointer to array of combinations of derivatives and transform
2283
for (unsigned int row = 0; row < num_derivatives; row++)
2285
delete [] combinations[row];
2286
delete [] transform[row];
2289
delete [] combinations;
2290
delete [] transform;
2293
if (8 <= i && i <= 11)
2295
// Map degree of freedom to element degree of freedom
2296
const unsigned int dof = i - 8;
2298
// Generate scalings
2299
const double scalings_y_0 = 1;
2300
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2301
const double scalings_z_0 = 1;
2302
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
2304
// Compute psitilde_a
2305
const double psitilde_a_0 = 1;
2306
const double psitilde_a_1 = x;
2308
// Compute psitilde_bs
2309
const double psitilde_bs_0_0 = 1;
2310
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2311
const double psitilde_bs_1_0 = 1;
2313
// Compute psitilde_cs
2314
const double psitilde_cs_00_0 = 1;
2315
const double psitilde_cs_00_1 = 2*z + 1;
2316
const double psitilde_cs_01_0 = 1;
2317
const double psitilde_cs_10_0 = 1;
2319
// Compute basisvalues
2320
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
2321
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
2322
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
2323
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
2325
// Table(s) of coefficients
2326
static const double coefficients0[4][4] = \
2327
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
2328
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
2329
{0.288675135, 0, 0.210818511, -0.0745355992},
2330
{0.288675135, 0, 0, 0.223606798}};
2332
// Interesting (new) part
2333
// Tables of derivatives of the polynomial base (transpose)
2334
static const double dmats0[4][4] = \
2336
{6.32455532, 0, 0, 0},
2340
static const double dmats1[4][4] = \
2342
{3.16227766, 0, 0, 0},
2343
{5.47722558, 0, 0, 0},
2346
static const double dmats2[4][4] = \
2348
{3.16227766, 0, 0, 0},
2349
{1.82574186, 0, 0, 0},
2350
{5.16397779, 0, 0, 0}};
2352
// Compute reference derivatives
2353
// Declare pointer to array of derivatives on FIAT element
2354
double *derivatives = new double [num_derivatives];
2356
// Declare coefficients
2357
double coeff0_0 = 0;
2358
double coeff0_1 = 0;
2359
double coeff0_2 = 0;
2360
double coeff0_3 = 0;
2362
// Declare new coefficients
2363
double new_coeff0_0 = 0;
2364
double new_coeff0_1 = 0;
2365
double new_coeff0_2 = 0;
2366
double new_coeff0_3 = 0;
2368
// Loop possible derivatives
2369
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2371
// Get values from coefficients array
2372
new_coeff0_0 = coefficients0[dof][0];
2373
new_coeff0_1 = coefficients0[dof][1];
2374
new_coeff0_2 = coefficients0[dof][2];
2375
new_coeff0_3 = coefficients0[dof][3];
2377
// Loop derivative order
2378
for (unsigned int j = 0; j < n; j++)
2380
// Update old coefficients
2381
coeff0_0 = new_coeff0_0;
2382
coeff0_1 = new_coeff0_1;
2383
coeff0_2 = new_coeff0_2;
2384
coeff0_3 = new_coeff0_3;
2386
if(combinations[deriv_num][j] == 0)
2388
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
2389
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
2390
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
2391
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
2393
if(combinations[deriv_num][j] == 1)
2395
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
2396
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
2397
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
2398
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
2400
if(combinations[deriv_num][j] == 2)
2402
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
2403
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
2404
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
2405
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
2409
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2410
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
2413
// Transform derivatives back to physical element
2414
for (unsigned int row = 0; row < num_derivatives; row++)
2416
for (unsigned int col = 0; col < num_derivatives; col++)
2418
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
2421
// Delete pointer to array of derivatives on FIAT element
2422
delete [] derivatives;
2424
// Delete pointer to array of combinations of derivatives and transform
2425
for (unsigned int row = 0; row < num_derivatives; row++)
2427
delete [] combinations[row];
2428
delete [] transform[row];
2431
delete [] combinations;
2432
delete [] transform;
2437
/// Evaluate order n derivatives of all basis functions at given point in cell
2438
virtual void evaluate_basis_derivatives_all(unsigned int n,
2440
const double* coordinates,
2441
const ufc::cell& c) const
2443
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2446
/// Evaluate linear functional for dof i on the function f
2447
virtual double evaluate_dof(unsigned int i,
2448
const ufc::function& f,
2449
const ufc::cell& c) const
2451
// The reference points, direction and weights:
2452
static const double X[12][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
2453
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
2454
static const double D[12][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
2456
const double * const * x = c.coordinates;
2457
double result = 0.0;
2458
// Iterate over the points:
2459
// Evaluate basis functions for affine mapping
2460
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
2461
const double w1 = X[i][0][0];
2462
const double w2 = X[i][0][1];
2463
const double w3 = X[i][0][2];
2465
// Compute affine mapping y = F(X)
2467
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
2468
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
2469
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
2471
// Evaluate function at physical points
2473
f.evaluate(values, y, c);
2475
// Map function values using appropriate mapping
2476
// Affine map: Do nothing
2478
// Note that we do not map the weights (yet).
2480
// Take directional components
2481
for(int k = 0; k < 3; k++)
2482
result += values[k]*D[i][0][k];
2483
// Multiply by weights
2489
/// Evaluate linear functionals for all dofs on the function f
2490
virtual void evaluate_dofs(double* values,
2491
const ufc::function& f,
2492
const ufc::cell& c) const
2494
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2497
/// Interpolate vertex values from dof values
2498
virtual void interpolate_vertex_values(double* vertex_values,
2499
const double* dof_values,
2500
const ufc::cell& c) const
2502
// Evaluate at vertices and use affine mapping
2503
vertex_values[0] = dof_values[0];
2504
vertex_values[3] = dof_values[1];
2505
vertex_values[6] = dof_values[2];
2506
vertex_values[9] = dof_values[3];
2507
// Evaluate at vertices and use affine mapping
2508
vertex_values[1] = dof_values[4];
2509
vertex_values[4] = dof_values[5];
2510
vertex_values[7] = dof_values[6];
2511
vertex_values[10] = dof_values[7];
2512
// Evaluate at vertices and use affine mapping
2513
vertex_values[2] = dof_values[8];
2514
vertex_values[5] = dof_values[9];
2515
vertex_values[8] = dof_values[10];
2516
vertex_values[11] = dof_values[11];
2519
/// Return the number of sub elements (for a mixed element)
2520
virtual unsigned int num_sub_elements() const
2525
/// Create a new finite element for sub element i (for a mixed element)
2526
virtual ufc::finite_element* create_sub_element(unsigned int i) const
2531
return new hyperelasticity_0_finite_element_0_0();
2534
return new hyperelasticity_0_finite_element_0_1();
2537
return new hyperelasticity_0_finite_element_0_2();
2545
/// This class defines the interface for a finite element.
2547
class hyperelasticity_0_finite_element_1_0: public ufc::finite_element
2552
hyperelasticity_0_finite_element_1_0() : ufc::finite_element()
2558
virtual ~hyperelasticity_0_finite_element_1_0()
2563
/// Return a string identifying the finite element
2564
virtual const char* signature() const
2566
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
2569
/// Return the cell shape
2570
virtual ufc::shape cell_shape() const
2572
return ufc::tetrahedron;
2575
/// Return the dimension of the finite element function space
2576
virtual unsigned int space_dimension() const
2581
/// Return the rank of the value space
2582
virtual unsigned int value_rank() const
2587
/// Return the dimension of the value space for axis i
2588
virtual unsigned int value_dimension(unsigned int i) const
2593
/// Evaluate basis function i at given point in cell
2594
virtual void evaluate_basis(unsigned int i,
2596
const double* coordinates,
2597
const ufc::cell& c) const
2599
// Extract vertex coordinates
2600
const double * const * element_coordinates = c.coordinates;
2602
// Compute Jacobian of affine map from reference cell
2603
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2604
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2605
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
2606
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2607
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2608
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
2609
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
2610
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
2611
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
2613
// Compute sub determinants
2614
const double d00 = J_11*J_22 - J_12*J_21;
2615
const double d01 = J_12*J_20 - J_10*J_22;
2616
const double d02 = J_10*J_21 - J_11*J_20;
2618
const double d10 = J_02*J_21 - J_01*J_22;
2619
const double d11 = J_00*J_22 - J_02*J_20;
2620
const double d12 = J_01*J_20 - J_00*J_21;
2622
const double d20 = J_01*J_12 - J_02*J_11;
2623
const double d21 = J_02*J_10 - J_00*J_12;
2624
const double d22 = J_00*J_11 - J_01*J_10;
2626
// Compute determinant of Jacobian
2627
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
2629
// Compute inverse of Jacobian
2631
// Compute constants
2632
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
2633
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
2634
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
2636
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
2637
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
2638
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
2640
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
2641
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
2642
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
2644
// Get coordinates and map to the UFC reference element
2645
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
2646
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
2647
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
2649
// Map coordinates to the reference cube
2650
if (std::abs(y + z - 1.0) < 1e-08)
2653
x = -2.0 * x/(y + z - 1.0) - 1.0;
2654
if (std::abs(z - 1.0) < 1e-08)
2657
y = 2.0 * y/(1.0 - z) - 1.0;
2663
// Map degree of freedom to element degree of freedom
2664
const unsigned int dof = i;
2666
// Generate scalings
2667
const double scalings_y_0 = 1;
2668
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2669
const double scalings_z_0 = 1;
2670
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
2672
// Compute psitilde_a
2673
const double psitilde_a_0 = 1;
2674
const double psitilde_a_1 = x;
2676
// Compute psitilde_bs
2677
const double psitilde_bs_0_0 = 1;
2678
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2679
const double psitilde_bs_1_0 = 1;
2681
// Compute psitilde_cs
2682
const double psitilde_cs_00_0 = 1;
2683
const double psitilde_cs_00_1 = 2*z + 1;
2684
const double psitilde_cs_01_0 = 1;
2685
const double psitilde_cs_10_0 = 1;
2687
// Compute basisvalues
2688
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
2689
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
2690
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
2691
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
2693
// Table(s) of coefficients
2694
static const double coefficients0[4][4] = \
2695
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
2696
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
2697
{0.288675135, 0, 0.210818511, -0.0745355992},
2698
{0.288675135, 0, 0, 0.223606798}};
2700
// Extract relevant coefficients
2701
const double coeff0_0 = coefficients0[dof][0];
2702
const double coeff0_1 = coefficients0[dof][1];
2703
const double coeff0_2 = coefficients0[dof][2];
2704
const double coeff0_3 = coefficients0[dof][3];
2707
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
2710
/// Evaluate all basis functions at given point in cell
2711
virtual void evaluate_basis_all(double* values,
2712
const double* coordinates,
2713
const ufc::cell& c) const
2715
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2718
/// Evaluate order n derivatives of basis function i at given point in cell
2719
virtual void evaluate_basis_derivatives(unsigned int i,
2722
const double* coordinates,
2723
const ufc::cell& c) const
2725
// Extract vertex coordinates
2726
const double * const * element_coordinates = c.coordinates;
2728
// Compute Jacobian of affine map from reference cell
2729
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2730
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2731
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
2732
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2733
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2734
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
2735
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
2736
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
2737
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
2739
// Compute sub determinants
2740
const double d00 = J_11*J_22 - J_12*J_21;
2741
const double d01 = J_12*J_20 - J_10*J_22;
2742
const double d02 = J_10*J_21 - J_11*J_20;
2744
const double d10 = J_02*J_21 - J_01*J_22;
2745
const double d11 = J_00*J_22 - J_02*J_20;
2746
const double d12 = J_01*J_20 - J_00*J_21;
2748
const double d20 = J_01*J_12 - J_02*J_11;
2749
const double d21 = J_02*J_10 - J_00*J_12;
2750
const double d22 = J_00*J_11 - J_01*J_10;
2752
// Compute determinant of Jacobian
2753
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
2755
// Compute inverse of Jacobian
2757
// Compute constants
2758
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
2759
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
2760
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
2762
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
2763
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
2764
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
2766
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
2767
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
2768
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
2770
// Get coordinates and map to the UFC reference element
2771
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
2772
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
2773
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
2775
// Map coordinates to the reference cube
2776
if (std::abs(y + z - 1.0) < 1e-08)
2779
x = -2.0 * x/(y + z - 1.0) - 1.0;
2780
if (std::abs(z - 1.0) < 1e-08)
2783
y = 2.0 * y/(1.0 - z) - 1.0;
2786
// Compute number of derivatives
2787
unsigned int num_derivatives = 1;
2789
for (unsigned int j = 0; j < n; j++)
2790
num_derivatives *= 3;
2793
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2794
unsigned int **combinations = new unsigned int *[num_derivatives];
2796
for (unsigned int j = 0; j < num_derivatives; j++)
2798
combinations[j] = new unsigned int [n];
2799
for (unsigned int k = 0; k < n; k++)
2800
combinations[j][k] = 0;
2803
// Generate combinations of derivatives
2804
for (unsigned int row = 1; row < num_derivatives; row++)
2806
for (unsigned int num = 0; num < row; num++)
2808
for (unsigned int col = n-1; col+1 > 0; col--)
2810
if (combinations[row][col] + 1 > 2)
2811
combinations[row][col] = 0;
2814
combinations[row][col] += 1;
2821
// Compute inverse of Jacobian
2822
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
2824
// Declare transformation matrix
2825
// Declare pointer to two dimensional array and initialise
2826
double **transform = new double *[num_derivatives];
2828
for (unsigned int j = 0; j < num_derivatives; j++)
2830
transform[j] = new double [num_derivatives];
2831
for (unsigned int k = 0; k < num_derivatives; k++)
2832
transform[j][k] = 1;
2835
// Construct transformation matrix
2836
for (unsigned int row = 0; row < num_derivatives; row++)
2838
for (unsigned int col = 0; col < num_derivatives; col++)
2840
for (unsigned int k = 0; k < n; k++)
2841
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2846
for (unsigned int j = 0; j < 1*num_derivatives; j++)
2849
// Map degree of freedom to element degree of freedom
2850
const unsigned int dof = i;
2852
// Generate scalings
2853
const double scalings_y_0 = 1;
2854
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2855
const double scalings_z_0 = 1;
2856
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
2858
// Compute psitilde_a
2859
const double psitilde_a_0 = 1;
2860
const double psitilde_a_1 = x;
2862
// Compute psitilde_bs
2863
const double psitilde_bs_0_0 = 1;
2864
const double psitilde_bs_0_1 = 1.5*y + 0.5;
2865
const double psitilde_bs_1_0 = 1;
2867
// Compute psitilde_cs
2868
const double psitilde_cs_00_0 = 1;
2869
const double psitilde_cs_00_1 = 2*z + 1;
2870
const double psitilde_cs_01_0 = 1;
2871
const double psitilde_cs_10_0 = 1;
2873
// Compute basisvalues
2874
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
2875
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
2876
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
2877
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
2879
// Table(s) of coefficients
2880
static const double coefficients0[4][4] = \
2881
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
2882
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
2883
{0.288675135, 0, 0.210818511, -0.0745355992},
2884
{0.288675135, 0, 0, 0.223606798}};
2886
// Interesting (new) part
2887
// Tables of derivatives of the polynomial base (transpose)
2888
static const double dmats0[4][4] = \
2890
{6.32455532, 0, 0, 0},
2894
static const double dmats1[4][4] = \
2896
{3.16227766, 0, 0, 0},
2897
{5.47722558, 0, 0, 0},
2900
static const double dmats2[4][4] = \
2902
{3.16227766, 0, 0, 0},
2903
{1.82574186, 0, 0, 0},
2904
{5.16397779, 0, 0, 0}};
2906
// Compute reference derivatives
2907
// Declare pointer to array of derivatives on FIAT element
2908
double *derivatives = new double [num_derivatives];
2910
// Declare coefficients
2911
double coeff0_0 = 0;
2912
double coeff0_1 = 0;
2913
double coeff0_2 = 0;
2914
double coeff0_3 = 0;
2916
// Declare new coefficients
2917
double new_coeff0_0 = 0;
2918
double new_coeff0_1 = 0;
2919
double new_coeff0_2 = 0;
2920
double new_coeff0_3 = 0;
2922
// Loop possible derivatives
2923
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2925
// Get values from coefficients array
2926
new_coeff0_0 = coefficients0[dof][0];
2927
new_coeff0_1 = coefficients0[dof][1];
2928
new_coeff0_2 = coefficients0[dof][2];
2929
new_coeff0_3 = coefficients0[dof][3];
2931
// Loop derivative order
2932
for (unsigned int j = 0; j < n; j++)
2934
// Update old coefficients
2935
coeff0_0 = new_coeff0_0;
2936
coeff0_1 = new_coeff0_1;
2937
coeff0_2 = new_coeff0_2;
2938
coeff0_3 = new_coeff0_3;
2940
if(combinations[deriv_num][j] == 0)
2942
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
2943
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
2944
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
2945
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
2947
if(combinations[deriv_num][j] == 1)
2949
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
2950
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
2951
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
2952
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
2954
if(combinations[deriv_num][j] == 2)
2956
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
2957
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
2958
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
2959
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
2963
// Compute derivatives on reference element as dot product of coefficients and basisvalues
2964
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
2967
// Transform derivatives back to physical element
2968
for (unsigned int row = 0; row < num_derivatives; row++)
2970
for (unsigned int col = 0; col < num_derivatives; col++)
2972
values[row] += transform[row][col]*derivatives[col];
2975
// Delete pointer to array of derivatives on FIAT element
2976
delete [] derivatives;
2978
// Delete pointer to array of combinations of derivatives and transform
2979
for (unsigned int row = 0; row < num_derivatives; row++)
2981
delete [] combinations[row];
2982
delete [] transform[row];
2985
delete [] combinations;
2986
delete [] transform;
2989
/// Evaluate order n derivatives of all basis functions at given point in cell
2990
virtual void evaluate_basis_derivatives_all(unsigned int n,
2992
const double* coordinates,
2993
const ufc::cell& c) const
2995
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2998
/// Evaluate linear functional for dof i on the function f
2999
virtual double evaluate_dof(unsigned int i,
3000
const ufc::function& f,
3001
const ufc::cell& c) const
3003
// The reference points, direction and weights:
3004
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
3005
static const double W[4][1] = {{1}, {1}, {1}, {1}};
3006
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
3008
const double * const * x = c.coordinates;
3009
double result = 0.0;
3010
// Iterate over the points:
3011
// Evaluate basis functions for affine mapping
3012
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
3013
const double w1 = X[i][0][0];
3014
const double w2 = X[i][0][1];
3015
const double w3 = X[i][0][2];
3017
// Compute affine mapping y = F(X)
3019
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
3020
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
3021
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
3023
// Evaluate function at physical points
3025
f.evaluate(values, y, c);
3027
// Map function values using appropriate mapping
3028
// Affine map: Do nothing
3030
// Note that we do not map the weights (yet).
3032
// Take directional components
3033
for(int k = 0; k < 1; k++)
3034
result += values[k]*D[i][0][k];
3035
// Multiply by weights
3041
/// Evaluate linear functionals for all dofs on the function f
3042
virtual void evaluate_dofs(double* values,
3043
const ufc::function& f,
3044
const ufc::cell& c) const
3046
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3049
/// Interpolate vertex values from dof values
3050
virtual void interpolate_vertex_values(double* vertex_values,
3051
const double* dof_values,
3052
const ufc::cell& c) const
3054
// Evaluate at vertices and use affine mapping
3055
vertex_values[0] = dof_values[0];
3056
vertex_values[1] = dof_values[1];
3057
vertex_values[2] = dof_values[2];
3058
vertex_values[3] = dof_values[3];
3061
/// Return the number of sub elements (for a mixed element)
3062
virtual unsigned int num_sub_elements() const
3067
/// Create a new finite element for sub element i (for a mixed element)
3068
virtual ufc::finite_element* create_sub_element(unsigned int i) const
3070
return new hyperelasticity_0_finite_element_1_0();
3075
/// This class defines the interface for a finite element.
3077
class hyperelasticity_0_finite_element_1_1: public ufc::finite_element
3082
hyperelasticity_0_finite_element_1_1() : ufc::finite_element()
3088
virtual ~hyperelasticity_0_finite_element_1_1()
3093
/// Return a string identifying the finite element
3094
virtual const char* signature() const
3096
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
3099
/// Return the cell shape
3100
virtual ufc::shape cell_shape() const
3102
return ufc::tetrahedron;
3105
/// Return the dimension of the finite element function space
3106
virtual unsigned int space_dimension() const
3111
/// Return the rank of the value space
3112
virtual unsigned int value_rank() const
3117
/// Return the dimension of the value space for axis i
3118
virtual unsigned int value_dimension(unsigned int i) const
3123
/// Evaluate basis function i at given point in cell
3124
virtual void evaluate_basis(unsigned int i,
3126
const double* coordinates,
3127
const ufc::cell& c) const
3129
// Extract vertex coordinates
3130
const double * const * element_coordinates = c.coordinates;
3132
// Compute Jacobian of affine map from reference cell
3133
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3134
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3135
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
3136
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3137
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3138
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
3139
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
3140
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
3141
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
3143
// Compute sub determinants
3144
const double d00 = J_11*J_22 - J_12*J_21;
3145
const double d01 = J_12*J_20 - J_10*J_22;
3146
const double d02 = J_10*J_21 - J_11*J_20;
3148
const double d10 = J_02*J_21 - J_01*J_22;
3149
const double d11 = J_00*J_22 - J_02*J_20;
3150
const double d12 = J_01*J_20 - J_00*J_21;
3152
const double d20 = J_01*J_12 - J_02*J_11;
3153
const double d21 = J_02*J_10 - J_00*J_12;
3154
const double d22 = J_00*J_11 - J_01*J_10;
3156
// Compute determinant of Jacobian
3157
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
3159
// Compute inverse of Jacobian
3161
// Compute constants
3162
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
3163
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
3164
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
3166
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
3167
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
3168
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
3170
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
3171
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
3172
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
3174
// Get coordinates and map to the UFC reference element
3175
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
3176
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
3177
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
3179
// Map coordinates to the reference cube
3180
if (std::abs(y + z - 1.0) < 1e-08)
3183
x = -2.0 * x/(y + z - 1.0) - 1.0;
3184
if (std::abs(z - 1.0) < 1e-08)
3187
y = 2.0 * y/(1.0 - z) - 1.0;
3193
// Map degree of freedom to element degree of freedom
3194
const unsigned int dof = i;
3196
// Generate scalings
3197
const double scalings_y_0 = 1;
3198
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3199
const double scalings_z_0 = 1;
3200
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
3202
// Compute psitilde_a
3203
const double psitilde_a_0 = 1;
3204
const double psitilde_a_1 = x;
3206
// Compute psitilde_bs
3207
const double psitilde_bs_0_0 = 1;
3208
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3209
const double psitilde_bs_1_0 = 1;
3211
// Compute psitilde_cs
3212
const double psitilde_cs_00_0 = 1;
3213
const double psitilde_cs_00_1 = 2*z + 1;
3214
const double psitilde_cs_01_0 = 1;
3215
const double psitilde_cs_10_0 = 1;
3217
// Compute basisvalues
3218
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
3219
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
3220
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
3221
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
3223
// Table(s) of coefficients
3224
static const double coefficients0[4][4] = \
3225
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
3226
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
3227
{0.288675135, 0, 0.210818511, -0.0745355992},
3228
{0.288675135, 0, 0, 0.223606798}};
3230
// Extract relevant coefficients
3231
const double coeff0_0 = coefficients0[dof][0];
3232
const double coeff0_1 = coefficients0[dof][1];
3233
const double coeff0_2 = coefficients0[dof][2];
3234
const double coeff0_3 = coefficients0[dof][3];
3237
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
3240
/// Evaluate all basis functions at given point in cell
3241
virtual void evaluate_basis_all(double* values,
3242
const double* coordinates,
3243
const ufc::cell& c) const
3245
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3248
/// Evaluate order n derivatives of basis function i at given point in cell
3249
virtual void evaluate_basis_derivatives(unsigned int i,
3252
const double* coordinates,
3253
const ufc::cell& c) const
3255
// Extract vertex coordinates
3256
const double * const * element_coordinates = c.coordinates;
3258
// Compute Jacobian of affine map from reference cell
3259
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3260
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3261
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
3262
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3263
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3264
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
3265
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
3266
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
3267
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
3269
// Compute sub determinants
3270
const double d00 = J_11*J_22 - J_12*J_21;
3271
const double d01 = J_12*J_20 - J_10*J_22;
3272
const double d02 = J_10*J_21 - J_11*J_20;
3274
const double d10 = J_02*J_21 - J_01*J_22;
3275
const double d11 = J_00*J_22 - J_02*J_20;
3276
const double d12 = J_01*J_20 - J_00*J_21;
3278
const double d20 = J_01*J_12 - J_02*J_11;
3279
const double d21 = J_02*J_10 - J_00*J_12;
3280
const double d22 = J_00*J_11 - J_01*J_10;
3282
// Compute determinant of Jacobian
3283
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
3285
// Compute inverse of Jacobian
3287
// Compute constants
3288
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
3289
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
3290
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
3292
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
3293
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
3294
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
3296
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
3297
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
3298
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
3300
// Get coordinates and map to the UFC reference element
3301
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
3302
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
3303
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
3305
// Map coordinates to the reference cube
3306
if (std::abs(y + z - 1.0) < 1e-08)
3309
x = -2.0 * x/(y + z - 1.0) - 1.0;
3310
if (std::abs(z - 1.0) < 1e-08)
3313
y = 2.0 * y/(1.0 - z) - 1.0;
3316
// Compute number of derivatives
3317
unsigned int num_derivatives = 1;
3319
for (unsigned int j = 0; j < n; j++)
3320
num_derivatives *= 3;
3323
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3324
unsigned int **combinations = new unsigned int *[num_derivatives];
3326
for (unsigned int j = 0; j < num_derivatives; j++)
3328
combinations[j] = new unsigned int [n];
3329
for (unsigned int k = 0; k < n; k++)
3330
combinations[j][k] = 0;
3333
// Generate combinations of derivatives
3334
for (unsigned int row = 1; row < num_derivatives; row++)
3336
for (unsigned int num = 0; num < row; num++)
3338
for (unsigned int col = n-1; col+1 > 0; col--)
3340
if (combinations[row][col] + 1 > 2)
3341
combinations[row][col] = 0;
3344
combinations[row][col] += 1;
3351
// Compute inverse of Jacobian
3352
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
3354
// Declare transformation matrix
3355
// Declare pointer to two dimensional array and initialise
3356
double **transform = new double *[num_derivatives];
3358
for (unsigned int j = 0; j < num_derivatives; j++)
3360
transform[j] = new double [num_derivatives];
3361
for (unsigned int k = 0; k < num_derivatives; k++)
3362
transform[j][k] = 1;
3365
// Construct transformation matrix
3366
for (unsigned int row = 0; row < num_derivatives; row++)
3368
for (unsigned int col = 0; col < num_derivatives; col++)
3370
for (unsigned int k = 0; k < n; k++)
3371
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3376
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3379
// Map degree of freedom to element degree of freedom
3380
const unsigned int dof = i;
3382
// Generate scalings
3383
const double scalings_y_0 = 1;
3384
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3385
const double scalings_z_0 = 1;
3386
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
3388
// Compute psitilde_a
3389
const double psitilde_a_0 = 1;
3390
const double psitilde_a_1 = x;
3392
// Compute psitilde_bs
3393
const double psitilde_bs_0_0 = 1;
3394
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3395
const double psitilde_bs_1_0 = 1;
3397
// Compute psitilde_cs
3398
const double psitilde_cs_00_0 = 1;
3399
const double psitilde_cs_00_1 = 2*z + 1;
3400
const double psitilde_cs_01_0 = 1;
3401
const double psitilde_cs_10_0 = 1;
3403
// Compute basisvalues
3404
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
3405
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
3406
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
3407
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
3409
// Table(s) of coefficients
3410
static const double coefficients0[4][4] = \
3411
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
3412
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
3413
{0.288675135, 0, 0.210818511, -0.0745355992},
3414
{0.288675135, 0, 0, 0.223606798}};
3416
// Interesting (new) part
3417
// Tables of derivatives of the polynomial base (transpose)
3418
static const double dmats0[4][4] = \
3420
{6.32455532, 0, 0, 0},
3424
static const double dmats1[4][4] = \
3426
{3.16227766, 0, 0, 0},
3427
{5.47722558, 0, 0, 0},
3430
static const double dmats2[4][4] = \
3432
{3.16227766, 0, 0, 0},
3433
{1.82574186, 0, 0, 0},
3434
{5.16397779, 0, 0, 0}};
3436
// Compute reference derivatives
3437
// Declare pointer to array of derivatives on FIAT element
3438
double *derivatives = new double [num_derivatives];
3440
// Declare coefficients
3441
double coeff0_0 = 0;
3442
double coeff0_1 = 0;
3443
double coeff0_2 = 0;
3444
double coeff0_3 = 0;
3446
// Declare new coefficients
3447
double new_coeff0_0 = 0;
3448
double new_coeff0_1 = 0;
3449
double new_coeff0_2 = 0;
3450
double new_coeff0_3 = 0;
3452
// Loop possible derivatives
3453
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3455
// Get values from coefficients array
3456
new_coeff0_0 = coefficients0[dof][0];
3457
new_coeff0_1 = coefficients0[dof][1];
3458
new_coeff0_2 = coefficients0[dof][2];
3459
new_coeff0_3 = coefficients0[dof][3];
3461
// Loop derivative order
3462
for (unsigned int j = 0; j < n; j++)
3464
// Update old coefficients
3465
coeff0_0 = new_coeff0_0;
3466
coeff0_1 = new_coeff0_1;
3467
coeff0_2 = new_coeff0_2;
3468
coeff0_3 = new_coeff0_3;
3470
if(combinations[deriv_num][j] == 0)
3472
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
3473
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
3474
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
3475
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
3477
if(combinations[deriv_num][j] == 1)
3479
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
3480
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
3481
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
3482
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
3484
if(combinations[deriv_num][j] == 2)
3486
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
3487
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
3488
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
3489
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
3493
// Compute derivatives on reference element as dot product of coefficients and basisvalues
3494
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
3497
// Transform derivatives back to physical element
3498
for (unsigned int row = 0; row < num_derivatives; row++)
3500
for (unsigned int col = 0; col < num_derivatives; col++)
3502
values[row] += transform[row][col]*derivatives[col];
3505
// Delete pointer to array of derivatives on FIAT element
3506
delete [] derivatives;
3508
// Delete pointer to array of combinations of derivatives and transform
3509
for (unsigned int row = 0; row < num_derivatives; row++)
3511
delete [] combinations[row];
3512
delete [] transform[row];
3515
delete [] combinations;
3516
delete [] transform;
3519
/// Evaluate order n derivatives of all basis functions at given point in cell
3520
virtual void evaluate_basis_derivatives_all(unsigned int n,
3522
const double* coordinates,
3523
const ufc::cell& c) const
3525
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3528
/// Evaluate linear functional for dof i on the function f
3529
virtual double evaluate_dof(unsigned int i,
3530
const ufc::function& f,
3531
const ufc::cell& c) const
3533
// The reference points, direction and weights:
3534
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
3535
static const double W[4][1] = {{1}, {1}, {1}, {1}};
3536
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
3538
const double * const * x = c.coordinates;
3539
double result = 0.0;
3540
// Iterate over the points:
3541
// Evaluate basis functions for affine mapping
3542
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
3543
const double w1 = X[i][0][0];
3544
const double w2 = X[i][0][1];
3545
const double w3 = X[i][0][2];
3547
// Compute affine mapping y = F(X)
3549
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
3550
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
3551
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
3553
// Evaluate function at physical points
3555
f.evaluate(values, y, c);
3557
// Map function values using appropriate mapping
3558
// Affine map: Do nothing
3560
// Note that we do not map the weights (yet).
3562
// Take directional components
3563
for(int k = 0; k < 1; k++)
3564
result += values[k]*D[i][0][k];
3565
// Multiply by weights
3571
/// Evaluate linear functionals for all dofs on the function f
3572
virtual void evaluate_dofs(double* values,
3573
const ufc::function& f,
3574
const ufc::cell& c) const
3576
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3579
/// Interpolate vertex values from dof values
3580
virtual void interpolate_vertex_values(double* vertex_values,
3581
const double* dof_values,
3582
const ufc::cell& c) const
3584
// Evaluate at vertices and use affine mapping
3585
vertex_values[0] = dof_values[0];
3586
vertex_values[1] = dof_values[1];
3587
vertex_values[2] = dof_values[2];
3588
vertex_values[3] = dof_values[3];
3591
/// Return the number of sub elements (for a mixed element)
3592
virtual unsigned int num_sub_elements() const
3597
/// Create a new finite element for sub element i (for a mixed element)
3598
virtual ufc::finite_element* create_sub_element(unsigned int i) const
3600
return new hyperelasticity_0_finite_element_1_1();
3605
/// This class defines the interface for a finite element.
3607
class hyperelasticity_0_finite_element_1_2: public ufc::finite_element
3612
hyperelasticity_0_finite_element_1_2() : ufc::finite_element()
3618
virtual ~hyperelasticity_0_finite_element_1_2()
3623
/// Return a string identifying the finite element
3624
virtual const char* signature() const
3626
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
3629
/// Return the cell shape
3630
virtual ufc::shape cell_shape() const
3632
return ufc::tetrahedron;
3635
/// Return the dimension of the finite element function space
3636
virtual unsigned int space_dimension() const
3641
/// Return the rank of the value space
3642
virtual unsigned int value_rank() const
3647
/// Return the dimension of the value space for axis i
3648
virtual unsigned int value_dimension(unsigned int i) const
3653
/// Evaluate basis function i at given point in cell
3654
virtual void evaluate_basis(unsigned int i,
3656
const double* coordinates,
3657
const ufc::cell& c) const
3659
// Extract vertex coordinates
3660
const double * const * element_coordinates = c.coordinates;
3662
// Compute Jacobian of affine map from reference cell
3663
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3664
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3665
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
3666
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3667
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3668
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
3669
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
3670
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
3671
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
3673
// Compute sub determinants
3674
const double d00 = J_11*J_22 - J_12*J_21;
3675
const double d01 = J_12*J_20 - J_10*J_22;
3676
const double d02 = J_10*J_21 - J_11*J_20;
3678
const double d10 = J_02*J_21 - J_01*J_22;
3679
const double d11 = J_00*J_22 - J_02*J_20;
3680
const double d12 = J_01*J_20 - J_00*J_21;
3682
const double d20 = J_01*J_12 - J_02*J_11;
3683
const double d21 = J_02*J_10 - J_00*J_12;
3684
const double d22 = J_00*J_11 - J_01*J_10;
3686
// Compute determinant of Jacobian
3687
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
3689
// Compute inverse of Jacobian
3691
// Compute constants
3692
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
3693
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
3694
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
3696
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
3697
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
3698
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
3700
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
3701
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
3702
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
3704
// Get coordinates and map to the UFC reference element
3705
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
3706
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
3707
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
3709
// Map coordinates to the reference cube
3710
if (std::abs(y + z - 1.0) < 1e-08)
3713
x = -2.0 * x/(y + z - 1.0) - 1.0;
3714
if (std::abs(z - 1.0) < 1e-08)
3717
y = 2.0 * y/(1.0 - z) - 1.0;
3723
// Map degree of freedom to element degree of freedom
3724
const unsigned int dof = i;
3726
// Generate scalings
3727
const double scalings_y_0 = 1;
3728
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3729
const double scalings_z_0 = 1;
3730
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
3732
// Compute psitilde_a
3733
const double psitilde_a_0 = 1;
3734
const double psitilde_a_1 = x;
3736
// Compute psitilde_bs
3737
const double psitilde_bs_0_0 = 1;
3738
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3739
const double psitilde_bs_1_0 = 1;
3741
// Compute psitilde_cs
3742
const double psitilde_cs_00_0 = 1;
3743
const double psitilde_cs_00_1 = 2*z + 1;
3744
const double psitilde_cs_01_0 = 1;
3745
const double psitilde_cs_10_0 = 1;
3747
// Compute basisvalues
3748
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
3749
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
3750
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
3751
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
3753
// Table(s) of coefficients
3754
static const double coefficients0[4][4] = \
3755
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
3756
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
3757
{0.288675135, 0, 0.210818511, -0.0745355992},
3758
{0.288675135, 0, 0, 0.223606798}};
3760
// Extract relevant coefficients
3761
const double coeff0_0 = coefficients0[dof][0];
3762
const double coeff0_1 = coefficients0[dof][1];
3763
const double coeff0_2 = coefficients0[dof][2];
3764
const double coeff0_3 = coefficients0[dof][3];
3767
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
3770
/// Evaluate all basis functions at given point in cell
3771
virtual void evaluate_basis_all(double* values,
3772
const double* coordinates,
3773
const ufc::cell& c) const
3775
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3778
/// Evaluate order n derivatives of basis function i at given point in cell
3779
virtual void evaluate_basis_derivatives(unsigned int i,
3782
const double* coordinates,
3783
const ufc::cell& c) const
3785
// Extract vertex coordinates
3786
const double * const * element_coordinates = c.coordinates;
3788
// Compute Jacobian of affine map from reference cell
3789
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3790
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3791
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
3792
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3793
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3794
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
3795
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
3796
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
3797
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
3799
// Compute sub determinants
3800
const double d00 = J_11*J_22 - J_12*J_21;
3801
const double d01 = J_12*J_20 - J_10*J_22;
3802
const double d02 = J_10*J_21 - J_11*J_20;
3804
const double d10 = J_02*J_21 - J_01*J_22;
3805
const double d11 = J_00*J_22 - J_02*J_20;
3806
const double d12 = J_01*J_20 - J_00*J_21;
3808
const double d20 = J_01*J_12 - J_02*J_11;
3809
const double d21 = J_02*J_10 - J_00*J_12;
3810
const double d22 = J_00*J_11 - J_01*J_10;
3812
// Compute determinant of Jacobian
3813
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
3815
// Compute inverse of Jacobian
3817
// Compute constants
3818
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
3819
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
3820
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
3822
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
3823
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
3824
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
3826
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
3827
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
3828
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
3830
// Get coordinates and map to the UFC reference element
3831
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
3832
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
3833
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
3835
// Map coordinates to the reference cube
3836
if (std::abs(y + z - 1.0) < 1e-08)
3839
x = -2.0 * x/(y + z - 1.0) - 1.0;
3840
if (std::abs(z - 1.0) < 1e-08)
3843
y = 2.0 * y/(1.0 - z) - 1.0;
3846
// Compute number of derivatives
3847
unsigned int num_derivatives = 1;
3849
for (unsigned int j = 0; j < n; j++)
3850
num_derivatives *= 3;
3853
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3854
unsigned int **combinations = new unsigned int *[num_derivatives];
3856
for (unsigned int j = 0; j < num_derivatives; j++)
3858
combinations[j] = new unsigned int [n];
3859
for (unsigned int k = 0; k < n; k++)
3860
combinations[j][k] = 0;
3863
// Generate combinations of derivatives
3864
for (unsigned int row = 1; row < num_derivatives; row++)
3866
for (unsigned int num = 0; num < row; num++)
3868
for (unsigned int col = n-1; col+1 > 0; col--)
3870
if (combinations[row][col] + 1 > 2)
3871
combinations[row][col] = 0;
3874
combinations[row][col] += 1;
3881
// Compute inverse of Jacobian
3882
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
3884
// Declare transformation matrix
3885
// Declare pointer to two dimensional array and initialise
3886
double **transform = new double *[num_derivatives];
3888
for (unsigned int j = 0; j < num_derivatives; j++)
3890
transform[j] = new double [num_derivatives];
3891
for (unsigned int k = 0; k < num_derivatives; k++)
3892
transform[j][k] = 1;
3895
// Construct transformation matrix
3896
for (unsigned int row = 0; row < num_derivatives; row++)
3898
for (unsigned int col = 0; col < num_derivatives; col++)
3900
for (unsigned int k = 0; k < n; k++)
3901
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3906
for (unsigned int j = 0; j < 1*num_derivatives; j++)
3909
// Map degree of freedom to element degree of freedom
3910
const unsigned int dof = i;
3912
// Generate scalings
3913
const double scalings_y_0 = 1;
3914
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3915
const double scalings_z_0 = 1;
3916
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
3918
// Compute psitilde_a
3919
const double psitilde_a_0 = 1;
3920
const double psitilde_a_1 = x;
3922
// Compute psitilde_bs
3923
const double psitilde_bs_0_0 = 1;
3924
const double psitilde_bs_0_1 = 1.5*y + 0.5;
3925
const double psitilde_bs_1_0 = 1;
3927
// Compute psitilde_cs
3928
const double psitilde_cs_00_0 = 1;
3929
const double psitilde_cs_00_1 = 2*z + 1;
3930
const double psitilde_cs_01_0 = 1;
3931
const double psitilde_cs_10_0 = 1;
3933
// Compute basisvalues
3934
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
3935
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
3936
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
3937
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
3939
// Table(s) of coefficients
3940
static const double coefficients0[4][4] = \
3941
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
3942
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
3943
{0.288675135, 0, 0.210818511, -0.0745355992},
3944
{0.288675135, 0, 0, 0.223606798}};
3946
// Interesting (new) part
3947
// Tables of derivatives of the polynomial base (transpose)
3948
static const double dmats0[4][4] = \
3950
{6.32455532, 0, 0, 0},
3954
static const double dmats1[4][4] = \
3956
{3.16227766, 0, 0, 0},
3957
{5.47722558, 0, 0, 0},
3960
static const double dmats2[4][4] = \
3962
{3.16227766, 0, 0, 0},
3963
{1.82574186, 0, 0, 0},
3964
{5.16397779, 0, 0, 0}};
3966
// Compute reference derivatives
3967
// Declare pointer to array of derivatives on FIAT element
3968
double *derivatives = new double [num_derivatives];
3970
// Declare coefficients
3971
double coeff0_0 = 0;
3972
double coeff0_1 = 0;
3973
double coeff0_2 = 0;
3974
double coeff0_3 = 0;
3976
// Declare new coefficients
3977
double new_coeff0_0 = 0;
3978
double new_coeff0_1 = 0;
3979
double new_coeff0_2 = 0;
3980
double new_coeff0_3 = 0;
3982
// Loop possible derivatives
3983
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3985
// Get values from coefficients array
3986
new_coeff0_0 = coefficients0[dof][0];
3987
new_coeff0_1 = coefficients0[dof][1];
3988
new_coeff0_2 = coefficients0[dof][2];
3989
new_coeff0_3 = coefficients0[dof][3];
3991
// Loop derivative order
3992
for (unsigned int j = 0; j < n; j++)
3994
// Update old coefficients
3995
coeff0_0 = new_coeff0_0;
3996
coeff0_1 = new_coeff0_1;
3997
coeff0_2 = new_coeff0_2;
3998
coeff0_3 = new_coeff0_3;
4000
if(combinations[deriv_num][j] == 0)
4002
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
4003
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
4004
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
4005
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
4007
if(combinations[deriv_num][j] == 1)
4009
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
4010
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
4011
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
4012
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
4014
if(combinations[deriv_num][j] == 2)
4016
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
4017
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
4018
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
4019
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
4023
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4024
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
4027
// Transform derivatives back to physical element
4028
for (unsigned int row = 0; row < num_derivatives; row++)
4030
for (unsigned int col = 0; col < num_derivatives; col++)
4032
values[row] += transform[row][col]*derivatives[col];
4035
// Delete pointer to array of derivatives on FIAT element
4036
delete [] derivatives;
4038
// Delete pointer to array of combinations of derivatives and transform
4039
for (unsigned int row = 0; row < num_derivatives; row++)
4041
delete [] combinations[row];
4042
delete [] transform[row];
4045
delete [] combinations;
4046
delete [] transform;
4049
/// Evaluate order n derivatives of all basis functions at given point in cell
4050
virtual void evaluate_basis_derivatives_all(unsigned int n,
4052
const double* coordinates,
4053
const ufc::cell& c) const
4055
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4058
/// Evaluate linear functional for dof i on the function f
4059
virtual double evaluate_dof(unsigned int i,
4060
const ufc::function& f,
4061
const ufc::cell& c) const
4063
// The reference points, direction and weights:
4064
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
4065
static const double W[4][1] = {{1}, {1}, {1}, {1}};
4066
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
4068
const double * const * x = c.coordinates;
4069
double result = 0.0;
4070
// Iterate over the points:
4071
// Evaluate basis functions for affine mapping
4072
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
4073
const double w1 = X[i][0][0];
4074
const double w2 = X[i][0][1];
4075
const double w3 = X[i][0][2];
4077
// Compute affine mapping y = F(X)
4079
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
4080
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
4081
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
4083
// Evaluate function at physical points
4085
f.evaluate(values, y, c);
4087
// Map function values using appropriate mapping
4088
// Affine map: Do nothing
4090
// Note that we do not map the weights (yet).
4092
// Take directional components
4093
for(int k = 0; k < 1; k++)
4094
result += values[k]*D[i][0][k];
4095
// Multiply by weights
4101
/// Evaluate linear functionals for all dofs on the function f
4102
virtual void evaluate_dofs(double* values,
4103
const ufc::function& f,
4104
const ufc::cell& c) const
4106
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4109
/// Interpolate vertex values from dof values
4110
virtual void interpolate_vertex_values(double* vertex_values,
4111
const double* dof_values,
4112
const ufc::cell& c) const
4114
// Evaluate at vertices and use affine mapping
4115
vertex_values[0] = dof_values[0];
4116
vertex_values[1] = dof_values[1];
4117
vertex_values[2] = dof_values[2];
4118
vertex_values[3] = dof_values[3];
4121
/// Return the number of sub elements (for a mixed element)
4122
virtual unsigned int num_sub_elements() const
4127
/// Create a new finite element for sub element i (for a mixed element)
4128
virtual ufc::finite_element* create_sub_element(unsigned int i) const
4130
return new hyperelasticity_0_finite_element_1_2();
4135
/// This class defines the interface for a finite element.
4137
class hyperelasticity_0_finite_element_1: public ufc::finite_element
4142
hyperelasticity_0_finite_element_1() : ufc::finite_element()
4148
virtual ~hyperelasticity_0_finite_element_1()
4153
/// Return a string identifying the finite element
4154
virtual const char* signature() const
4156
return "VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
4159
/// Return the cell shape
4160
virtual ufc::shape cell_shape() const
4162
return ufc::tetrahedron;
4165
/// Return the dimension of the finite element function space
4166
virtual unsigned int space_dimension() const
4171
/// Return the rank of the value space
4172
virtual unsigned int value_rank() const
4177
/// Return the dimension of the value space for axis i
4178
virtual unsigned int value_dimension(unsigned int i) const
4183
/// Evaluate basis function i at given point in cell
4184
virtual void evaluate_basis(unsigned int i,
4186
const double* coordinates,
4187
const ufc::cell& c) const
4189
// Extract vertex coordinates
4190
const double * const * element_coordinates = c.coordinates;
4192
// Compute Jacobian of affine map from reference cell
4193
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4194
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4195
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
4196
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4197
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4198
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
4199
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
4200
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
4201
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
4203
// Compute sub determinants
4204
const double d00 = J_11*J_22 - J_12*J_21;
4205
const double d01 = J_12*J_20 - J_10*J_22;
4206
const double d02 = J_10*J_21 - J_11*J_20;
4208
const double d10 = J_02*J_21 - J_01*J_22;
4209
const double d11 = J_00*J_22 - J_02*J_20;
4210
const double d12 = J_01*J_20 - J_00*J_21;
4212
const double d20 = J_01*J_12 - J_02*J_11;
4213
const double d21 = J_02*J_10 - J_00*J_12;
4214
const double d22 = J_00*J_11 - J_01*J_10;
4216
// Compute determinant of Jacobian
4217
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
4219
// Compute inverse of Jacobian
4221
// Compute constants
4222
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
4223
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
4224
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
4226
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
4227
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
4228
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
4230
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
4231
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
4232
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
4234
// Get coordinates and map to the UFC reference element
4235
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
4236
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
4237
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
4239
// Map coordinates to the reference cube
4240
if (std::abs(y + z - 1.0) < 1e-08)
4243
x = -2.0 * x/(y + z - 1.0) - 1.0;
4244
if (std::abs(z - 1.0) < 1e-08)
4247
y = 2.0 * y/(1.0 - z) - 1.0;
4255
if (0 <= i && i <= 3)
4257
// Map degree of freedom to element degree of freedom
4258
const unsigned int dof = i;
4260
// Generate scalings
4261
const double scalings_y_0 = 1;
4262
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4263
const double scalings_z_0 = 1;
4264
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
4266
// Compute psitilde_a
4267
const double psitilde_a_0 = 1;
4268
const double psitilde_a_1 = x;
4270
// Compute psitilde_bs
4271
const double psitilde_bs_0_0 = 1;
4272
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4273
const double psitilde_bs_1_0 = 1;
4275
// Compute psitilde_cs
4276
const double psitilde_cs_00_0 = 1;
4277
const double psitilde_cs_00_1 = 2*z + 1;
4278
const double psitilde_cs_01_0 = 1;
4279
const double psitilde_cs_10_0 = 1;
4281
// Compute basisvalues
4282
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
4283
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
4284
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
4285
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
4287
// Table(s) of coefficients
4288
static const double coefficients0[4][4] = \
4289
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
4290
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
4291
{0.288675135, 0, 0.210818511, -0.0745355992},
4292
{0.288675135, 0, 0, 0.223606798}};
4294
// Extract relevant coefficients
4295
const double coeff0_0 = coefficients0[dof][0];
4296
const double coeff0_1 = coefficients0[dof][1];
4297
const double coeff0_2 = coefficients0[dof][2];
4298
const double coeff0_3 = coefficients0[dof][3];
4301
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
4304
if (4 <= i && i <= 7)
4306
// Map degree of freedom to element degree of freedom
4307
const unsigned int dof = i - 4;
4309
// Generate scalings
4310
const double scalings_y_0 = 1;
4311
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4312
const double scalings_z_0 = 1;
4313
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
4315
// Compute psitilde_a
4316
const double psitilde_a_0 = 1;
4317
const double psitilde_a_1 = x;
4319
// Compute psitilde_bs
4320
const double psitilde_bs_0_0 = 1;
4321
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4322
const double psitilde_bs_1_0 = 1;
4324
// Compute psitilde_cs
4325
const double psitilde_cs_00_0 = 1;
4326
const double psitilde_cs_00_1 = 2*z + 1;
4327
const double psitilde_cs_01_0 = 1;
4328
const double psitilde_cs_10_0 = 1;
4330
// Compute basisvalues
4331
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
4332
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
4333
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
4334
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
4336
// Table(s) of coefficients
4337
static const double coefficients0[4][4] = \
4338
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
4339
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
4340
{0.288675135, 0, 0.210818511, -0.0745355992},
4341
{0.288675135, 0, 0, 0.223606798}};
4343
// Extract relevant coefficients
4344
const double coeff0_0 = coefficients0[dof][0];
4345
const double coeff0_1 = coefficients0[dof][1];
4346
const double coeff0_2 = coefficients0[dof][2];
4347
const double coeff0_3 = coefficients0[dof][3];
4350
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
4353
if (8 <= i && i <= 11)
4355
// Map degree of freedom to element degree of freedom
4356
const unsigned int dof = i - 8;
4358
// Generate scalings
4359
const double scalings_y_0 = 1;
4360
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4361
const double scalings_z_0 = 1;
4362
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
4364
// Compute psitilde_a
4365
const double psitilde_a_0 = 1;
4366
const double psitilde_a_1 = x;
4368
// Compute psitilde_bs
4369
const double psitilde_bs_0_0 = 1;
4370
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4371
const double psitilde_bs_1_0 = 1;
4373
// Compute psitilde_cs
4374
const double psitilde_cs_00_0 = 1;
4375
const double psitilde_cs_00_1 = 2*z + 1;
4376
const double psitilde_cs_01_0 = 1;
4377
const double psitilde_cs_10_0 = 1;
4379
// Compute basisvalues
4380
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
4381
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
4382
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
4383
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
4385
// Table(s) of coefficients
4386
static const double coefficients0[4][4] = \
4387
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
4388
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
4389
{0.288675135, 0, 0.210818511, -0.0745355992},
4390
{0.288675135, 0, 0, 0.223606798}};
4392
// Extract relevant coefficients
4393
const double coeff0_0 = coefficients0[dof][0];
4394
const double coeff0_1 = coefficients0[dof][1];
4395
const double coeff0_2 = coefficients0[dof][2];
4396
const double coeff0_3 = coefficients0[dof][3];
4399
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
4404
/// Evaluate all basis functions at given point in cell
4405
virtual void evaluate_basis_all(double* values,
4406
const double* coordinates,
4407
const ufc::cell& c) const
4409
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4412
/// Evaluate order n derivatives of basis function i at given point in cell
4413
virtual void evaluate_basis_derivatives(unsigned int i,
4416
const double* coordinates,
4417
const ufc::cell& c) const
4419
// Extract vertex coordinates
4420
const double * const * element_coordinates = c.coordinates;
4422
// Compute Jacobian of affine map from reference cell
4423
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4424
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4425
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
4426
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4427
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4428
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
4429
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
4430
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
4431
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
4433
// Compute sub determinants
4434
const double d00 = J_11*J_22 - J_12*J_21;
4435
const double d01 = J_12*J_20 - J_10*J_22;
4436
const double d02 = J_10*J_21 - J_11*J_20;
4438
const double d10 = J_02*J_21 - J_01*J_22;
4439
const double d11 = J_00*J_22 - J_02*J_20;
4440
const double d12 = J_01*J_20 - J_00*J_21;
4442
const double d20 = J_01*J_12 - J_02*J_11;
4443
const double d21 = J_02*J_10 - J_00*J_12;
4444
const double d22 = J_00*J_11 - J_01*J_10;
4446
// Compute determinant of Jacobian
4447
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
4449
// Compute inverse of Jacobian
4451
// Compute constants
4452
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
4453
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
4454
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
4456
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
4457
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
4458
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
4460
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
4461
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
4462
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
4464
// Get coordinates and map to the UFC reference element
4465
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
4466
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
4467
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
4469
// Map coordinates to the reference cube
4470
if (std::abs(y + z - 1.0) < 1e-08)
4473
x = -2.0 * x/(y + z - 1.0) - 1.0;
4474
if (std::abs(z - 1.0) < 1e-08)
4477
y = 2.0 * y/(1.0 - z) - 1.0;
4480
// Compute number of derivatives
4481
unsigned int num_derivatives = 1;
4483
for (unsigned int j = 0; j < n; j++)
4484
num_derivatives *= 3;
4487
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4488
unsigned int **combinations = new unsigned int *[num_derivatives];
4490
for (unsigned int j = 0; j < num_derivatives; j++)
4492
combinations[j] = new unsigned int [n];
4493
for (unsigned int k = 0; k < n; k++)
4494
combinations[j][k] = 0;
4497
// Generate combinations of derivatives
4498
for (unsigned int row = 1; row < num_derivatives; row++)
4500
for (unsigned int num = 0; num < row; num++)
4502
for (unsigned int col = n-1; col+1 > 0; col--)
4504
if (combinations[row][col] + 1 > 2)
4505
combinations[row][col] = 0;
4508
combinations[row][col] += 1;
4515
// Compute inverse of Jacobian
4516
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
4518
// Declare transformation matrix
4519
// Declare pointer to two dimensional array and initialise
4520
double **transform = new double *[num_derivatives];
4522
for (unsigned int j = 0; j < num_derivatives; j++)
4524
transform[j] = new double [num_derivatives];
4525
for (unsigned int k = 0; k < num_derivatives; k++)
4526
transform[j][k] = 1;
4529
// Construct transformation matrix
4530
for (unsigned int row = 0; row < num_derivatives; row++)
4532
for (unsigned int col = 0; col < num_derivatives; col++)
4534
for (unsigned int k = 0; k < n; k++)
4535
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4540
for (unsigned int j = 0; j < 3*num_derivatives; j++)
4543
if (0 <= i && i <= 3)
4545
// Map degree of freedom to element degree of freedom
4546
const unsigned int dof = i;
4548
// Generate scalings
4549
const double scalings_y_0 = 1;
4550
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4551
const double scalings_z_0 = 1;
4552
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
4554
// Compute psitilde_a
4555
const double psitilde_a_0 = 1;
4556
const double psitilde_a_1 = x;
4558
// Compute psitilde_bs
4559
const double psitilde_bs_0_0 = 1;
4560
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4561
const double psitilde_bs_1_0 = 1;
4563
// Compute psitilde_cs
4564
const double psitilde_cs_00_0 = 1;
4565
const double psitilde_cs_00_1 = 2*z + 1;
4566
const double psitilde_cs_01_0 = 1;
4567
const double psitilde_cs_10_0 = 1;
4569
// Compute basisvalues
4570
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
4571
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
4572
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
4573
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
4575
// Table(s) of coefficients
4576
static const double coefficients0[4][4] = \
4577
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
4578
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
4579
{0.288675135, 0, 0.210818511, -0.0745355992},
4580
{0.288675135, 0, 0, 0.223606798}};
4582
// Interesting (new) part
4583
// Tables of derivatives of the polynomial base (transpose)
4584
static const double dmats0[4][4] = \
4586
{6.32455532, 0, 0, 0},
4590
static const double dmats1[4][4] = \
4592
{3.16227766, 0, 0, 0},
4593
{5.47722558, 0, 0, 0},
4596
static const double dmats2[4][4] = \
4598
{3.16227766, 0, 0, 0},
4599
{1.82574186, 0, 0, 0},
4600
{5.16397779, 0, 0, 0}};
4602
// Compute reference derivatives
4603
// Declare pointer to array of derivatives on FIAT element
4604
double *derivatives = new double [num_derivatives];
4606
// Declare coefficients
4607
double coeff0_0 = 0;
4608
double coeff0_1 = 0;
4609
double coeff0_2 = 0;
4610
double coeff0_3 = 0;
4612
// Declare new coefficients
4613
double new_coeff0_0 = 0;
4614
double new_coeff0_1 = 0;
4615
double new_coeff0_2 = 0;
4616
double new_coeff0_3 = 0;
4618
// Loop possible derivatives
4619
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4621
// Get values from coefficients array
4622
new_coeff0_0 = coefficients0[dof][0];
4623
new_coeff0_1 = coefficients0[dof][1];
4624
new_coeff0_2 = coefficients0[dof][2];
4625
new_coeff0_3 = coefficients0[dof][3];
4627
// Loop derivative order
4628
for (unsigned int j = 0; j < n; j++)
4630
// Update old coefficients
4631
coeff0_0 = new_coeff0_0;
4632
coeff0_1 = new_coeff0_1;
4633
coeff0_2 = new_coeff0_2;
4634
coeff0_3 = new_coeff0_3;
4636
if(combinations[deriv_num][j] == 0)
4638
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
4639
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
4640
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
4641
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
4643
if(combinations[deriv_num][j] == 1)
4645
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
4646
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
4647
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
4648
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
4650
if(combinations[deriv_num][j] == 2)
4652
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
4653
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
4654
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
4655
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
4659
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4660
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
4663
// Transform derivatives back to physical element
4664
for (unsigned int row = 0; row < num_derivatives; row++)
4666
for (unsigned int col = 0; col < num_derivatives; col++)
4668
values[row] += transform[row][col]*derivatives[col];
4671
// Delete pointer to array of derivatives on FIAT element
4672
delete [] derivatives;
4674
// Delete pointer to array of combinations of derivatives and transform
4675
for (unsigned int row = 0; row < num_derivatives; row++)
4677
delete [] combinations[row];
4678
delete [] transform[row];
4681
delete [] combinations;
4682
delete [] transform;
4685
if (4 <= i && i <= 7)
4687
// Map degree of freedom to element degree of freedom
4688
const unsigned int dof = i - 4;
4690
// Generate scalings
4691
const double scalings_y_0 = 1;
4692
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4693
const double scalings_z_0 = 1;
4694
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
4696
// Compute psitilde_a
4697
const double psitilde_a_0 = 1;
4698
const double psitilde_a_1 = x;
4700
// Compute psitilde_bs
4701
const double psitilde_bs_0_0 = 1;
4702
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4703
const double psitilde_bs_1_0 = 1;
4705
// Compute psitilde_cs
4706
const double psitilde_cs_00_0 = 1;
4707
const double psitilde_cs_00_1 = 2*z + 1;
4708
const double psitilde_cs_01_0 = 1;
4709
const double psitilde_cs_10_0 = 1;
4711
// Compute basisvalues
4712
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
4713
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
4714
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
4715
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
4717
// Table(s) of coefficients
4718
static const double coefficients0[4][4] = \
4719
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
4720
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
4721
{0.288675135, 0, 0.210818511, -0.0745355992},
4722
{0.288675135, 0, 0, 0.223606798}};
4724
// Interesting (new) part
4725
// Tables of derivatives of the polynomial base (transpose)
4726
static const double dmats0[4][4] = \
4728
{6.32455532, 0, 0, 0},
4732
static const double dmats1[4][4] = \
4734
{3.16227766, 0, 0, 0},
4735
{5.47722558, 0, 0, 0},
4738
static const double dmats2[4][4] = \
4740
{3.16227766, 0, 0, 0},
4741
{1.82574186, 0, 0, 0},
4742
{5.16397779, 0, 0, 0}};
4744
// Compute reference derivatives
4745
// Declare pointer to array of derivatives on FIAT element
4746
double *derivatives = new double [num_derivatives];
4748
// Declare coefficients
4749
double coeff0_0 = 0;
4750
double coeff0_1 = 0;
4751
double coeff0_2 = 0;
4752
double coeff0_3 = 0;
4754
// Declare new coefficients
4755
double new_coeff0_0 = 0;
4756
double new_coeff0_1 = 0;
4757
double new_coeff0_2 = 0;
4758
double new_coeff0_3 = 0;
4760
// Loop possible derivatives
4761
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4763
// Get values from coefficients array
4764
new_coeff0_0 = coefficients0[dof][0];
4765
new_coeff0_1 = coefficients0[dof][1];
4766
new_coeff0_2 = coefficients0[dof][2];
4767
new_coeff0_3 = coefficients0[dof][3];
4769
// Loop derivative order
4770
for (unsigned int j = 0; j < n; j++)
4772
// Update old coefficients
4773
coeff0_0 = new_coeff0_0;
4774
coeff0_1 = new_coeff0_1;
4775
coeff0_2 = new_coeff0_2;
4776
coeff0_3 = new_coeff0_3;
4778
if(combinations[deriv_num][j] == 0)
4780
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
4781
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
4782
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
4783
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
4785
if(combinations[deriv_num][j] == 1)
4787
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
4788
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
4789
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
4790
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
4792
if(combinations[deriv_num][j] == 2)
4794
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
4795
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
4796
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
4797
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
4801
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4802
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
4805
// Transform derivatives back to physical element
4806
for (unsigned int row = 0; row < num_derivatives; row++)
4808
for (unsigned int col = 0; col < num_derivatives; col++)
4810
values[num_derivatives + row] += transform[row][col]*derivatives[col];
4813
// Delete pointer to array of derivatives on FIAT element
4814
delete [] derivatives;
4816
// Delete pointer to array of combinations of derivatives and transform
4817
for (unsigned int row = 0; row < num_derivatives; row++)
4819
delete [] combinations[row];
4820
delete [] transform[row];
4823
delete [] combinations;
4824
delete [] transform;
4827
if (8 <= i && i <= 11)
4829
// Map degree of freedom to element degree of freedom
4830
const unsigned int dof = i - 8;
4832
// Generate scalings
4833
const double scalings_y_0 = 1;
4834
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4835
const double scalings_z_0 = 1;
4836
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
4838
// Compute psitilde_a
4839
const double psitilde_a_0 = 1;
4840
const double psitilde_a_1 = x;
4842
// Compute psitilde_bs
4843
const double psitilde_bs_0_0 = 1;
4844
const double psitilde_bs_0_1 = 1.5*y + 0.5;
4845
const double psitilde_bs_1_0 = 1;
4847
// Compute psitilde_cs
4848
const double psitilde_cs_00_0 = 1;
4849
const double psitilde_cs_00_1 = 2*z + 1;
4850
const double psitilde_cs_01_0 = 1;
4851
const double psitilde_cs_10_0 = 1;
4853
// Compute basisvalues
4854
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
4855
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
4856
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
4857
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
4859
// Table(s) of coefficients
4860
static const double coefficients0[4][4] = \
4861
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
4862
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
4863
{0.288675135, 0, 0.210818511, -0.0745355992},
4864
{0.288675135, 0, 0, 0.223606798}};
4866
// Interesting (new) part
4867
// Tables of derivatives of the polynomial base (transpose)
4868
static const double dmats0[4][4] = \
4870
{6.32455532, 0, 0, 0},
4874
static const double dmats1[4][4] = \
4876
{3.16227766, 0, 0, 0},
4877
{5.47722558, 0, 0, 0},
4880
static const double dmats2[4][4] = \
4882
{3.16227766, 0, 0, 0},
4883
{1.82574186, 0, 0, 0},
4884
{5.16397779, 0, 0, 0}};
4886
// Compute reference derivatives
4887
// Declare pointer to array of derivatives on FIAT element
4888
double *derivatives = new double [num_derivatives];
4890
// Declare coefficients
4891
double coeff0_0 = 0;
4892
double coeff0_1 = 0;
4893
double coeff0_2 = 0;
4894
double coeff0_3 = 0;
4896
// Declare new coefficients
4897
double new_coeff0_0 = 0;
4898
double new_coeff0_1 = 0;
4899
double new_coeff0_2 = 0;
4900
double new_coeff0_3 = 0;
4902
// Loop possible derivatives
4903
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4905
// Get values from coefficients array
4906
new_coeff0_0 = coefficients0[dof][0];
4907
new_coeff0_1 = coefficients0[dof][1];
4908
new_coeff0_2 = coefficients0[dof][2];
4909
new_coeff0_3 = coefficients0[dof][3];
4911
// Loop derivative order
4912
for (unsigned int j = 0; j < n; j++)
4914
// Update old coefficients
4915
coeff0_0 = new_coeff0_0;
4916
coeff0_1 = new_coeff0_1;
4917
coeff0_2 = new_coeff0_2;
4918
coeff0_3 = new_coeff0_3;
4920
if(combinations[deriv_num][j] == 0)
4922
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
4923
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
4924
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
4925
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
4927
if(combinations[deriv_num][j] == 1)
4929
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
4930
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
4931
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
4932
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
4934
if(combinations[deriv_num][j] == 2)
4936
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
4937
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
4938
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
4939
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
4943
// Compute derivatives on reference element as dot product of coefficients and basisvalues
4944
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
4947
// Transform derivatives back to physical element
4948
for (unsigned int row = 0; row < num_derivatives; row++)
4950
for (unsigned int col = 0; col < num_derivatives; col++)
4952
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
4955
// Delete pointer to array of derivatives on FIAT element
4956
delete [] derivatives;
4958
// Delete pointer to array of combinations of derivatives and transform
4959
for (unsigned int row = 0; row < num_derivatives; row++)
4961
delete [] combinations[row];
4962
delete [] transform[row];
4965
delete [] combinations;
4966
delete [] transform;
4971
/// Evaluate order n derivatives of all basis functions at given point in cell
4972
virtual void evaluate_basis_derivatives_all(unsigned int n,
4974
const double* coordinates,
4975
const ufc::cell& c) const
4977
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4980
/// Evaluate linear functional for dof i on the function f
4981
virtual double evaluate_dof(unsigned int i,
4982
const ufc::function& f,
4983
const ufc::cell& c) const
4985
// The reference points, direction and weights:
4986
static const double X[12][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
4987
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
4988
static const double D[12][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
4990
const double * const * x = c.coordinates;
4991
double result = 0.0;
4992
// Iterate over the points:
4993
// Evaluate basis functions for affine mapping
4994
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
4995
const double w1 = X[i][0][0];
4996
const double w2 = X[i][0][1];
4997
const double w3 = X[i][0][2];
4999
// Compute affine mapping y = F(X)
5001
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
5002
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
5003
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
5005
// Evaluate function at physical points
5007
f.evaluate(values, y, c);
5009
// Map function values using appropriate mapping
5010
// Affine map: Do nothing
5012
// Note that we do not map the weights (yet).
5014
// Take directional components
5015
for(int k = 0; k < 3; k++)
5016
result += values[k]*D[i][0][k];
5017
// Multiply by weights
5023
/// Evaluate linear functionals for all dofs on the function f
5024
virtual void evaluate_dofs(double* values,
5025
const ufc::function& f,
5026
const ufc::cell& c) const
5028
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5031
/// Interpolate vertex values from dof values
5032
virtual void interpolate_vertex_values(double* vertex_values,
5033
const double* dof_values,
5034
const ufc::cell& c) const
5036
// Evaluate at vertices and use affine mapping
5037
vertex_values[0] = dof_values[0];
5038
vertex_values[3] = dof_values[1];
5039
vertex_values[6] = dof_values[2];
5040
vertex_values[9] = dof_values[3];
5041
// Evaluate at vertices and use affine mapping
5042
vertex_values[1] = dof_values[4];
5043
vertex_values[4] = dof_values[5];
5044
vertex_values[7] = dof_values[6];
5045
vertex_values[10] = dof_values[7];
5046
// Evaluate at vertices and use affine mapping
5047
vertex_values[2] = dof_values[8];
5048
vertex_values[5] = dof_values[9];
5049
vertex_values[8] = dof_values[10];
5050
vertex_values[11] = dof_values[11];
5053
/// Return the number of sub elements (for a mixed element)
5054
virtual unsigned int num_sub_elements() const
5059
/// Create a new finite element for sub element i (for a mixed element)
5060
virtual ufc::finite_element* create_sub_element(unsigned int i) const
5065
return new hyperelasticity_0_finite_element_1_0();
5068
return new hyperelasticity_0_finite_element_1_1();
5071
return new hyperelasticity_0_finite_element_1_2();
5079
/// This class defines the interface for a finite element.
5081
class hyperelasticity_0_finite_element_2_0: public ufc::finite_element
5086
hyperelasticity_0_finite_element_2_0() : ufc::finite_element()
5092
virtual ~hyperelasticity_0_finite_element_2_0()
5097
/// Return a string identifying the finite element
5098
virtual const char* signature() const
5100
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
5103
/// Return the cell shape
5104
virtual ufc::shape cell_shape() const
5106
return ufc::tetrahedron;
5109
/// Return the dimension of the finite element function space
5110
virtual unsigned int space_dimension() const
5115
/// Return the rank of the value space
5116
virtual unsigned int value_rank() const
5121
/// Return the dimension of the value space for axis i
5122
virtual unsigned int value_dimension(unsigned int i) const
5127
/// Evaluate basis function i at given point in cell
5128
virtual void evaluate_basis(unsigned int i,
5130
const double* coordinates,
5131
const ufc::cell& c) const
5133
// Extract vertex coordinates
5134
const double * const * element_coordinates = c.coordinates;
5136
// Compute Jacobian of affine map from reference cell
5137
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5138
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5139
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
5140
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5141
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5142
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
5143
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
5144
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
5145
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
5147
// Compute sub determinants
5148
const double d00 = J_11*J_22 - J_12*J_21;
5149
const double d01 = J_12*J_20 - J_10*J_22;
5150
const double d02 = J_10*J_21 - J_11*J_20;
5152
const double d10 = J_02*J_21 - J_01*J_22;
5153
const double d11 = J_00*J_22 - J_02*J_20;
5154
const double d12 = J_01*J_20 - J_00*J_21;
5156
const double d20 = J_01*J_12 - J_02*J_11;
5157
const double d21 = J_02*J_10 - J_00*J_12;
5158
const double d22 = J_00*J_11 - J_01*J_10;
5160
// Compute determinant of Jacobian
5161
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
5163
// Compute inverse of Jacobian
5165
// Compute constants
5166
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
5167
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
5168
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
5170
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
5171
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
5172
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
5174
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
5175
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
5176
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
5178
// Get coordinates and map to the UFC reference element
5179
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
5180
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
5181
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
5183
// Map coordinates to the reference cube
5184
if (std::abs(y + z - 1.0) < 1e-08)
5187
x = -2.0 * x/(y + z - 1.0) - 1.0;
5188
if (std::abs(z - 1.0) < 1e-08)
5191
y = 2.0 * y/(1.0 - z) - 1.0;
5197
// Map degree of freedom to element degree of freedom
5198
const unsigned int dof = i;
5200
// Generate scalings
5201
const double scalings_y_0 = 1;
5202
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5203
const double scalings_z_0 = 1;
5204
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
5206
// Compute psitilde_a
5207
const double psitilde_a_0 = 1;
5208
const double psitilde_a_1 = x;
5210
// Compute psitilde_bs
5211
const double psitilde_bs_0_0 = 1;
5212
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5213
const double psitilde_bs_1_0 = 1;
5215
// Compute psitilde_cs
5216
const double psitilde_cs_00_0 = 1;
5217
const double psitilde_cs_00_1 = 2*z + 1;
5218
const double psitilde_cs_01_0 = 1;
5219
const double psitilde_cs_10_0 = 1;
5221
// Compute basisvalues
5222
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
5223
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
5224
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
5225
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
5227
// Table(s) of coefficients
5228
static const double coefficients0[4][4] = \
5229
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
5230
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
5231
{0.288675135, 0, 0.210818511, -0.0745355992},
5232
{0.288675135, 0, 0, 0.223606798}};
5234
// Extract relevant coefficients
5235
const double coeff0_0 = coefficients0[dof][0];
5236
const double coeff0_1 = coefficients0[dof][1];
5237
const double coeff0_2 = coefficients0[dof][2];
5238
const double coeff0_3 = coefficients0[dof][3];
5241
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
5244
/// Evaluate all basis functions at given point in cell
5245
virtual void evaluate_basis_all(double* values,
5246
const double* coordinates,
5247
const ufc::cell& c) const
5249
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5252
/// Evaluate order n derivatives of basis function i at given point in cell
5253
virtual void evaluate_basis_derivatives(unsigned int i,
5256
const double* coordinates,
5257
const ufc::cell& c) const
5259
// Extract vertex coordinates
5260
const double * const * element_coordinates = c.coordinates;
5262
// Compute Jacobian of affine map from reference cell
5263
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5264
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5265
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
5266
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5267
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5268
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
5269
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
5270
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
5271
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
5273
// Compute sub determinants
5274
const double d00 = J_11*J_22 - J_12*J_21;
5275
const double d01 = J_12*J_20 - J_10*J_22;
5276
const double d02 = J_10*J_21 - J_11*J_20;
5278
const double d10 = J_02*J_21 - J_01*J_22;
5279
const double d11 = J_00*J_22 - J_02*J_20;
5280
const double d12 = J_01*J_20 - J_00*J_21;
5282
const double d20 = J_01*J_12 - J_02*J_11;
5283
const double d21 = J_02*J_10 - J_00*J_12;
5284
const double d22 = J_00*J_11 - J_01*J_10;
5286
// Compute determinant of Jacobian
5287
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
5289
// Compute inverse of Jacobian
5291
// Compute constants
5292
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
5293
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
5294
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
5296
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
5297
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
5298
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
5300
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
5301
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
5302
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
5304
// Get coordinates and map to the UFC reference element
5305
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
5306
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
5307
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
5309
// Map coordinates to the reference cube
5310
if (std::abs(y + z - 1.0) < 1e-08)
5313
x = -2.0 * x/(y + z - 1.0) - 1.0;
5314
if (std::abs(z - 1.0) < 1e-08)
5317
y = 2.0 * y/(1.0 - z) - 1.0;
5320
// Compute number of derivatives
5321
unsigned int num_derivatives = 1;
5323
for (unsigned int j = 0; j < n; j++)
5324
num_derivatives *= 3;
5327
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5328
unsigned int **combinations = new unsigned int *[num_derivatives];
5330
for (unsigned int j = 0; j < num_derivatives; j++)
5332
combinations[j] = new unsigned int [n];
5333
for (unsigned int k = 0; k < n; k++)
5334
combinations[j][k] = 0;
5337
// Generate combinations of derivatives
5338
for (unsigned int row = 1; row < num_derivatives; row++)
5340
for (unsigned int num = 0; num < row; num++)
5342
for (unsigned int col = n-1; col+1 > 0; col--)
5344
if (combinations[row][col] + 1 > 2)
5345
combinations[row][col] = 0;
5348
combinations[row][col] += 1;
5355
// Compute inverse of Jacobian
5356
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
5358
// Declare transformation matrix
5359
// Declare pointer to two dimensional array and initialise
5360
double **transform = new double *[num_derivatives];
5362
for (unsigned int j = 0; j < num_derivatives; j++)
5364
transform[j] = new double [num_derivatives];
5365
for (unsigned int k = 0; k < num_derivatives; k++)
5366
transform[j][k] = 1;
5369
// Construct transformation matrix
5370
for (unsigned int row = 0; row < num_derivatives; row++)
5372
for (unsigned int col = 0; col < num_derivatives; col++)
5374
for (unsigned int k = 0; k < n; k++)
5375
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5380
for (unsigned int j = 0; j < 1*num_derivatives; j++)
5383
// Map degree of freedom to element degree of freedom
5384
const unsigned int dof = i;
5386
// Generate scalings
5387
const double scalings_y_0 = 1;
5388
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5389
const double scalings_z_0 = 1;
5390
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
5392
// Compute psitilde_a
5393
const double psitilde_a_0 = 1;
5394
const double psitilde_a_1 = x;
5396
// Compute psitilde_bs
5397
const double psitilde_bs_0_0 = 1;
5398
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5399
const double psitilde_bs_1_0 = 1;
5401
// Compute psitilde_cs
5402
const double psitilde_cs_00_0 = 1;
5403
const double psitilde_cs_00_1 = 2*z + 1;
5404
const double psitilde_cs_01_0 = 1;
5405
const double psitilde_cs_10_0 = 1;
5407
// Compute basisvalues
5408
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
5409
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
5410
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
5411
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
5413
// Table(s) of coefficients
5414
static const double coefficients0[4][4] = \
5415
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
5416
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
5417
{0.288675135, 0, 0.210818511, -0.0745355992},
5418
{0.288675135, 0, 0, 0.223606798}};
5420
// Interesting (new) part
5421
// Tables of derivatives of the polynomial base (transpose)
5422
static const double dmats0[4][4] = \
5424
{6.32455532, 0, 0, 0},
5428
static const double dmats1[4][4] = \
5430
{3.16227766, 0, 0, 0},
5431
{5.47722558, 0, 0, 0},
5434
static const double dmats2[4][4] = \
5436
{3.16227766, 0, 0, 0},
5437
{1.82574186, 0, 0, 0},
5438
{5.16397779, 0, 0, 0}};
5440
// Compute reference derivatives
5441
// Declare pointer to array of derivatives on FIAT element
5442
double *derivatives = new double [num_derivatives];
5444
// Declare coefficients
5445
double coeff0_0 = 0;
5446
double coeff0_1 = 0;
5447
double coeff0_2 = 0;
5448
double coeff0_3 = 0;
5450
// Declare new coefficients
5451
double new_coeff0_0 = 0;
5452
double new_coeff0_1 = 0;
5453
double new_coeff0_2 = 0;
5454
double new_coeff0_3 = 0;
5456
// Loop possible derivatives
5457
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5459
// Get values from coefficients array
5460
new_coeff0_0 = coefficients0[dof][0];
5461
new_coeff0_1 = coefficients0[dof][1];
5462
new_coeff0_2 = coefficients0[dof][2];
5463
new_coeff0_3 = coefficients0[dof][3];
5465
// Loop derivative order
5466
for (unsigned int j = 0; j < n; j++)
5468
// Update old coefficients
5469
coeff0_0 = new_coeff0_0;
5470
coeff0_1 = new_coeff0_1;
5471
coeff0_2 = new_coeff0_2;
5472
coeff0_3 = new_coeff0_3;
5474
if(combinations[deriv_num][j] == 0)
5476
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
5477
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
5478
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
5479
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
5481
if(combinations[deriv_num][j] == 1)
5483
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
5484
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
5485
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
5486
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
5488
if(combinations[deriv_num][j] == 2)
5490
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
5491
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
5492
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
5493
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
5497
// Compute derivatives on reference element as dot product of coefficients and basisvalues
5498
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
5501
// Transform derivatives back to physical element
5502
for (unsigned int row = 0; row < num_derivatives; row++)
5504
for (unsigned int col = 0; col < num_derivatives; col++)
5506
values[row] += transform[row][col]*derivatives[col];
5509
// Delete pointer to array of derivatives on FIAT element
5510
delete [] derivatives;
5512
// Delete pointer to array of combinations of derivatives and transform
5513
for (unsigned int row = 0; row < num_derivatives; row++)
5515
delete [] combinations[row];
5516
delete [] transform[row];
5519
delete [] combinations;
5520
delete [] transform;
5523
/// Evaluate order n derivatives of all basis functions at given point in cell
5524
virtual void evaluate_basis_derivatives_all(unsigned int n,
5526
const double* coordinates,
5527
const ufc::cell& c) const
5529
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5532
/// Evaluate linear functional for dof i on the function f
5533
virtual double evaluate_dof(unsigned int i,
5534
const ufc::function& f,
5535
const ufc::cell& c) const
5537
// The reference points, direction and weights:
5538
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
5539
static const double W[4][1] = {{1}, {1}, {1}, {1}};
5540
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
5542
const double * const * x = c.coordinates;
5543
double result = 0.0;
5544
// Iterate over the points:
5545
// Evaluate basis functions for affine mapping
5546
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
5547
const double w1 = X[i][0][0];
5548
const double w2 = X[i][0][1];
5549
const double w3 = X[i][0][2];
5551
// Compute affine mapping y = F(X)
5553
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
5554
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
5555
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
5557
// Evaluate function at physical points
5559
f.evaluate(values, y, c);
5561
// Map function values using appropriate mapping
5562
// Affine map: Do nothing
5564
// Note that we do not map the weights (yet).
5566
// Take directional components
5567
for(int k = 0; k < 1; k++)
5568
result += values[k]*D[i][0][k];
5569
// Multiply by weights
5575
/// Evaluate linear functionals for all dofs on the function f
5576
virtual void evaluate_dofs(double* values,
5577
const ufc::function& f,
5578
const ufc::cell& c) const
5580
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5583
/// Interpolate vertex values from dof values
5584
virtual void interpolate_vertex_values(double* vertex_values,
5585
const double* dof_values,
5586
const ufc::cell& c) const
5588
// Evaluate at vertices and use affine mapping
5589
vertex_values[0] = dof_values[0];
5590
vertex_values[1] = dof_values[1];
5591
vertex_values[2] = dof_values[2];
5592
vertex_values[3] = dof_values[3];
5595
/// Return the number of sub elements (for a mixed element)
5596
virtual unsigned int num_sub_elements() const
5601
/// Create a new finite element for sub element i (for a mixed element)
5602
virtual ufc::finite_element* create_sub_element(unsigned int i) const
5604
return new hyperelasticity_0_finite_element_2_0();
5609
/// This class defines the interface for a finite element.
5611
class hyperelasticity_0_finite_element_2_1: public ufc::finite_element
5616
hyperelasticity_0_finite_element_2_1() : ufc::finite_element()
5622
virtual ~hyperelasticity_0_finite_element_2_1()
5627
/// Return a string identifying the finite element
5628
virtual const char* signature() const
5630
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
5633
/// Return the cell shape
5634
virtual ufc::shape cell_shape() const
5636
return ufc::tetrahedron;
5639
/// Return the dimension of the finite element function space
5640
virtual unsigned int space_dimension() const
5645
/// Return the rank of the value space
5646
virtual unsigned int value_rank() const
5651
/// Return the dimension of the value space for axis i
5652
virtual unsigned int value_dimension(unsigned int i) const
5657
/// Evaluate basis function i at given point in cell
5658
virtual void evaluate_basis(unsigned int i,
5660
const double* coordinates,
5661
const ufc::cell& c) const
5663
// Extract vertex coordinates
5664
const double * const * element_coordinates = c.coordinates;
5666
// Compute Jacobian of affine map from reference cell
5667
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5668
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5669
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
5670
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5671
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5672
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
5673
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
5674
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
5675
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
5677
// Compute sub determinants
5678
const double d00 = J_11*J_22 - J_12*J_21;
5679
const double d01 = J_12*J_20 - J_10*J_22;
5680
const double d02 = J_10*J_21 - J_11*J_20;
5682
const double d10 = J_02*J_21 - J_01*J_22;
5683
const double d11 = J_00*J_22 - J_02*J_20;
5684
const double d12 = J_01*J_20 - J_00*J_21;
5686
const double d20 = J_01*J_12 - J_02*J_11;
5687
const double d21 = J_02*J_10 - J_00*J_12;
5688
const double d22 = J_00*J_11 - J_01*J_10;
5690
// Compute determinant of Jacobian
5691
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
5693
// Compute inverse of Jacobian
5695
// Compute constants
5696
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
5697
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
5698
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
5700
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
5701
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
5702
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
5704
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
5705
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
5706
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
5708
// Get coordinates and map to the UFC reference element
5709
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
5710
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
5711
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
5713
// Map coordinates to the reference cube
5714
if (std::abs(y + z - 1.0) < 1e-08)
5717
x = -2.0 * x/(y + z - 1.0) - 1.0;
5718
if (std::abs(z - 1.0) < 1e-08)
5721
y = 2.0 * y/(1.0 - z) - 1.0;
5727
// Map degree of freedom to element degree of freedom
5728
const unsigned int dof = i;
5730
// Generate scalings
5731
const double scalings_y_0 = 1;
5732
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5733
const double scalings_z_0 = 1;
5734
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
5736
// Compute psitilde_a
5737
const double psitilde_a_0 = 1;
5738
const double psitilde_a_1 = x;
5740
// Compute psitilde_bs
5741
const double psitilde_bs_0_0 = 1;
5742
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5743
const double psitilde_bs_1_0 = 1;
5745
// Compute psitilde_cs
5746
const double psitilde_cs_00_0 = 1;
5747
const double psitilde_cs_00_1 = 2*z + 1;
5748
const double psitilde_cs_01_0 = 1;
5749
const double psitilde_cs_10_0 = 1;
5751
// Compute basisvalues
5752
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
5753
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
5754
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
5755
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
5757
// Table(s) of coefficients
5758
static const double coefficients0[4][4] = \
5759
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
5760
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
5761
{0.288675135, 0, 0.210818511, -0.0745355992},
5762
{0.288675135, 0, 0, 0.223606798}};
5764
// Extract relevant coefficients
5765
const double coeff0_0 = coefficients0[dof][0];
5766
const double coeff0_1 = coefficients0[dof][1];
5767
const double coeff0_2 = coefficients0[dof][2];
5768
const double coeff0_3 = coefficients0[dof][3];
5771
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
5774
/// Evaluate all basis functions at given point in cell
5775
virtual void evaluate_basis_all(double* values,
5776
const double* coordinates,
5777
const ufc::cell& c) const
5779
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5782
/// Evaluate order n derivatives of basis function i at given point in cell
5783
virtual void evaluate_basis_derivatives(unsigned int i,
5786
const double* coordinates,
5787
const ufc::cell& c) const
5789
// Extract vertex coordinates
5790
const double * const * element_coordinates = c.coordinates;
5792
// Compute Jacobian of affine map from reference cell
5793
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5794
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5795
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
5796
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5797
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5798
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
5799
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
5800
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
5801
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
5803
// Compute sub determinants
5804
const double d00 = J_11*J_22 - J_12*J_21;
5805
const double d01 = J_12*J_20 - J_10*J_22;
5806
const double d02 = J_10*J_21 - J_11*J_20;
5808
const double d10 = J_02*J_21 - J_01*J_22;
5809
const double d11 = J_00*J_22 - J_02*J_20;
5810
const double d12 = J_01*J_20 - J_00*J_21;
5812
const double d20 = J_01*J_12 - J_02*J_11;
5813
const double d21 = J_02*J_10 - J_00*J_12;
5814
const double d22 = J_00*J_11 - J_01*J_10;
5816
// Compute determinant of Jacobian
5817
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
5819
// Compute inverse of Jacobian
5821
// Compute constants
5822
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
5823
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
5824
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
5826
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
5827
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
5828
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
5830
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
5831
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
5832
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
5834
// Get coordinates and map to the UFC reference element
5835
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
5836
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
5837
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
5839
// Map coordinates to the reference cube
5840
if (std::abs(y + z - 1.0) < 1e-08)
5843
x = -2.0 * x/(y + z - 1.0) - 1.0;
5844
if (std::abs(z - 1.0) < 1e-08)
5847
y = 2.0 * y/(1.0 - z) - 1.0;
5850
// Compute number of derivatives
5851
unsigned int num_derivatives = 1;
5853
for (unsigned int j = 0; j < n; j++)
5854
num_derivatives *= 3;
5857
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5858
unsigned int **combinations = new unsigned int *[num_derivatives];
5860
for (unsigned int j = 0; j < num_derivatives; j++)
5862
combinations[j] = new unsigned int [n];
5863
for (unsigned int k = 0; k < n; k++)
5864
combinations[j][k] = 0;
5867
// Generate combinations of derivatives
5868
for (unsigned int row = 1; row < num_derivatives; row++)
5870
for (unsigned int num = 0; num < row; num++)
5872
for (unsigned int col = n-1; col+1 > 0; col--)
5874
if (combinations[row][col] + 1 > 2)
5875
combinations[row][col] = 0;
5878
combinations[row][col] += 1;
5885
// Compute inverse of Jacobian
5886
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
5888
// Declare transformation matrix
5889
// Declare pointer to two dimensional array and initialise
5890
double **transform = new double *[num_derivatives];
5892
for (unsigned int j = 0; j < num_derivatives; j++)
5894
transform[j] = new double [num_derivatives];
5895
for (unsigned int k = 0; k < num_derivatives; k++)
5896
transform[j][k] = 1;
5899
// Construct transformation matrix
5900
for (unsigned int row = 0; row < num_derivatives; row++)
5902
for (unsigned int col = 0; col < num_derivatives; col++)
5904
for (unsigned int k = 0; k < n; k++)
5905
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5910
for (unsigned int j = 0; j < 1*num_derivatives; j++)
5913
// Map degree of freedom to element degree of freedom
5914
const unsigned int dof = i;
5916
// Generate scalings
5917
const double scalings_y_0 = 1;
5918
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
5919
const double scalings_z_0 = 1;
5920
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
5922
// Compute psitilde_a
5923
const double psitilde_a_0 = 1;
5924
const double psitilde_a_1 = x;
5926
// Compute psitilde_bs
5927
const double psitilde_bs_0_0 = 1;
5928
const double psitilde_bs_0_1 = 1.5*y + 0.5;
5929
const double psitilde_bs_1_0 = 1;
5931
// Compute psitilde_cs
5932
const double psitilde_cs_00_0 = 1;
5933
const double psitilde_cs_00_1 = 2*z + 1;
5934
const double psitilde_cs_01_0 = 1;
5935
const double psitilde_cs_10_0 = 1;
5937
// Compute basisvalues
5938
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
5939
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
5940
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
5941
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
5943
// Table(s) of coefficients
5944
static const double coefficients0[4][4] = \
5945
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
5946
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
5947
{0.288675135, 0, 0.210818511, -0.0745355992},
5948
{0.288675135, 0, 0, 0.223606798}};
5950
// Interesting (new) part
5951
// Tables of derivatives of the polynomial base (transpose)
5952
static const double dmats0[4][4] = \
5954
{6.32455532, 0, 0, 0},
5958
static const double dmats1[4][4] = \
5960
{3.16227766, 0, 0, 0},
5961
{5.47722558, 0, 0, 0},
5964
static const double dmats2[4][4] = \
5966
{3.16227766, 0, 0, 0},
5967
{1.82574186, 0, 0, 0},
5968
{5.16397779, 0, 0, 0}};
5970
// Compute reference derivatives
5971
// Declare pointer to array of derivatives on FIAT element
5972
double *derivatives = new double [num_derivatives];
5974
// Declare coefficients
5975
double coeff0_0 = 0;
5976
double coeff0_1 = 0;
5977
double coeff0_2 = 0;
5978
double coeff0_3 = 0;
5980
// Declare new coefficients
5981
double new_coeff0_0 = 0;
5982
double new_coeff0_1 = 0;
5983
double new_coeff0_2 = 0;
5984
double new_coeff0_3 = 0;
5986
// Loop possible derivatives
5987
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5989
// Get values from coefficients array
5990
new_coeff0_0 = coefficients0[dof][0];
5991
new_coeff0_1 = coefficients0[dof][1];
5992
new_coeff0_2 = coefficients0[dof][2];
5993
new_coeff0_3 = coefficients0[dof][3];
5995
// Loop derivative order
5996
for (unsigned int j = 0; j < n; j++)
5998
// Update old coefficients
5999
coeff0_0 = new_coeff0_0;
6000
coeff0_1 = new_coeff0_1;
6001
coeff0_2 = new_coeff0_2;
6002
coeff0_3 = new_coeff0_3;
6004
if(combinations[deriv_num][j] == 0)
6006
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
6007
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
6008
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
6009
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
6011
if(combinations[deriv_num][j] == 1)
6013
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
6014
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
6015
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
6016
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
6018
if(combinations[deriv_num][j] == 2)
6020
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
6021
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
6022
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
6023
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
6027
// Compute derivatives on reference element as dot product of coefficients and basisvalues
6028
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
6031
// Transform derivatives back to physical element
6032
for (unsigned int row = 0; row < num_derivatives; row++)
6034
for (unsigned int col = 0; col < num_derivatives; col++)
6036
values[row] += transform[row][col]*derivatives[col];
6039
// Delete pointer to array of derivatives on FIAT element
6040
delete [] derivatives;
6042
// Delete pointer to array of combinations of derivatives and transform
6043
for (unsigned int row = 0; row < num_derivatives; row++)
6045
delete [] combinations[row];
6046
delete [] transform[row];
6049
delete [] combinations;
6050
delete [] transform;
6053
/// Evaluate order n derivatives of all basis functions at given point in cell
6054
virtual void evaluate_basis_derivatives_all(unsigned int n,
6056
const double* coordinates,
6057
const ufc::cell& c) const
6059
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
6062
/// Evaluate linear functional for dof i on the function f
6063
virtual double evaluate_dof(unsigned int i,
6064
const ufc::function& f,
6065
const ufc::cell& c) const
6067
// The reference points, direction and weights:
6068
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
6069
static const double W[4][1] = {{1}, {1}, {1}, {1}};
6070
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
6072
const double * const * x = c.coordinates;
6073
double result = 0.0;
6074
// Iterate over the points:
6075
// Evaluate basis functions for affine mapping
6076
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
6077
const double w1 = X[i][0][0];
6078
const double w2 = X[i][0][1];
6079
const double w3 = X[i][0][2];
6081
// Compute affine mapping y = F(X)
6083
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
6084
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
6085
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
6087
// Evaluate function at physical points
6089
f.evaluate(values, y, c);
6091
// Map function values using appropriate mapping
6092
// Affine map: Do nothing
6094
// Note that we do not map the weights (yet).
6096
// Take directional components
6097
for(int k = 0; k < 1; k++)
6098
result += values[k]*D[i][0][k];
6099
// Multiply by weights
6105
/// Evaluate linear functionals for all dofs on the function f
6106
virtual void evaluate_dofs(double* values,
6107
const ufc::function& f,
6108
const ufc::cell& c) const
6110
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6113
/// Interpolate vertex values from dof values
6114
virtual void interpolate_vertex_values(double* vertex_values,
6115
const double* dof_values,
6116
const ufc::cell& c) const
6118
// Evaluate at vertices and use affine mapping
6119
vertex_values[0] = dof_values[0];
6120
vertex_values[1] = dof_values[1];
6121
vertex_values[2] = dof_values[2];
6122
vertex_values[3] = dof_values[3];
6125
/// Return the number of sub elements (for a mixed element)
6126
virtual unsigned int num_sub_elements() const
6131
/// Create a new finite element for sub element i (for a mixed element)
6132
virtual ufc::finite_element* create_sub_element(unsigned int i) const
6134
return new hyperelasticity_0_finite_element_2_1();
6139
/// This class defines the interface for a finite element.
6141
class hyperelasticity_0_finite_element_2_2: public ufc::finite_element
6146
hyperelasticity_0_finite_element_2_2() : ufc::finite_element()
6152
virtual ~hyperelasticity_0_finite_element_2_2()
6157
/// Return a string identifying the finite element
6158
virtual const char* signature() const
6160
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
6163
/// Return the cell shape
6164
virtual ufc::shape cell_shape() const
6166
return ufc::tetrahedron;
6169
/// Return the dimension of the finite element function space
6170
virtual unsigned int space_dimension() const
6175
/// Return the rank of the value space
6176
virtual unsigned int value_rank() const
6181
/// Return the dimension of the value space for axis i
6182
virtual unsigned int value_dimension(unsigned int i) const
6187
/// Evaluate basis function i at given point in cell
6188
virtual void evaluate_basis(unsigned int i,
6190
const double* coordinates,
6191
const ufc::cell& c) const
6193
// Extract vertex coordinates
6194
const double * const * element_coordinates = c.coordinates;
6196
// Compute Jacobian of affine map from reference cell
6197
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
6198
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
6199
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
6200
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
6201
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
6202
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
6203
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
6204
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
6205
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
6207
// Compute sub determinants
6208
const double d00 = J_11*J_22 - J_12*J_21;
6209
const double d01 = J_12*J_20 - J_10*J_22;
6210
const double d02 = J_10*J_21 - J_11*J_20;
6212
const double d10 = J_02*J_21 - J_01*J_22;
6213
const double d11 = J_00*J_22 - J_02*J_20;
6214
const double d12 = J_01*J_20 - J_00*J_21;
6216
const double d20 = J_01*J_12 - J_02*J_11;
6217
const double d21 = J_02*J_10 - J_00*J_12;
6218
const double d22 = J_00*J_11 - J_01*J_10;
6220
// Compute determinant of Jacobian
6221
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
6223
// Compute inverse of Jacobian
6225
// Compute constants
6226
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
6227
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
6228
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
6230
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
6231
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
6232
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
6234
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
6235
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
6236
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
6238
// Get coordinates and map to the UFC reference element
6239
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
6240
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
6241
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
6243
// Map coordinates to the reference cube
6244
if (std::abs(y + z - 1.0) < 1e-08)
6247
x = -2.0 * x/(y + z - 1.0) - 1.0;
6248
if (std::abs(z - 1.0) < 1e-08)
6251
y = 2.0 * y/(1.0 - z) - 1.0;
6257
// Map degree of freedom to element degree of freedom
6258
const unsigned int dof = i;
6260
// Generate scalings
6261
const double scalings_y_0 = 1;
6262
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
6263
const double scalings_z_0 = 1;
6264
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
6266
// Compute psitilde_a
6267
const double psitilde_a_0 = 1;
6268
const double psitilde_a_1 = x;
6270
// Compute psitilde_bs
6271
const double psitilde_bs_0_0 = 1;
6272
const double psitilde_bs_0_1 = 1.5*y + 0.5;
6273
const double psitilde_bs_1_0 = 1;
6275
// Compute psitilde_cs
6276
const double psitilde_cs_00_0 = 1;
6277
const double psitilde_cs_00_1 = 2*z + 1;
6278
const double psitilde_cs_01_0 = 1;
6279
const double psitilde_cs_10_0 = 1;
6281
// Compute basisvalues
6282
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
6283
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
6284
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
6285
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
6287
// Table(s) of coefficients
6288
static const double coefficients0[4][4] = \
6289
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
6290
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
6291
{0.288675135, 0, 0.210818511, -0.0745355992},
6292
{0.288675135, 0, 0, 0.223606798}};
6294
// Extract relevant coefficients
6295
const double coeff0_0 = coefficients0[dof][0];
6296
const double coeff0_1 = coefficients0[dof][1];
6297
const double coeff0_2 = coefficients0[dof][2];
6298
const double coeff0_3 = coefficients0[dof][3];
6301
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
6304
/// Evaluate all basis functions at given point in cell
6305
virtual void evaluate_basis_all(double* values,
6306
const double* coordinates,
6307
const ufc::cell& c) const
6309
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
6312
/// Evaluate order n derivatives of basis function i at given point in cell
6313
virtual void evaluate_basis_derivatives(unsigned int i,
6316
const double* coordinates,
6317
const ufc::cell& c) const
6319
// Extract vertex coordinates
6320
const double * const * element_coordinates = c.coordinates;
6322
// Compute Jacobian of affine map from reference cell
6323
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
6324
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
6325
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
6326
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
6327
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
6328
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
6329
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
6330
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
6331
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
6333
// Compute sub determinants
6334
const double d00 = J_11*J_22 - J_12*J_21;
6335
const double d01 = J_12*J_20 - J_10*J_22;
6336
const double d02 = J_10*J_21 - J_11*J_20;
6338
const double d10 = J_02*J_21 - J_01*J_22;
6339
const double d11 = J_00*J_22 - J_02*J_20;
6340
const double d12 = J_01*J_20 - J_00*J_21;
6342
const double d20 = J_01*J_12 - J_02*J_11;
6343
const double d21 = J_02*J_10 - J_00*J_12;
6344
const double d22 = J_00*J_11 - J_01*J_10;
6346
// Compute determinant of Jacobian
6347
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
6349
// Compute inverse of Jacobian
6351
// Compute constants
6352
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
6353
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
6354
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
6356
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
6357
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
6358
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
6360
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
6361
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
6362
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
6364
// Get coordinates and map to the UFC reference element
6365
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
6366
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
6367
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
6369
// Map coordinates to the reference cube
6370
if (std::abs(y + z - 1.0) < 1e-08)
6373
x = -2.0 * x/(y + z - 1.0) - 1.0;
6374
if (std::abs(z - 1.0) < 1e-08)
6377
y = 2.0 * y/(1.0 - z) - 1.0;
6380
// Compute number of derivatives
6381
unsigned int num_derivatives = 1;
6383
for (unsigned int j = 0; j < n; j++)
6384
num_derivatives *= 3;
6387
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
6388
unsigned int **combinations = new unsigned int *[num_derivatives];
6390
for (unsigned int j = 0; j < num_derivatives; j++)
6392
combinations[j] = new unsigned int [n];
6393
for (unsigned int k = 0; k < n; k++)
6394
combinations[j][k] = 0;
6397
// Generate combinations of derivatives
6398
for (unsigned int row = 1; row < num_derivatives; row++)
6400
for (unsigned int num = 0; num < row; num++)
6402
for (unsigned int col = n-1; col+1 > 0; col--)
6404
if (combinations[row][col] + 1 > 2)
6405
combinations[row][col] = 0;
6408
combinations[row][col] += 1;
6415
// Compute inverse of Jacobian
6416
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
6418
// Declare transformation matrix
6419
// Declare pointer to two dimensional array and initialise
6420
double **transform = new double *[num_derivatives];
6422
for (unsigned int j = 0; j < num_derivatives; j++)
6424
transform[j] = new double [num_derivatives];
6425
for (unsigned int k = 0; k < num_derivatives; k++)
6426
transform[j][k] = 1;
6429
// Construct transformation matrix
6430
for (unsigned int row = 0; row < num_derivatives; row++)
6432
for (unsigned int col = 0; col < num_derivatives; col++)
6434
for (unsigned int k = 0; k < n; k++)
6435
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
6440
for (unsigned int j = 0; j < 1*num_derivatives; j++)
6443
// Map degree of freedom to element degree of freedom
6444
const unsigned int dof = i;
6446
// Generate scalings
6447
const double scalings_y_0 = 1;
6448
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
6449
const double scalings_z_0 = 1;
6450
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
6452
// Compute psitilde_a
6453
const double psitilde_a_0 = 1;
6454
const double psitilde_a_1 = x;
6456
// Compute psitilde_bs
6457
const double psitilde_bs_0_0 = 1;
6458
const double psitilde_bs_0_1 = 1.5*y + 0.5;
6459
const double psitilde_bs_1_0 = 1;
6461
// Compute psitilde_cs
6462
const double psitilde_cs_00_0 = 1;
6463
const double psitilde_cs_00_1 = 2*z + 1;
6464
const double psitilde_cs_01_0 = 1;
6465
const double psitilde_cs_10_0 = 1;
6467
// Compute basisvalues
6468
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
6469
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
6470
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
6471
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
6473
// Table(s) of coefficients
6474
static const double coefficients0[4][4] = \
6475
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
6476
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
6477
{0.288675135, 0, 0.210818511, -0.0745355992},
6478
{0.288675135, 0, 0, 0.223606798}};
6480
// Interesting (new) part
6481
// Tables of derivatives of the polynomial base (transpose)
6482
static const double dmats0[4][4] = \
6484
{6.32455532, 0, 0, 0},
6488
static const double dmats1[4][4] = \
6490
{3.16227766, 0, 0, 0},
6491
{5.47722558, 0, 0, 0},
6494
static const double dmats2[4][4] = \
6496
{3.16227766, 0, 0, 0},
6497
{1.82574186, 0, 0, 0},
6498
{5.16397779, 0, 0, 0}};
6500
// Compute reference derivatives
6501
// Declare pointer to array of derivatives on FIAT element
6502
double *derivatives = new double [num_derivatives];
6504
// Declare coefficients
6505
double coeff0_0 = 0;
6506
double coeff0_1 = 0;
6507
double coeff0_2 = 0;
6508
double coeff0_3 = 0;
6510
// Declare new coefficients
6511
double new_coeff0_0 = 0;
6512
double new_coeff0_1 = 0;
6513
double new_coeff0_2 = 0;
6514
double new_coeff0_3 = 0;
6516
// Loop possible derivatives
6517
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
6519
// Get values from coefficients array
6520
new_coeff0_0 = coefficients0[dof][0];
6521
new_coeff0_1 = coefficients0[dof][1];
6522
new_coeff0_2 = coefficients0[dof][2];
6523
new_coeff0_3 = coefficients0[dof][3];
6525
// Loop derivative order
6526
for (unsigned int j = 0; j < n; j++)
6528
// Update old coefficients
6529
coeff0_0 = new_coeff0_0;
6530
coeff0_1 = new_coeff0_1;
6531
coeff0_2 = new_coeff0_2;
6532
coeff0_3 = new_coeff0_3;
6534
if(combinations[deriv_num][j] == 0)
6536
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
6537
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
6538
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
6539
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
6541
if(combinations[deriv_num][j] == 1)
6543
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
6544
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
6545
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
6546
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
6548
if(combinations[deriv_num][j] == 2)
6550
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
6551
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
6552
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
6553
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
6557
// Compute derivatives on reference element as dot product of coefficients and basisvalues
6558
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
6561
// Transform derivatives back to physical element
6562
for (unsigned int row = 0; row < num_derivatives; row++)
6564
for (unsigned int col = 0; col < num_derivatives; col++)
6566
values[row] += transform[row][col]*derivatives[col];
6569
// Delete pointer to array of derivatives on FIAT element
6570
delete [] derivatives;
6572
// Delete pointer to array of combinations of derivatives and transform
6573
for (unsigned int row = 0; row < num_derivatives; row++)
6575
delete [] combinations[row];
6576
delete [] transform[row];
6579
delete [] combinations;
6580
delete [] transform;
6583
/// Evaluate order n derivatives of all basis functions at given point in cell
6584
virtual void evaluate_basis_derivatives_all(unsigned int n,
6586
const double* coordinates,
6587
const ufc::cell& c) const
6589
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
6592
/// Evaluate linear functional for dof i on the function f
6593
virtual double evaluate_dof(unsigned int i,
6594
const ufc::function& f,
6595
const ufc::cell& c) const
6597
// The reference points, direction and weights:
6598
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
6599
static const double W[4][1] = {{1}, {1}, {1}, {1}};
6600
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
6602
const double * const * x = c.coordinates;
6603
double result = 0.0;
6604
// Iterate over the points:
6605
// Evaluate basis functions for affine mapping
6606
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
6607
const double w1 = X[i][0][0];
6608
const double w2 = X[i][0][1];
6609
const double w3 = X[i][0][2];
6611
// Compute affine mapping y = F(X)
6613
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
6614
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
6615
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
6617
// Evaluate function at physical points
6619
f.evaluate(values, y, c);
6621
// Map function values using appropriate mapping
6622
// Affine map: Do nothing
6624
// Note that we do not map the weights (yet).
6626
// Take directional components
6627
for(int k = 0; k < 1; k++)
6628
result += values[k]*D[i][0][k];
6629
// Multiply by weights
6635
/// Evaluate linear functionals for all dofs on the function f
6636
virtual void evaluate_dofs(double* values,
6637
const ufc::function& f,
6638
const ufc::cell& c) const
6640
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6643
/// Interpolate vertex values from dof values
6644
virtual void interpolate_vertex_values(double* vertex_values,
6645
const double* dof_values,
6646
const ufc::cell& c) const
6648
// Evaluate at vertices and use affine mapping
6649
vertex_values[0] = dof_values[0];
6650
vertex_values[1] = dof_values[1];
6651
vertex_values[2] = dof_values[2];
6652
vertex_values[3] = dof_values[3];
6655
/// Return the number of sub elements (for a mixed element)
6656
virtual unsigned int num_sub_elements() const
6661
/// Create a new finite element for sub element i (for a mixed element)
6662
virtual ufc::finite_element* create_sub_element(unsigned int i) const
6664
return new hyperelasticity_0_finite_element_2_2();
6669
/// This class defines the interface for a finite element.
6671
class hyperelasticity_0_finite_element_2: public ufc::finite_element
6676
hyperelasticity_0_finite_element_2() : ufc::finite_element()
6682
virtual ~hyperelasticity_0_finite_element_2()
6687
/// Return a string identifying the finite element
6688
virtual const char* signature() const
6690
return "VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
6693
/// Return the cell shape
6694
virtual ufc::shape cell_shape() const
6696
return ufc::tetrahedron;
6699
/// Return the dimension of the finite element function space
6700
virtual unsigned int space_dimension() const
6705
/// Return the rank of the value space
6706
virtual unsigned int value_rank() const
6711
/// Return the dimension of the value space for axis i
6712
virtual unsigned int value_dimension(unsigned int i) const
6717
/// Evaluate basis function i at given point in cell
6718
virtual void evaluate_basis(unsigned int i,
6720
const double* coordinates,
6721
const ufc::cell& c) const
6723
// Extract vertex coordinates
6724
const double * const * element_coordinates = c.coordinates;
6726
// Compute Jacobian of affine map from reference cell
6727
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
6728
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
6729
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
6730
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
6731
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
6732
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
6733
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
6734
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
6735
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
6737
// Compute sub determinants
6738
const double d00 = J_11*J_22 - J_12*J_21;
6739
const double d01 = J_12*J_20 - J_10*J_22;
6740
const double d02 = J_10*J_21 - J_11*J_20;
6742
const double d10 = J_02*J_21 - J_01*J_22;
6743
const double d11 = J_00*J_22 - J_02*J_20;
6744
const double d12 = J_01*J_20 - J_00*J_21;
6746
const double d20 = J_01*J_12 - J_02*J_11;
6747
const double d21 = J_02*J_10 - J_00*J_12;
6748
const double d22 = J_00*J_11 - J_01*J_10;
6750
// Compute determinant of Jacobian
6751
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
6753
// Compute inverse of Jacobian
6755
// Compute constants
6756
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
6757
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
6758
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
6760
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
6761
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
6762
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
6764
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
6765
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
6766
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
6768
// Get coordinates and map to the UFC reference element
6769
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
6770
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
6771
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
6773
// Map coordinates to the reference cube
6774
if (std::abs(y + z - 1.0) < 1e-08)
6777
x = -2.0 * x/(y + z - 1.0) - 1.0;
6778
if (std::abs(z - 1.0) < 1e-08)
6781
y = 2.0 * y/(1.0 - z) - 1.0;
6789
if (0 <= i && i <= 3)
6791
// Map degree of freedom to element degree of freedom
6792
const unsigned int dof = i;
6794
// Generate scalings
6795
const double scalings_y_0 = 1;
6796
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
6797
const double scalings_z_0 = 1;
6798
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
6800
// Compute psitilde_a
6801
const double psitilde_a_0 = 1;
6802
const double psitilde_a_1 = x;
6804
// Compute psitilde_bs
6805
const double psitilde_bs_0_0 = 1;
6806
const double psitilde_bs_0_1 = 1.5*y + 0.5;
6807
const double psitilde_bs_1_0 = 1;
6809
// Compute psitilde_cs
6810
const double psitilde_cs_00_0 = 1;
6811
const double psitilde_cs_00_1 = 2*z + 1;
6812
const double psitilde_cs_01_0 = 1;
6813
const double psitilde_cs_10_0 = 1;
6815
// Compute basisvalues
6816
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
6817
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
6818
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
6819
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
6821
// Table(s) of coefficients
6822
static const double coefficients0[4][4] = \
6823
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
6824
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
6825
{0.288675135, 0, 0.210818511, -0.0745355992},
6826
{0.288675135, 0, 0, 0.223606798}};
6828
// Extract relevant coefficients
6829
const double coeff0_0 = coefficients0[dof][0];
6830
const double coeff0_1 = coefficients0[dof][1];
6831
const double coeff0_2 = coefficients0[dof][2];
6832
const double coeff0_3 = coefficients0[dof][3];
6835
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
6838
if (4 <= i && i <= 7)
6840
// Map degree of freedom to element degree of freedom
6841
const unsigned int dof = i - 4;
6843
// Generate scalings
6844
const double scalings_y_0 = 1;
6845
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
6846
const double scalings_z_0 = 1;
6847
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
6849
// Compute psitilde_a
6850
const double psitilde_a_0 = 1;
6851
const double psitilde_a_1 = x;
6853
// Compute psitilde_bs
6854
const double psitilde_bs_0_0 = 1;
6855
const double psitilde_bs_0_1 = 1.5*y + 0.5;
6856
const double psitilde_bs_1_0 = 1;
6858
// Compute psitilde_cs
6859
const double psitilde_cs_00_0 = 1;
6860
const double psitilde_cs_00_1 = 2*z + 1;
6861
const double psitilde_cs_01_0 = 1;
6862
const double psitilde_cs_10_0 = 1;
6864
// Compute basisvalues
6865
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
6866
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
6867
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
6868
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
6870
// Table(s) of coefficients
6871
static const double coefficients0[4][4] = \
6872
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
6873
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
6874
{0.288675135, 0, 0.210818511, -0.0745355992},
6875
{0.288675135, 0, 0, 0.223606798}};
6877
// Extract relevant coefficients
6878
const double coeff0_0 = coefficients0[dof][0];
6879
const double coeff0_1 = coefficients0[dof][1];
6880
const double coeff0_2 = coefficients0[dof][2];
6881
const double coeff0_3 = coefficients0[dof][3];
6884
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
6887
if (8 <= i && i <= 11)
6889
// Map degree of freedom to element degree of freedom
6890
const unsigned int dof = i - 8;
6892
// Generate scalings
6893
const double scalings_y_0 = 1;
6894
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
6895
const double scalings_z_0 = 1;
6896
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
6898
// Compute psitilde_a
6899
const double psitilde_a_0 = 1;
6900
const double psitilde_a_1 = x;
6902
// Compute psitilde_bs
6903
const double psitilde_bs_0_0 = 1;
6904
const double psitilde_bs_0_1 = 1.5*y + 0.5;
6905
const double psitilde_bs_1_0 = 1;
6907
// Compute psitilde_cs
6908
const double psitilde_cs_00_0 = 1;
6909
const double psitilde_cs_00_1 = 2*z + 1;
6910
const double psitilde_cs_01_0 = 1;
6911
const double psitilde_cs_10_0 = 1;
6913
// Compute basisvalues
6914
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
6915
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
6916
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
6917
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
6919
// Table(s) of coefficients
6920
static const double coefficients0[4][4] = \
6921
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
6922
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
6923
{0.288675135, 0, 0.210818511, -0.0745355992},
6924
{0.288675135, 0, 0, 0.223606798}};
6926
// Extract relevant coefficients
6927
const double coeff0_0 = coefficients0[dof][0];
6928
const double coeff0_1 = coefficients0[dof][1];
6929
const double coeff0_2 = coefficients0[dof][2];
6930
const double coeff0_3 = coefficients0[dof][3];
6933
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
6938
/// Evaluate all basis functions at given point in cell
6939
virtual void evaluate_basis_all(double* values,
6940
const double* coordinates,
6941
const ufc::cell& c) const
6943
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
6946
/// Evaluate order n derivatives of basis function i at given point in cell
6947
virtual void evaluate_basis_derivatives(unsigned int i,
6950
const double* coordinates,
6951
const ufc::cell& c) const
6953
// Extract vertex coordinates
6954
const double * const * element_coordinates = c.coordinates;
6956
// Compute Jacobian of affine map from reference cell
6957
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
6958
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
6959
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
6960
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
6961
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
6962
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
6963
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
6964
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
6965
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
6967
// Compute sub determinants
6968
const double d00 = J_11*J_22 - J_12*J_21;
6969
const double d01 = J_12*J_20 - J_10*J_22;
6970
const double d02 = J_10*J_21 - J_11*J_20;
6972
const double d10 = J_02*J_21 - J_01*J_22;
6973
const double d11 = J_00*J_22 - J_02*J_20;
6974
const double d12 = J_01*J_20 - J_00*J_21;
6976
const double d20 = J_01*J_12 - J_02*J_11;
6977
const double d21 = J_02*J_10 - J_00*J_12;
6978
const double d22 = J_00*J_11 - J_01*J_10;
6980
// Compute determinant of Jacobian
6981
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
6983
// Compute inverse of Jacobian
6985
// Compute constants
6986
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
6987
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
6988
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
6990
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
6991
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
6992
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
6994
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
6995
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
6996
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
6998
// Get coordinates and map to the UFC reference element
6999
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
7000
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
7001
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
7003
// Map coordinates to the reference cube
7004
if (std::abs(y + z - 1.0) < 1e-08)
7007
x = -2.0 * x/(y + z - 1.0) - 1.0;
7008
if (std::abs(z - 1.0) < 1e-08)
7011
y = 2.0 * y/(1.0 - z) - 1.0;
7014
// Compute number of derivatives
7015
unsigned int num_derivatives = 1;
7017
for (unsigned int j = 0; j < n; j++)
7018
num_derivatives *= 3;
7021
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
7022
unsigned int **combinations = new unsigned int *[num_derivatives];
7024
for (unsigned int j = 0; j < num_derivatives; j++)
7026
combinations[j] = new unsigned int [n];
7027
for (unsigned int k = 0; k < n; k++)
7028
combinations[j][k] = 0;
7031
// Generate combinations of derivatives
7032
for (unsigned int row = 1; row < num_derivatives; row++)
7034
for (unsigned int num = 0; num < row; num++)
7036
for (unsigned int col = n-1; col+1 > 0; col--)
7038
if (combinations[row][col] + 1 > 2)
7039
combinations[row][col] = 0;
7042
combinations[row][col] += 1;
7049
// Compute inverse of Jacobian
7050
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
7052
// Declare transformation matrix
7053
// Declare pointer to two dimensional array and initialise
7054
double **transform = new double *[num_derivatives];
7056
for (unsigned int j = 0; j < num_derivatives; j++)
7058
transform[j] = new double [num_derivatives];
7059
for (unsigned int k = 0; k < num_derivatives; k++)
7060
transform[j][k] = 1;
7063
// Construct transformation matrix
7064
for (unsigned int row = 0; row < num_derivatives; row++)
7066
for (unsigned int col = 0; col < num_derivatives; col++)
7068
for (unsigned int k = 0; k < n; k++)
7069
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
7074
for (unsigned int j = 0; j < 3*num_derivatives; j++)
7077
if (0 <= i && i <= 3)
7079
// Map degree of freedom to element degree of freedom
7080
const unsigned int dof = i;
7082
// Generate scalings
7083
const double scalings_y_0 = 1;
7084
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
7085
const double scalings_z_0 = 1;
7086
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
7088
// Compute psitilde_a
7089
const double psitilde_a_0 = 1;
7090
const double psitilde_a_1 = x;
7092
// Compute psitilde_bs
7093
const double psitilde_bs_0_0 = 1;
7094
const double psitilde_bs_0_1 = 1.5*y + 0.5;
7095
const double psitilde_bs_1_0 = 1;
7097
// Compute psitilde_cs
7098
const double psitilde_cs_00_0 = 1;
7099
const double psitilde_cs_00_1 = 2*z + 1;
7100
const double psitilde_cs_01_0 = 1;
7101
const double psitilde_cs_10_0 = 1;
7103
// Compute basisvalues
7104
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
7105
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
7106
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
7107
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
7109
// Table(s) of coefficients
7110
static const double coefficients0[4][4] = \
7111
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
7112
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
7113
{0.288675135, 0, 0.210818511, -0.0745355992},
7114
{0.288675135, 0, 0, 0.223606798}};
7116
// Interesting (new) part
7117
// Tables of derivatives of the polynomial base (transpose)
7118
static const double dmats0[4][4] = \
7120
{6.32455532, 0, 0, 0},
7124
static const double dmats1[4][4] = \
7126
{3.16227766, 0, 0, 0},
7127
{5.47722558, 0, 0, 0},
7130
static const double dmats2[4][4] = \
7132
{3.16227766, 0, 0, 0},
7133
{1.82574186, 0, 0, 0},
7134
{5.16397779, 0, 0, 0}};
7136
// Compute reference derivatives
7137
// Declare pointer to array of derivatives on FIAT element
7138
double *derivatives = new double [num_derivatives];
7140
// Declare coefficients
7141
double coeff0_0 = 0;
7142
double coeff0_1 = 0;
7143
double coeff0_2 = 0;
7144
double coeff0_3 = 0;
7146
// Declare new coefficients
7147
double new_coeff0_0 = 0;
7148
double new_coeff0_1 = 0;
7149
double new_coeff0_2 = 0;
7150
double new_coeff0_3 = 0;
7152
// Loop possible derivatives
7153
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
7155
// Get values from coefficients array
7156
new_coeff0_0 = coefficients0[dof][0];
7157
new_coeff0_1 = coefficients0[dof][1];
7158
new_coeff0_2 = coefficients0[dof][2];
7159
new_coeff0_3 = coefficients0[dof][3];
7161
// Loop derivative order
7162
for (unsigned int j = 0; j < n; j++)
7164
// Update old coefficients
7165
coeff0_0 = new_coeff0_0;
7166
coeff0_1 = new_coeff0_1;
7167
coeff0_2 = new_coeff0_2;
7168
coeff0_3 = new_coeff0_3;
7170
if(combinations[deriv_num][j] == 0)
7172
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
7173
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
7174
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
7175
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
7177
if(combinations[deriv_num][j] == 1)
7179
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
7180
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
7181
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
7182
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
7184
if(combinations[deriv_num][j] == 2)
7186
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
7187
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
7188
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
7189
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
7193
// Compute derivatives on reference element as dot product of coefficients and basisvalues
7194
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
7197
// Transform derivatives back to physical element
7198
for (unsigned int row = 0; row < num_derivatives; row++)
7200
for (unsigned int col = 0; col < num_derivatives; col++)
7202
values[row] += transform[row][col]*derivatives[col];
7205
// Delete pointer to array of derivatives on FIAT element
7206
delete [] derivatives;
7208
// Delete pointer to array of combinations of derivatives and transform
7209
for (unsigned int row = 0; row < num_derivatives; row++)
7211
delete [] combinations[row];
7212
delete [] transform[row];
7215
delete [] combinations;
7216
delete [] transform;
7219
if (4 <= i && i <= 7)
7221
// Map degree of freedom to element degree of freedom
7222
const unsigned int dof = i - 4;
7224
// Generate scalings
7225
const double scalings_y_0 = 1;
7226
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
7227
const double scalings_z_0 = 1;
7228
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
7230
// Compute psitilde_a
7231
const double psitilde_a_0 = 1;
7232
const double psitilde_a_1 = x;
7234
// Compute psitilde_bs
7235
const double psitilde_bs_0_0 = 1;
7236
const double psitilde_bs_0_1 = 1.5*y + 0.5;
7237
const double psitilde_bs_1_0 = 1;
7239
// Compute psitilde_cs
7240
const double psitilde_cs_00_0 = 1;
7241
const double psitilde_cs_00_1 = 2*z + 1;
7242
const double psitilde_cs_01_0 = 1;
7243
const double psitilde_cs_10_0 = 1;
7245
// Compute basisvalues
7246
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
7247
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
7248
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
7249
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
7251
// Table(s) of coefficients
7252
static const double coefficients0[4][4] = \
7253
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
7254
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
7255
{0.288675135, 0, 0.210818511, -0.0745355992},
7256
{0.288675135, 0, 0, 0.223606798}};
7258
// Interesting (new) part
7259
// Tables of derivatives of the polynomial base (transpose)
7260
static const double dmats0[4][4] = \
7262
{6.32455532, 0, 0, 0},
7266
static const double dmats1[4][4] = \
7268
{3.16227766, 0, 0, 0},
7269
{5.47722558, 0, 0, 0},
7272
static const double dmats2[4][4] = \
7274
{3.16227766, 0, 0, 0},
7275
{1.82574186, 0, 0, 0},
7276
{5.16397779, 0, 0, 0}};
7278
// Compute reference derivatives
7279
// Declare pointer to array of derivatives on FIAT element
7280
double *derivatives = new double [num_derivatives];
7282
// Declare coefficients
7283
double coeff0_0 = 0;
7284
double coeff0_1 = 0;
7285
double coeff0_2 = 0;
7286
double coeff0_3 = 0;
7288
// Declare new coefficients
7289
double new_coeff0_0 = 0;
7290
double new_coeff0_1 = 0;
7291
double new_coeff0_2 = 0;
7292
double new_coeff0_3 = 0;
7294
// Loop possible derivatives
7295
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
7297
// Get values from coefficients array
7298
new_coeff0_0 = coefficients0[dof][0];
7299
new_coeff0_1 = coefficients0[dof][1];
7300
new_coeff0_2 = coefficients0[dof][2];
7301
new_coeff0_3 = coefficients0[dof][3];
7303
// Loop derivative order
7304
for (unsigned int j = 0; j < n; j++)
7306
// Update old coefficients
7307
coeff0_0 = new_coeff0_0;
7308
coeff0_1 = new_coeff0_1;
7309
coeff0_2 = new_coeff0_2;
7310
coeff0_3 = new_coeff0_3;
7312
if(combinations[deriv_num][j] == 0)
7314
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
7315
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
7316
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
7317
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
7319
if(combinations[deriv_num][j] == 1)
7321
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
7322
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
7323
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
7324
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
7326
if(combinations[deriv_num][j] == 2)
7328
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
7329
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
7330
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
7331
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
7335
// Compute derivatives on reference element as dot product of coefficients and basisvalues
7336
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
7339
// Transform derivatives back to physical element
7340
for (unsigned int row = 0; row < num_derivatives; row++)
7342
for (unsigned int col = 0; col < num_derivatives; col++)
7344
values[num_derivatives + row] += transform[row][col]*derivatives[col];
7347
// Delete pointer to array of derivatives on FIAT element
7348
delete [] derivatives;
7350
// Delete pointer to array of combinations of derivatives and transform
7351
for (unsigned int row = 0; row < num_derivatives; row++)
7353
delete [] combinations[row];
7354
delete [] transform[row];
7357
delete [] combinations;
7358
delete [] transform;
7361
if (8 <= i && i <= 11)
7363
// Map degree of freedom to element degree of freedom
7364
const unsigned int dof = i - 8;
7366
// Generate scalings
7367
const double scalings_y_0 = 1;
7368
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
7369
const double scalings_z_0 = 1;
7370
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
7372
// Compute psitilde_a
7373
const double psitilde_a_0 = 1;
7374
const double psitilde_a_1 = x;
7376
// Compute psitilde_bs
7377
const double psitilde_bs_0_0 = 1;
7378
const double psitilde_bs_0_1 = 1.5*y + 0.5;
7379
const double psitilde_bs_1_0 = 1;
7381
// Compute psitilde_cs
7382
const double psitilde_cs_00_0 = 1;
7383
const double psitilde_cs_00_1 = 2*z + 1;
7384
const double psitilde_cs_01_0 = 1;
7385
const double psitilde_cs_10_0 = 1;
7387
// Compute basisvalues
7388
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
7389
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
7390
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
7391
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
7393
// Table(s) of coefficients
7394
static const double coefficients0[4][4] = \
7395
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
7396
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
7397
{0.288675135, 0, 0.210818511, -0.0745355992},
7398
{0.288675135, 0, 0, 0.223606798}};
7400
// Interesting (new) part
7401
// Tables of derivatives of the polynomial base (transpose)
7402
static const double dmats0[4][4] = \
7404
{6.32455532, 0, 0, 0},
7408
static const double dmats1[4][4] = \
7410
{3.16227766, 0, 0, 0},
7411
{5.47722558, 0, 0, 0},
7414
static const double dmats2[4][4] = \
7416
{3.16227766, 0, 0, 0},
7417
{1.82574186, 0, 0, 0},
7418
{5.16397779, 0, 0, 0}};
7420
// Compute reference derivatives
7421
// Declare pointer to array of derivatives on FIAT element
7422
double *derivatives = new double [num_derivatives];
7424
// Declare coefficients
7425
double coeff0_0 = 0;
7426
double coeff0_1 = 0;
7427
double coeff0_2 = 0;
7428
double coeff0_3 = 0;
7430
// Declare new coefficients
7431
double new_coeff0_0 = 0;
7432
double new_coeff0_1 = 0;
7433
double new_coeff0_2 = 0;
7434
double new_coeff0_3 = 0;
7436
// Loop possible derivatives
7437
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
7439
// Get values from coefficients array
7440
new_coeff0_0 = coefficients0[dof][0];
7441
new_coeff0_1 = coefficients0[dof][1];
7442
new_coeff0_2 = coefficients0[dof][2];
7443
new_coeff0_3 = coefficients0[dof][3];
7445
// Loop derivative order
7446
for (unsigned int j = 0; j < n; j++)
7448
// Update old coefficients
7449
coeff0_0 = new_coeff0_0;
7450
coeff0_1 = new_coeff0_1;
7451
coeff0_2 = new_coeff0_2;
7452
coeff0_3 = new_coeff0_3;
7454
if(combinations[deriv_num][j] == 0)
7456
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
7457
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
7458
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
7459
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
7461
if(combinations[deriv_num][j] == 1)
7463
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
7464
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
7465
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
7466
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
7468
if(combinations[deriv_num][j] == 2)
7470
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
7471
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
7472
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
7473
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
7477
// Compute derivatives on reference element as dot product of coefficients and basisvalues
7478
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
7481
// Transform derivatives back to physical element
7482
for (unsigned int row = 0; row < num_derivatives; row++)
7484
for (unsigned int col = 0; col < num_derivatives; col++)
7486
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
7489
// Delete pointer to array of derivatives on FIAT element
7490
delete [] derivatives;
7492
// Delete pointer to array of combinations of derivatives and transform
7493
for (unsigned int row = 0; row < num_derivatives; row++)
7495
delete [] combinations[row];
7496
delete [] transform[row];
7499
delete [] combinations;
7500
delete [] transform;
7505
/// Evaluate order n derivatives of all basis functions at given point in cell
7506
virtual void evaluate_basis_derivatives_all(unsigned int n,
7508
const double* coordinates,
7509
const ufc::cell& c) const
7511
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
7514
/// Evaluate linear functional for dof i on the function f
7515
virtual double evaluate_dof(unsigned int i,
7516
const ufc::function& f,
7517
const ufc::cell& c) const
7519
// The reference points, direction and weights:
7520
static const double X[12][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
7521
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
7522
static const double D[12][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
7524
const double * const * x = c.coordinates;
7525
double result = 0.0;
7526
// Iterate over the points:
7527
// Evaluate basis functions for affine mapping
7528
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
7529
const double w1 = X[i][0][0];
7530
const double w2 = X[i][0][1];
7531
const double w3 = X[i][0][2];
7533
// Compute affine mapping y = F(X)
7535
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
7536
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
7537
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
7539
// Evaluate function at physical points
7541
f.evaluate(values, y, c);
7543
// Map function values using appropriate mapping
7544
// Affine map: Do nothing
7546
// Note that we do not map the weights (yet).
7548
// Take directional components
7549
for(int k = 0; k < 3; k++)
7550
result += values[k]*D[i][0][k];
7551
// Multiply by weights
7557
/// Evaluate linear functionals for all dofs on the function f
7558
virtual void evaluate_dofs(double* values,
7559
const ufc::function& f,
7560
const ufc::cell& c) const
7562
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7565
/// Interpolate vertex values from dof values
7566
virtual void interpolate_vertex_values(double* vertex_values,
7567
const double* dof_values,
7568
const ufc::cell& c) const
7570
// Evaluate at vertices and use affine mapping
7571
vertex_values[0] = dof_values[0];
7572
vertex_values[3] = dof_values[1];
7573
vertex_values[6] = dof_values[2];
7574
vertex_values[9] = dof_values[3];
7575
// Evaluate at vertices and use affine mapping
7576
vertex_values[1] = dof_values[4];
7577
vertex_values[4] = dof_values[5];
7578
vertex_values[7] = dof_values[6];
7579
vertex_values[10] = dof_values[7];
7580
// Evaluate at vertices and use affine mapping
7581
vertex_values[2] = dof_values[8];
7582
vertex_values[5] = dof_values[9];
7583
vertex_values[8] = dof_values[10];
7584
vertex_values[11] = dof_values[11];
7587
/// Return the number of sub elements (for a mixed element)
7588
virtual unsigned int num_sub_elements() const
7593
/// Create a new finite element for sub element i (for a mixed element)
7594
virtual ufc::finite_element* create_sub_element(unsigned int i) const
7599
return new hyperelasticity_0_finite_element_2_0();
7602
return new hyperelasticity_0_finite_element_2_1();
7605
return new hyperelasticity_0_finite_element_2_2();
7613
/// This class defines the interface for a finite element.
7615
class hyperelasticity_0_finite_element_3: public ufc::finite_element
7620
hyperelasticity_0_finite_element_3() : ufc::finite_element()
7626
virtual ~hyperelasticity_0_finite_element_3()
7631
/// Return a string identifying the finite element
7632
virtual const char* signature() const
7634
return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
7637
/// Return the cell shape
7638
virtual ufc::shape cell_shape() const
7640
return ufc::tetrahedron;
7643
/// Return the dimension of the finite element function space
7644
virtual unsigned int space_dimension() const
7649
/// Return the rank of the value space
7650
virtual unsigned int value_rank() const
7655
/// Return the dimension of the value space for axis i
7656
virtual unsigned int value_dimension(unsigned int i) const
7661
/// Evaluate basis function i at given point in cell
7662
virtual void evaluate_basis(unsigned int i,
7664
const double* coordinates,
7665
const ufc::cell& c) const
7667
// Extract vertex coordinates
7668
const double * const * element_coordinates = c.coordinates;
7670
// Compute Jacobian of affine map from reference cell
7671
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
7672
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
7673
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
7674
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
7675
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
7676
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
7677
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
7678
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
7679
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
7681
// Compute sub determinants
7682
const double d00 = J_11*J_22 - J_12*J_21;
7683
const double d01 = J_12*J_20 - J_10*J_22;
7684
const double d02 = J_10*J_21 - J_11*J_20;
7686
const double d10 = J_02*J_21 - J_01*J_22;
7687
const double d11 = J_00*J_22 - J_02*J_20;
7688
const double d12 = J_01*J_20 - J_00*J_21;
7690
const double d20 = J_01*J_12 - J_02*J_11;
7691
const double d21 = J_02*J_10 - J_00*J_12;
7692
const double d22 = J_00*J_11 - J_01*J_10;
7694
// Compute determinant of Jacobian
7695
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
7697
// Compute inverse of Jacobian
7699
// Compute constants
7700
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
7701
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
7702
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
7704
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
7705
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
7706
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
7708
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
7709
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
7710
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
7712
// Get coordinates and map to the UFC reference element
7713
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
7714
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
7715
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
7717
// Map coordinates to the reference cube
7718
if (std::abs(y + z - 1.0) < 1e-08)
7721
x = -2.0 * x/(y + z - 1.0) - 1.0;
7722
if (std::abs(z - 1.0) < 1e-08)
7725
y = 2.0 * y/(1.0 - z) - 1.0;
7731
// Map degree of freedom to element degree of freedom
7732
const unsigned int dof = i;
7734
// Generate scalings
7735
const double scalings_y_0 = 1;
7736
const double scalings_z_0 = 1;
7738
// Compute psitilde_a
7739
const double psitilde_a_0 = 1;
7741
// Compute psitilde_bs
7742
const double psitilde_bs_0_0 = 1;
7744
// Compute psitilde_cs
7745
const double psitilde_cs_00_0 = 1;
7747
// Compute basisvalues
7748
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
7750
// Table(s) of coefficients
7751
static const double coefficients0[1][1] = \
7754
// Extract relevant coefficients
7755
const double coeff0_0 = coefficients0[dof][0];
7758
*values = coeff0_0*basisvalue0;
7761
/// Evaluate all basis functions at given point in cell
7762
virtual void evaluate_basis_all(double* values,
7763
const double* coordinates,
7764
const ufc::cell& c) const
7766
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
7769
/// Evaluate order n derivatives of basis function i at given point in cell
7770
virtual void evaluate_basis_derivatives(unsigned int i,
7773
const double* coordinates,
7774
const ufc::cell& c) const
7776
// Extract vertex coordinates
7777
const double * const * element_coordinates = c.coordinates;
7779
// Compute Jacobian of affine map from reference cell
7780
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
7781
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
7782
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
7783
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
7784
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
7785
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
7786
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
7787
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
7788
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
7790
// Compute sub determinants
7791
const double d00 = J_11*J_22 - J_12*J_21;
7792
const double d01 = J_12*J_20 - J_10*J_22;
7793
const double d02 = J_10*J_21 - J_11*J_20;
7795
const double d10 = J_02*J_21 - J_01*J_22;
7796
const double d11 = J_00*J_22 - J_02*J_20;
7797
const double d12 = J_01*J_20 - J_00*J_21;
7799
const double d20 = J_01*J_12 - J_02*J_11;
7800
const double d21 = J_02*J_10 - J_00*J_12;
7801
const double d22 = J_00*J_11 - J_01*J_10;
7803
// Compute determinant of Jacobian
7804
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
7806
// Compute inverse of Jacobian
7808
// Compute constants
7809
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
7810
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
7811
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
7813
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
7814
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
7815
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
7817
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
7818
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
7819
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
7821
// Get coordinates and map to the UFC reference element
7822
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
7823
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
7824
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
7826
// Map coordinates to the reference cube
7827
if (std::abs(y + z - 1.0) < 1e-08)
7830
x = -2.0 * x/(y + z - 1.0) - 1.0;
7831
if (std::abs(z - 1.0) < 1e-08)
7834
y = 2.0 * y/(1.0 - z) - 1.0;
7837
// Compute number of derivatives
7838
unsigned int num_derivatives = 1;
7840
for (unsigned int j = 0; j < n; j++)
7841
num_derivatives *= 3;
7844
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
7845
unsigned int **combinations = new unsigned int *[num_derivatives];
7847
for (unsigned int j = 0; j < num_derivatives; j++)
7849
combinations[j] = new unsigned int [n];
7850
for (unsigned int k = 0; k < n; k++)
7851
combinations[j][k] = 0;
7854
// Generate combinations of derivatives
7855
for (unsigned int row = 1; row < num_derivatives; row++)
7857
for (unsigned int num = 0; num < row; num++)
7859
for (unsigned int col = n-1; col+1 > 0; col--)
7861
if (combinations[row][col] + 1 > 2)
7862
combinations[row][col] = 0;
7865
combinations[row][col] += 1;
7872
// Compute inverse of Jacobian
7873
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
7875
// Declare transformation matrix
7876
// Declare pointer to two dimensional array and initialise
7877
double **transform = new double *[num_derivatives];
7879
for (unsigned int j = 0; j < num_derivatives; j++)
7881
transform[j] = new double [num_derivatives];
7882
for (unsigned int k = 0; k < num_derivatives; k++)
7883
transform[j][k] = 1;
7886
// Construct transformation matrix
7887
for (unsigned int row = 0; row < num_derivatives; row++)
7889
for (unsigned int col = 0; col < num_derivatives; col++)
7891
for (unsigned int k = 0; k < n; k++)
7892
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
7897
for (unsigned int j = 0; j < 1*num_derivatives; j++)
7900
// Map degree of freedom to element degree of freedom
7901
const unsigned int dof = i;
7903
// Generate scalings
7904
const double scalings_y_0 = 1;
7905
const double scalings_z_0 = 1;
7907
// Compute psitilde_a
7908
const double psitilde_a_0 = 1;
7910
// Compute psitilde_bs
7911
const double psitilde_bs_0_0 = 1;
7913
// Compute psitilde_cs
7914
const double psitilde_cs_00_0 = 1;
7916
// Compute basisvalues
7917
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
7919
// Table(s) of coefficients
7920
static const double coefficients0[1][1] = \
7923
// Interesting (new) part
7924
// Tables of derivatives of the polynomial base (transpose)
7925
static const double dmats0[1][1] = \
7928
static const double dmats1[1][1] = \
7931
static const double dmats2[1][1] = \
7934
// Compute reference derivatives
7935
// Declare pointer to array of derivatives on FIAT element
7936
double *derivatives = new double [num_derivatives];
7938
// Declare coefficients
7939
double coeff0_0 = 0;
7941
// Declare new coefficients
7942
double new_coeff0_0 = 0;
7944
// Loop possible derivatives
7945
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
7947
// Get values from coefficients array
7948
new_coeff0_0 = coefficients0[dof][0];
7950
// Loop derivative order
7951
for (unsigned int j = 0; j < n; j++)
7953
// Update old coefficients
7954
coeff0_0 = new_coeff0_0;
7956
if(combinations[deriv_num][j] == 0)
7958
new_coeff0_0 = coeff0_0*dmats0[0][0];
7960
if(combinations[deriv_num][j] == 1)
7962
new_coeff0_0 = coeff0_0*dmats1[0][0];
7964
if(combinations[deriv_num][j] == 2)
7966
new_coeff0_0 = coeff0_0*dmats2[0][0];
7970
// Compute derivatives on reference element as dot product of coefficients and basisvalues
7971
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
7974
// Transform derivatives back to physical element
7975
for (unsigned int row = 0; row < num_derivatives; row++)
7977
for (unsigned int col = 0; col < num_derivatives; col++)
7979
values[row] += transform[row][col]*derivatives[col];
7982
// Delete pointer to array of derivatives on FIAT element
7983
delete [] derivatives;
7985
// Delete pointer to array of combinations of derivatives and transform
7986
for (unsigned int row = 0; row < num_derivatives; row++)
7988
delete [] combinations[row];
7989
delete [] transform[row];
7992
delete [] combinations;
7993
delete [] transform;
7996
/// Evaluate order n derivatives of all basis functions at given point in cell
7997
virtual void evaluate_basis_derivatives_all(unsigned int n,
7999
const double* coordinates,
8000
const ufc::cell& c) const
8002
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8005
/// Evaluate linear functional for dof i on the function f
8006
virtual double evaluate_dof(unsigned int i,
8007
const ufc::function& f,
8008
const ufc::cell& c) const
8010
// The reference points, direction and weights:
8011
static const double X[1][1][3] = {{{0.25, 0.25, 0.25}}};
8012
static const double W[1][1] = {{1}};
8013
static const double D[1][1][1] = {{{1}}};
8015
const double * const * x = c.coordinates;
8016
double result = 0.0;
8017
// Iterate over the points:
8018
// Evaluate basis functions for affine mapping
8019
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
8020
const double w1 = X[i][0][0];
8021
const double w2 = X[i][0][1];
8022
const double w3 = X[i][0][2];
8024
// Compute affine mapping y = F(X)
8026
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
8027
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
8028
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
8030
// Evaluate function at physical points
8032
f.evaluate(values, y, c);
8034
// Map function values using appropriate mapping
8035
// Affine map: Do nothing
8037
// Note that we do not map the weights (yet).
8039
// Take directional components
8040
for(int k = 0; k < 1; k++)
8041
result += values[k]*D[i][0][k];
8042
// Multiply by weights
8048
/// Evaluate linear functionals for all dofs on the function f
8049
virtual void evaluate_dofs(double* values,
8050
const ufc::function& f,
8051
const ufc::cell& c) const
8053
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8056
/// Interpolate vertex values from dof values
8057
virtual void interpolate_vertex_values(double* vertex_values,
8058
const double* dof_values,
8059
const ufc::cell& c) const
8061
// Evaluate at vertices and use affine mapping
8062
vertex_values[0] = dof_values[0];
8063
vertex_values[1] = dof_values[0];
8064
vertex_values[2] = dof_values[0];
8065
vertex_values[3] = dof_values[0];
8068
/// Return the number of sub elements (for a mixed element)
8069
virtual unsigned int num_sub_elements() const
8074
/// Create a new finite element for sub element i (for a mixed element)
8075
virtual ufc::finite_element* create_sub_element(unsigned int i) const
8077
return new hyperelasticity_0_finite_element_3();
8082
/// This class defines the interface for a finite element.
8084
class hyperelasticity_0_finite_element_4: public ufc::finite_element
8089
hyperelasticity_0_finite_element_4() : ufc::finite_element()
8095
virtual ~hyperelasticity_0_finite_element_4()
8100
/// Return a string identifying the finite element
8101
virtual const char* signature() const
8103
return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
8106
/// Return the cell shape
8107
virtual ufc::shape cell_shape() const
8109
return ufc::tetrahedron;
8112
/// Return the dimension of the finite element function space
8113
virtual unsigned int space_dimension() const
8118
/// Return the rank of the value space
8119
virtual unsigned int value_rank() const
8124
/// Return the dimension of the value space for axis i
8125
virtual unsigned int value_dimension(unsigned int i) const
8130
/// Evaluate basis function i at given point in cell
8131
virtual void evaluate_basis(unsigned int i,
8133
const double* coordinates,
8134
const ufc::cell& c) const
8136
// Extract vertex coordinates
8137
const double * const * element_coordinates = c.coordinates;
8139
// Compute Jacobian of affine map from reference cell
8140
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8141
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8142
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
8143
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8144
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8145
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
8146
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
8147
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
8148
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
8150
// Compute sub determinants
8151
const double d00 = J_11*J_22 - J_12*J_21;
8152
const double d01 = J_12*J_20 - J_10*J_22;
8153
const double d02 = J_10*J_21 - J_11*J_20;
8155
const double d10 = J_02*J_21 - J_01*J_22;
8156
const double d11 = J_00*J_22 - J_02*J_20;
8157
const double d12 = J_01*J_20 - J_00*J_21;
8159
const double d20 = J_01*J_12 - J_02*J_11;
8160
const double d21 = J_02*J_10 - J_00*J_12;
8161
const double d22 = J_00*J_11 - J_01*J_10;
8163
// Compute determinant of Jacobian
8164
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
8166
// Compute inverse of Jacobian
8168
// Compute constants
8169
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
8170
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
8171
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
8173
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
8174
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
8175
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
8177
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
8178
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
8179
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
8181
// Get coordinates and map to the UFC reference element
8182
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
8183
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
8184
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
8186
// Map coordinates to the reference cube
8187
if (std::abs(y + z - 1.0) < 1e-08)
8190
x = -2.0 * x/(y + z - 1.0) - 1.0;
8191
if (std::abs(z - 1.0) < 1e-08)
8194
y = 2.0 * y/(1.0 - z) - 1.0;
8200
// Map degree of freedom to element degree of freedom
8201
const unsigned int dof = i;
8203
// Generate scalings
8204
const double scalings_y_0 = 1;
8205
const double scalings_z_0 = 1;
8207
// Compute psitilde_a
8208
const double psitilde_a_0 = 1;
8210
// Compute psitilde_bs
8211
const double psitilde_bs_0_0 = 1;
8213
// Compute psitilde_cs
8214
const double psitilde_cs_00_0 = 1;
8216
// Compute basisvalues
8217
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
8219
// Table(s) of coefficients
8220
static const double coefficients0[1][1] = \
8223
// Extract relevant coefficients
8224
const double coeff0_0 = coefficients0[dof][0];
8227
*values = coeff0_0*basisvalue0;
8230
/// Evaluate all basis functions at given point in cell
8231
virtual void evaluate_basis_all(double* values,
8232
const double* coordinates,
8233
const ufc::cell& c) const
8235
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8238
/// Evaluate order n derivatives of basis function i at given point in cell
8239
virtual void evaluate_basis_derivatives(unsigned int i,
8242
const double* coordinates,
8243
const ufc::cell& c) const
8245
// Extract vertex coordinates
8246
const double * const * element_coordinates = c.coordinates;
8248
// Compute Jacobian of affine map from reference cell
8249
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8250
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8251
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
8252
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8253
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8254
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
8255
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
8256
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
8257
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
8259
// Compute sub determinants
8260
const double d00 = J_11*J_22 - J_12*J_21;
8261
const double d01 = J_12*J_20 - J_10*J_22;
8262
const double d02 = J_10*J_21 - J_11*J_20;
8264
const double d10 = J_02*J_21 - J_01*J_22;
8265
const double d11 = J_00*J_22 - J_02*J_20;
8266
const double d12 = J_01*J_20 - J_00*J_21;
8268
const double d20 = J_01*J_12 - J_02*J_11;
8269
const double d21 = J_02*J_10 - J_00*J_12;
8270
const double d22 = J_00*J_11 - J_01*J_10;
8272
// Compute determinant of Jacobian
8273
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
8275
// Compute inverse of Jacobian
8277
// Compute constants
8278
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
8279
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
8280
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
8282
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
8283
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
8284
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
8286
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
8287
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
8288
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
8290
// Get coordinates and map to the UFC reference element
8291
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
8292
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
8293
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
8295
// Map coordinates to the reference cube
8296
if (std::abs(y + z - 1.0) < 1e-08)
8299
x = -2.0 * x/(y + z - 1.0) - 1.0;
8300
if (std::abs(z - 1.0) < 1e-08)
8303
y = 2.0 * y/(1.0 - z) - 1.0;
8306
// Compute number of derivatives
8307
unsigned int num_derivatives = 1;
8309
for (unsigned int j = 0; j < n; j++)
8310
num_derivatives *= 3;
8313
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8314
unsigned int **combinations = new unsigned int *[num_derivatives];
8316
for (unsigned int j = 0; j < num_derivatives; j++)
8318
combinations[j] = new unsigned int [n];
8319
for (unsigned int k = 0; k < n; k++)
8320
combinations[j][k] = 0;
8323
// Generate combinations of derivatives
8324
for (unsigned int row = 1; row < num_derivatives; row++)
8326
for (unsigned int num = 0; num < row; num++)
8328
for (unsigned int col = n-1; col+1 > 0; col--)
8330
if (combinations[row][col] + 1 > 2)
8331
combinations[row][col] = 0;
8334
combinations[row][col] += 1;
8341
// Compute inverse of Jacobian
8342
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
8344
// Declare transformation matrix
8345
// Declare pointer to two dimensional array and initialise
8346
double **transform = new double *[num_derivatives];
8348
for (unsigned int j = 0; j < num_derivatives; j++)
8350
transform[j] = new double [num_derivatives];
8351
for (unsigned int k = 0; k < num_derivatives; k++)
8352
transform[j][k] = 1;
8355
// Construct transformation matrix
8356
for (unsigned int row = 0; row < num_derivatives; row++)
8358
for (unsigned int col = 0; col < num_derivatives; col++)
8360
for (unsigned int k = 0; k < n; k++)
8361
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8366
for (unsigned int j = 0; j < 1*num_derivatives; j++)
8369
// Map degree of freedom to element degree of freedom
8370
const unsigned int dof = i;
8372
// Generate scalings
8373
const double scalings_y_0 = 1;
8374
const double scalings_z_0 = 1;
8376
// Compute psitilde_a
8377
const double psitilde_a_0 = 1;
8379
// Compute psitilde_bs
8380
const double psitilde_bs_0_0 = 1;
8382
// Compute psitilde_cs
8383
const double psitilde_cs_00_0 = 1;
8385
// Compute basisvalues
8386
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
8388
// Table(s) of coefficients
8389
static const double coefficients0[1][1] = \
8392
// Interesting (new) part
8393
// Tables of derivatives of the polynomial base (transpose)
8394
static const double dmats0[1][1] = \
8397
static const double dmats1[1][1] = \
8400
static const double dmats2[1][1] = \
8403
// Compute reference derivatives
8404
// Declare pointer to array of derivatives on FIAT element
8405
double *derivatives = new double [num_derivatives];
8407
// Declare coefficients
8408
double coeff0_0 = 0;
8410
// Declare new coefficients
8411
double new_coeff0_0 = 0;
8413
// Loop possible derivatives
8414
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8416
// Get values from coefficients array
8417
new_coeff0_0 = coefficients0[dof][0];
8419
// Loop derivative order
8420
for (unsigned int j = 0; j < n; j++)
8422
// Update old coefficients
8423
coeff0_0 = new_coeff0_0;
8425
if(combinations[deriv_num][j] == 0)
8427
new_coeff0_0 = coeff0_0*dmats0[0][0];
8429
if(combinations[deriv_num][j] == 1)
8431
new_coeff0_0 = coeff0_0*dmats1[0][0];
8433
if(combinations[deriv_num][j] == 2)
8435
new_coeff0_0 = coeff0_0*dmats2[0][0];
8439
// Compute derivatives on reference element as dot product of coefficients and basisvalues
8440
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
8443
// Transform derivatives back to physical element
8444
for (unsigned int row = 0; row < num_derivatives; row++)
8446
for (unsigned int col = 0; col < num_derivatives; col++)
8448
values[row] += transform[row][col]*derivatives[col];
8451
// Delete pointer to array of derivatives on FIAT element
8452
delete [] derivatives;
8454
// Delete pointer to array of combinations of derivatives and transform
8455
for (unsigned int row = 0; row < num_derivatives; row++)
8457
delete [] combinations[row];
8458
delete [] transform[row];
8461
delete [] combinations;
8462
delete [] transform;
8465
/// Evaluate order n derivatives of all basis functions at given point in cell
8466
virtual void evaluate_basis_derivatives_all(unsigned int n,
8468
const double* coordinates,
8469
const ufc::cell& c) const
8471
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8474
/// Evaluate linear functional for dof i on the function f
8475
virtual double evaluate_dof(unsigned int i,
8476
const ufc::function& f,
8477
const ufc::cell& c) const
8479
// The reference points, direction and weights:
8480
static const double X[1][1][3] = {{{0.25, 0.25, 0.25}}};
8481
static const double W[1][1] = {{1}};
8482
static const double D[1][1][1] = {{{1}}};
8484
const double * const * x = c.coordinates;
8485
double result = 0.0;
8486
// Iterate over the points:
8487
// Evaluate basis functions for affine mapping
8488
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
8489
const double w1 = X[i][0][0];
8490
const double w2 = X[i][0][1];
8491
const double w3 = X[i][0][2];
8493
// Compute affine mapping y = F(X)
8495
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
8496
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
8497
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
8499
// Evaluate function at physical points
8501
f.evaluate(values, y, c);
8503
// Map function values using appropriate mapping
8504
// Affine map: Do nothing
8506
// Note that we do not map the weights (yet).
8508
// Take directional components
8509
for(int k = 0; k < 1; k++)
8510
result += values[k]*D[i][0][k];
8511
// Multiply by weights
8517
/// Evaluate linear functionals for all dofs on the function f
8518
virtual void evaluate_dofs(double* values,
8519
const ufc::function& f,
8520
const ufc::cell& c) const
8522
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8525
/// Interpolate vertex values from dof values
8526
virtual void interpolate_vertex_values(double* vertex_values,
8527
const double* dof_values,
8528
const ufc::cell& c) const
8530
// Evaluate at vertices and use affine mapping
8531
vertex_values[0] = dof_values[0];
8532
vertex_values[1] = dof_values[0];
8533
vertex_values[2] = dof_values[0];
8534
vertex_values[3] = dof_values[0];
8537
/// Return the number of sub elements (for a mixed element)
8538
virtual unsigned int num_sub_elements() const
8543
/// Create a new finite element for sub element i (for a mixed element)
8544
virtual ufc::finite_element* create_sub_element(unsigned int i) const
8546
return new hyperelasticity_0_finite_element_4();
8551
/// This class defines the interface for a local-to-global mapping of
8552
/// degrees of freedom (dofs).
8554
class hyperelasticity_0_dof_map_0_0: public ufc::dof_map
8558
unsigned int __global_dimension;
8563
hyperelasticity_0_dof_map_0_0() : ufc::dof_map()
8565
__global_dimension = 0;
8569
virtual ~hyperelasticity_0_dof_map_0_0()
8574
/// Return a string identifying the dof map
8575
virtual const char* signature() const
8577
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
8580
/// Return true iff mesh entities of topological dimension d are needed
8581
virtual bool needs_mesh_entities(unsigned int d) const
8601
/// Initialize dof map for mesh (return true iff init_cell() is needed)
8602
virtual bool init_mesh(const ufc::mesh& m)
8604
__global_dimension = m.num_entities[0];
8608
/// Initialize dof map for given cell
8609
virtual void init_cell(const ufc::mesh& m,
8615
/// Finish initialization of dof map for cells
8616
virtual void init_cell_finalize()
8621
/// Return the dimension of the global finite element function space
8622
virtual unsigned int global_dimension() const
8624
return __global_dimension;
8627
/// Return the dimension of the local finite element function space for a cell
8628
virtual unsigned int local_dimension(const ufc::cell& c) const
8633
/// Return the maximum dimension of the local finite element function space
8634
virtual unsigned int max_local_dimension() const
8639
// Return the geometric dimension of the coordinates this dof map provides
8640
virtual unsigned int geometric_dimension() const
8645
/// Return the number of dofs on each cell facet
8646
virtual unsigned int num_facet_dofs() const
8651
/// Return the number of dofs associated with each cell entity of dimension d
8652
virtual unsigned int num_entity_dofs(unsigned int d) const
8654
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8657
/// Tabulate the local-to-global mapping of dofs on a cell
8658
virtual void tabulate_dofs(unsigned int* dofs,
8660
const ufc::cell& c) const
8662
dofs[0] = c.entity_indices[0][0];
8663
dofs[1] = c.entity_indices[0][1];
8664
dofs[2] = c.entity_indices[0][2];
8665
dofs[3] = c.entity_indices[0][3];
8668
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
8669
virtual void tabulate_facet_dofs(unsigned int* dofs,
8670
unsigned int facet) const
8697
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
8698
virtual void tabulate_entity_dofs(unsigned int* dofs,
8699
unsigned int d, unsigned int i) const
8701
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8704
/// Tabulate the coordinates of all dofs on a cell
8705
virtual void tabulate_coordinates(double** coordinates,
8706
const ufc::cell& c) const
8708
const double * const * x = c.coordinates;
8709
coordinates[0][0] = x[0][0];
8710
coordinates[0][1] = x[0][1];
8711
coordinates[0][2] = x[0][2];
8712
coordinates[1][0] = x[1][0];
8713
coordinates[1][1] = x[1][1];
8714
coordinates[1][2] = x[1][2];
8715
coordinates[2][0] = x[2][0];
8716
coordinates[2][1] = x[2][1];
8717
coordinates[2][2] = x[2][2];
8718
coordinates[3][0] = x[3][0];
8719
coordinates[3][1] = x[3][1];
8720
coordinates[3][2] = x[3][2];
8723
/// Return the number of sub dof maps (for a mixed element)
8724
virtual unsigned int num_sub_dof_maps() const
8729
/// Create a new dof_map for sub dof map i (for a mixed element)
8730
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
8732
return new hyperelasticity_0_dof_map_0_0();
8737
/// This class defines the interface for a local-to-global mapping of
8738
/// degrees of freedom (dofs).
8740
class hyperelasticity_0_dof_map_0_1: public ufc::dof_map
8744
unsigned int __global_dimension;
8749
hyperelasticity_0_dof_map_0_1() : ufc::dof_map()
8751
__global_dimension = 0;
8755
virtual ~hyperelasticity_0_dof_map_0_1()
8760
/// Return a string identifying the dof map
8761
virtual const char* signature() const
8763
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
8766
/// Return true iff mesh entities of topological dimension d are needed
8767
virtual bool needs_mesh_entities(unsigned int d) const
8787
/// Initialize dof map for mesh (return true iff init_cell() is needed)
8788
virtual bool init_mesh(const ufc::mesh& m)
8790
__global_dimension = m.num_entities[0];
8794
/// Initialize dof map for given cell
8795
virtual void init_cell(const ufc::mesh& m,
8801
/// Finish initialization of dof map for cells
8802
virtual void init_cell_finalize()
8807
/// Return the dimension of the global finite element function space
8808
virtual unsigned int global_dimension() const
8810
return __global_dimension;
8813
/// Return the dimension of the local finite element function space for a cell
8814
virtual unsigned int local_dimension(const ufc::cell& c) const
8819
/// Return the maximum dimension of the local finite element function space
8820
virtual unsigned int max_local_dimension() const
8825
// Return the geometric dimension of the coordinates this dof map provides
8826
virtual unsigned int geometric_dimension() const
8831
/// Return the number of dofs on each cell facet
8832
virtual unsigned int num_facet_dofs() const
8837
/// Return the number of dofs associated with each cell entity of dimension d
8838
virtual unsigned int num_entity_dofs(unsigned int d) const
8840
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8843
/// Tabulate the local-to-global mapping of dofs on a cell
8844
virtual void tabulate_dofs(unsigned int* dofs,
8846
const ufc::cell& c) const
8848
dofs[0] = c.entity_indices[0][0];
8849
dofs[1] = c.entity_indices[0][1];
8850
dofs[2] = c.entity_indices[0][2];
8851
dofs[3] = c.entity_indices[0][3];
8854
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
8855
virtual void tabulate_facet_dofs(unsigned int* dofs,
8856
unsigned int facet) const
8883
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
8884
virtual void tabulate_entity_dofs(unsigned int* dofs,
8885
unsigned int d, unsigned int i) const
8887
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8890
/// Tabulate the coordinates of all dofs on a cell
8891
virtual void tabulate_coordinates(double** coordinates,
8892
const ufc::cell& c) const
8894
const double * const * x = c.coordinates;
8895
coordinates[0][0] = x[0][0];
8896
coordinates[0][1] = x[0][1];
8897
coordinates[0][2] = x[0][2];
8898
coordinates[1][0] = x[1][0];
8899
coordinates[1][1] = x[1][1];
8900
coordinates[1][2] = x[1][2];
8901
coordinates[2][0] = x[2][0];
8902
coordinates[2][1] = x[2][1];
8903
coordinates[2][2] = x[2][2];
8904
coordinates[3][0] = x[3][0];
8905
coordinates[3][1] = x[3][1];
8906
coordinates[3][2] = x[3][2];
8909
/// Return the number of sub dof maps (for a mixed element)
8910
virtual unsigned int num_sub_dof_maps() const
8915
/// Create a new dof_map for sub dof map i (for a mixed element)
8916
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
8918
return new hyperelasticity_0_dof_map_0_1();
8923
/// This class defines the interface for a local-to-global mapping of
8924
/// degrees of freedom (dofs).
8926
class hyperelasticity_0_dof_map_0_2: public ufc::dof_map
8930
unsigned int __global_dimension;
8935
hyperelasticity_0_dof_map_0_2() : ufc::dof_map()
8937
__global_dimension = 0;
8941
virtual ~hyperelasticity_0_dof_map_0_2()
8946
/// Return a string identifying the dof map
8947
virtual const char* signature() const
8949
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
8952
/// Return true iff mesh entities of topological dimension d are needed
8953
virtual bool needs_mesh_entities(unsigned int d) const
8973
/// Initialize dof map for mesh (return true iff init_cell() is needed)
8974
virtual bool init_mesh(const ufc::mesh& m)
8976
__global_dimension = m.num_entities[0];
8980
/// Initialize dof map for given cell
8981
virtual void init_cell(const ufc::mesh& m,
8987
/// Finish initialization of dof map for cells
8988
virtual void init_cell_finalize()
8993
/// Return the dimension of the global finite element function space
8994
virtual unsigned int global_dimension() const
8996
return __global_dimension;
8999
/// Return the dimension of the local finite element function space for a cell
9000
virtual unsigned int local_dimension(const ufc::cell& c) const
9005
/// Return the maximum dimension of the local finite element function space
9006
virtual unsigned int max_local_dimension() const
9011
// Return the geometric dimension of the coordinates this dof map provides
9012
virtual unsigned int geometric_dimension() const
9017
/// Return the number of dofs on each cell facet
9018
virtual unsigned int num_facet_dofs() const
9023
/// Return the number of dofs associated with each cell entity of dimension d
9024
virtual unsigned int num_entity_dofs(unsigned int d) const
9026
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9029
/// Tabulate the local-to-global mapping of dofs on a cell
9030
virtual void tabulate_dofs(unsigned int* dofs,
9032
const ufc::cell& c) const
9034
dofs[0] = c.entity_indices[0][0];
9035
dofs[1] = c.entity_indices[0][1];
9036
dofs[2] = c.entity_indices[0][2];
9037
dofs[3] = c.entity_indices[0][3];
9040
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
9041
virtual void tabulate_facet_dofs(unsigned int* dofs,
9042
unsigned int facet) const
9069
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
9070
virtual void tabulate_entity_dofs(unsigned int* dofs,
9071
unsigned int d, unsigned int i) const
9073
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9076
/// Tabulate the coordinates of all dofs on a cell
9077
virtual void tabulate_coordinates(double** coordinates,
9078
const ufc::cell& c) const
9080
const double * const * x = c.coordinates;
9081
coordinates[0][0] = x[0][0];
9082
coordinates[0][1] = x[0][1];
9083
coordinates[0][2] = x[0][2];
9084
coordinates[1][0] = x[1][0];
9085
coordinates[1][1] = x[1][1];
9086
coordinates[1][2] = x[1][2];
9087
coordinates[2][0] = x[2][0];
9088
coordinates[2][1] = x[2][1];
9089
coordinates[2][2] = x[2][2];
9090
coordinates[3][0] = x[3][0];
9091
coordinates[3][1] = x[3][1];
9092
coordinates[3][2] = x[3][2];
9095
/// Return the number of sub dof maps (for a mixed element)
9096
virtual unsigned int num_sub_dof_maps() const
9101
/// Create a new dof_map for sub dof map i (for a mixed element)
9102
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
9104
return new hyperelasticity_0_dof_map_0_2();
9109
/// This class defines the interface for a local-to-global mapping of
9110
/// degrees of freedom (dofs).
9112
class hyperelasticity_0_dof_map_0: public ufc::dof_map
9116
unsigned int __global_dimension;
9121
hyperelasticity_0_dof_map_0() : ufc::dof_map()
9123
__global_dimension = 0;
9127
virtual ~hyperelasticity_0_dof_map_0()
9132
/// Return a string identifying the dof map
9133
virtual const char* signature() const
9135
return "FFC dof map for VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
9138
/// Return true iff mesh entities of topological dimension d are needed
9139
virtual bool needs_mesh_entities(unsigned int d) const
9159
/// Initialize dof map for mesh (return true iff init_cell() is needed)
9160
virtual bool init_mesh(const ufc::mesh& m)
9162
__global_dimension = 3*m.num_entities[0];
9166
/// Initialize dof map for given cell
9167
virtual void init_cell(const ufc::mesh& m,
9173
/// Finish initialization of dof map for cells
9174
virtual void init_cell_finalize()
9179
/// Return the dimension of the global finite element function space
9180
virtual unsigned int global_dimension() const
9182
return __global_dimension;
9185
/// Return the dimension of the local finite element function space for a cell
9186
virtual unsigned int local_dimension(const ufc::cell& c) const
9191
/// Return the maximum dimension of the local finite element function space
9192
virtual unsigned int max_local_dimension() const
9197
// Return the geometric dimension of the coordinates this dof map provides
9198
virtual unsigned int geometric_dimension() const
9203
/// Return the number of dofs on each cell facet
9204
virtual unsigned int num_facet_dofs() const
9209
/// Return the number of dofs associated with each cell entity of dimension d
9210
virtual unsigned int num_entity_dofs(unsigned int d) const
9212
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9215
/// Tabulate the local-to-global mapping of dofs on a cell
9216
virtual void tabulate_dofs(unsigned int* dofs,
9218
const ufc::cell& c) const
9220
dofs[0] = c.entity_indices[0][0];
9221
dofs[1] = c.entity_indices[0][1];
9222
dofs[2] = c.entity_indices[0][2];
9223
dofs[3] = c.entity_indices[0][3];
9224
unsigned int offset = m.num_entities[0];
9225
dofs[4] = offset + c.entity_indices[0][0];
9226
dofs[5] = offset + c.entity_indices[0][1];
9227
dofs[6] = offset + c.entity_indices[0][2];
9228
dofs[7] = offset + c.entity_indices[0][3];
9229
offset = offset + m.num_entities[0];
9230
dofs[8] = offset + c.entity_indices[0][0];
9231
dofs[9] = offset + c.entity_indices[0][1];
9232
dofs[10] = offset + c.entity_indices[0][2];
9233
dofs[11] = offset + c.entity_indices[0][3];
9236
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
9237
virtual void tabulate_facet_dofs(unsigned int* dofs,
9238
unsigned int facet) const
9289
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
9290
virtual void tabulate_entity_dofs(unsigned int* dofs,
9291
unsigned int d, unsigned int i) const
9293
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9296
/// Tabulate the coordinates of all dofs on a cell
9297
virtual void tabulate_coordinates(double** coordinates,
9298
const ufc::cell& c) const
9300
const double * const * x = c.coordinates;
9301
coordinates[0][0] = x[0][0];
9302
coordinates[0][1] = x[0][1];
9303
coordinates[0][2] = x[0][2];
9304
coordinates[1][0] = x[1][0];
9305
coordinates[1][1] = x[1][1];
9306
coordinates[1][2] = x[1][2];
9307
coordinates[2][0] = x[2][0];
9308
coordinates[2][1] = x[2][1];
9309
coordinates[2][2] = x[2][2];
9310
coordinates[3][0] = x[3][0];
9311
coordinates[3][1] = x[3][1];
9312
coordinates[3][2] = x[3][2];
9313
coordinates[4][0] = x[0][0];
9314
coordinates[4][1] = x[0][1];
9315
coordinates[4][2] = x[0][2];
9316
coordinates[5][0] = x[1][0];
9317
coordinates[5][1] = x[1][1];
9318
coordinates[5][2] = x[1][2];
9319
coordinates[6][0] = x[2][0];
9320
coordinates[6][1] = x[2][1];
9321
coordinates[6][2] = x[2][2];
9322
coordinates[7][0] = x[3][0];
9323
coordinates[7][1] = x[3][1];
9324
coordinates[7][2] = x[3][2];
9325
coordinates[8][0] = x[0][0];
9326
coordinates[8][1] = x[0][1];
9327
coordinates[8][2] = x[0][2];
9328
coordinates[9][0] = x[1][0];
9329
coordinates[9][1] = x[1][1];
9330
coordinates[9][2] = x[1][2];
9331
coordinates[10][0] = x[2][0];
9332
coordinates[10][1] = x[2][1];
9333
coordinates[10][2] = x[2][2];
9334
coordinates[11][0] = x[3][0];
9335
coordinates[11][1] = x[3][1];
9336
coordinates[11][2] = x[3][2];
9339
/// Return the number of sub dof maps (for a mixed element)
9340
virtual unsigned int num_sub_dof_maps() const
9345
/// Create a new dof_map for sub dof map i (for a mixed element)
9346
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
9351
return new hyperelasticity_0_dof_map_0_0();
9354
return new hyperelasticity_0_dof_map_0_1();
9357
return new hyperelasticity_0_dof_map_0_2();
9365
/// This class defines the interface for a local-to-global mapping of
9366
/// degrees of freedom (dofs).
9368
class hyperelasticity_0_dof_map_1_0: public ufc::dof_map
9372
unsigned int __global_dimension;
9377
hyperelasticity_0_dof_map_1_0() : ufc::dof_map()
9379
__global_dimension = 0;
9383
virtual ~hyperelasticity_0_dof_map_1_0()
9388
/// Return a string identifying the dof map
9389
virtual const char* signature() const
9391
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
9394
/// Return true iff mesh entities of topological dimension d are needed
9395
virtual bool needs_mesh_entities(unsigned int d) const
9415
/// Initialize dof map for mesh (return true iff init_cell() is needed)
9416
virtual bool init_mesh(const ufc::mesh& m)
9418
__global_dimension = m.num_entities[0];
9422
/// Initialize dof map for given cell
9423
virtual void init_cell(const ufc::mesh& m,
9429
/// Finish initialization of dof map for cells
9430
virtual void init_cell_finalize()
9435
/// Return the dimension of the global finite element function space
9436
virtual unsigned int global_dimension() const
9438
return __global_dimension;
9441
/// Return the dimension of the local finite element function space for a cell
9442
virtual unsigned int local_dimension(const ufc::cell& c) const
9447
/// Return the maximum dimension of the local finite element function space
9448
virtual unsigned int max_local_dimension() const
9453
// Return the geometric dimension of the coordinates this dof map provides
9454
virtual unsigned int geometric_dimension() const
9459
/// Return the number of dofs on each cell facet
9460
virtual unsigned int num_facet_dofs() const
9465
/// Return the number of dofs associated with each cell entity of dimension d
9466
virtual unsigned int num_entity_dofs(unsigned int d) const
9468
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9471
/// Tabulate the local-to-global mapping of dofs on a cell
9472
virtual void tabulate_dofs(unsigned int* dofs,
9474
const ufc::cell& c) const
9476
dofs[0] = c.entity_indices[0][0];
9477
dofs[1] = c.entity_indices[0][1];
9478
dofs[2] = c.entity_indices[0][2];
9479
dofs[3] = c.entity_indices[0][3];
9482
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
9483
virtual void tabulate_facet_dofs(unsigned int* dofs,
9484
unsigned int facet) const
9511
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
9512
virtual void tabulate_entity_dofs(unsigned int* dofs,
9513
unsigned int d, unsigned int i) const
9515
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9518
/// Tabulate the coordinates of all dofs on a cell
9519
virtual void tabulate_coordinates(double** coordinates,
9520
const ufc::cell& c) const
9522
const double * const * x = c.coordinates;
9523
coordinates[0][0] = x[0][0];
9524
coordinates[0][1] = x[0][1];
9525
coordinates[0][2] = x[0][2];
9526
coordinates[1][0] = x[1][0];
9527
coordinates[1][1] = x[1][1];
9528
coordinates[1][2] = x[1][2];
9529
coordinates[2][0] = x[2][0];
9530
coordinates[2][1] = x[2][1];
9531
coordinates[2][2] = x[2][2];
9532
coordinates[3][0] = x[3][0];
9533
coordinates[3][1] = x[3][1];
9534
coordinates[3][2] = x[3][2];
9537
/// Return the number of sub dof maps (for a mixed element)
9538
virtual unsigned int num_sub_dof_maps() const
9543
/// Create a new dof_map for sub dof map i (for a mixed element)
9544
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
9546
return new hyperelasticity_0_dof_map_1_0();
9551
/// This class defines the interface for a local-to-global mapping of
9552
/// degrees of freedom (dofs).
9554
class hyperelasticity_0_dof_map_1_1: public ufc::dof_map
9558
unsigned int __global_dimension;
9563
hyperelasticity_0_dof_map_1_1() : ufc::dof_map()
9565
__global_dimension = 0;
9569
virtual ~hyperelasticity_0_dof_map_1_1()
9574
/// Return a string identifying the dof map
9575
virtual const char* signature() const
9577
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
9580
/// Return true iff mesh entities of topological dimension d are needed
9581
virtual bool needs_mesh_entities(unsigned int d) const
9601
/// Initialize dof map for mesh (return true iff init_cell() is needed)
9602
virtual bool init_mesh(const ufc::mesh& m)
9604
__global_dimension = m.num_entities[0];
9608
/// Initialize dof map for given cell
9609
virtual void init_cell(const ufc::mesh& m,
9615
/// Finish initialization of dof map for cells
9616
virtual void init_cell_finalize()
9621
/// Return the dimension of the global finite element function space
9622
virtual unsigned int global_dimension() const
9624
return __global_dimension;
9627
/// Return the dimension of the local finite element function space for a cell
9628
virtual unsigned int local_dimension(const ufc::cell& c) const
9633
/// Return the maximum dimension of the local finite element function space
9634
virtual unsigned int max_local_dimension() const
9639
// Return the geometric dimension of the coordinates this dof map provides
9640
virtual unsigned int geometric_dimension() const
9645
/// Return the number of dofs on each cell facet
9646
virtual unsigned int num_facet_dofs() const
9651
/// Return the number of dofs associated with each cell entity of dimension d
9652
virtual unsigned int num_entity_dofs(unsigned int d) const
9654
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9657
/// Tabulate the local-to-global mapping of dofs on a cell
9658
virtual void tabulate_dofs(unsigned int* dofs,
9660
const ufc::cell& c) const
9662
dofs[0] = c.entity_indices[0][0];
9663
dofs[1] = c.entity_indices[0][1];
9664
dofs[2] = c.entity_indices[0][2];
9665
dofs[3] = c.entity_indices[0][3];
9668
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
9669
virtual void tabulate_facet_dofs(unsigned int* dofs,
9670
unsigned int facet) const
9697
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
9698
virtual void tabulate_entity_dofs(unsigned int* dofs,
9699
unsigned int d, unsigned int i) const
9701
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9704
/// Tabulate the coordinates of all dofs on a cell
9705
virtual void tabulate_coordinates(double** coordinates,
9706
const ufc::cell& c) const
9708
const double * const * x = c.coordinates;
9709
coordinates[0][0] = x[0][0];
9710
coordinates[0][1] = x[0][1];
9711
coordinates[0][2] = x[0][2];
9712
coordinates[1][0] = x[1][0];
9713
coordinates[1][1] = x[1][1];
9714
coordinates[1][2] = x[1][2];
9715
coordinates[2][0] = x[2][0];
9716
coordinates[2][1] = x[2][1];
9717
coordinates[2][2] = x[2][2];
9718
coordinates[3][0] = x[3][0];
9719
coordinates[3][1] = x[3][1];
9720
coordinates[3][2] = x[3][2];
9723
/// Return the number of sub dof maps (for a mixed element)
9724
virtual unsigned int num_sub_dof_maps() const
9729
/// Create a new dof_map for sub dof map i (for a mixed element)
9730
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
9732
return new hyperelasticity_0_dof_map_1_1();
9737
/// This class defines the interface for a local-to-global mapping of
9738
/// degrees of freedom (dofs).
9740
class hyperelasticity_0_dof_map_1_2: public ufc::dof_map
9744
unsigned int __global_dimension;
9749
hyperelasticity_0_dof_map_1_2() : ufc::dof_map()
9751
__global_dimension = 0;
9755
virtual ~hyperelasticity_0_dof_map_1_2()
9760
/// Return a string identifying the dof map
9761
virtual const char* signature() const
9763
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
9766
/// Return true iff mesh entities of topological dimension d are needed
9767
virtual bool needs_mesh_entities(unsigned int d) const
9787
/// Initialize dof map for mesh (return true iff init_cell() is needed)
9788
virtual bool init_mesh(const ufc::mesh& m)
9790
__global_dimension = m.num_entities[0];
9794
/// Initialize dof map for given cell
9795
virtual void init_cell(const ufc::mesh& m,
9801
/// Finish initialization of dof map for cells
9802
virtual void init_cell_finalize()
9807
/// Return the dimension of the global finite element function space
9808
virtual unsigned int global_dimension() const
9810
return __global_dimension;
9813
/// Return the dimension of the local finite element function space for a cell
9814
virtual unsigned int local_dimension(const ufc::cell& c) const
9819
/// Return the maximum dimension of the local finite element function space
9820
virtual unsigned int max_local_dimension() const
9825
// Return the geometric dimension of the coordinates this dof map provides
9826
virtual unsigned int geometric_dimension() const
9831
/// Return the number of dofs on each cell facet
9832
virtual unsigned int num_facet_dofs() const
9837
/// Return the number of dofs associated with each cell entity of dimension d
9838
virtual unsigned int num_entity_dofs(unsigned int d) const
9840
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9843
/// Tabulate the local-to-global mapping of dofs on a cell
9844
virtual void tabulate_dofs(unsigned int* dofs,
9846
const ufc::cell& c) const
9848
dofs[0] = c.entity_indices[0][0];
9849
dofs[1] = c.entity_indices[0][1];
9850
dofs[2] = c.entity_indices[0][2];
9851
dofs[3] = c.entity_indices[0][3];
9854
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
9855
virtual void tabulate_facet_dofs(unsigned int* dofs,
9856
unsigned int facet) const
9883
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
9884
virtual void tabulate_entity_dofs(unsigned int* dofs,
9885
unsigned int d, unsigned int i) const
9887
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9890
/// Tabulate the coordinates of all dofs on a cell
9891
virtual void tabulate_coordinates(double** coordinates,
9892
const ufc::cell& c) const
9894
const double * const * x = c.coordinates;
9895
coordinates[0][0] = x[0][0];
9896
coordinates[0][1] = x[0][1];
9897
coordinates[0][2] = x[0][2];
9898
coordinates[1][0] = x[1][0];
9899
coordinates[1][1] = x[1][1];
9900
coordinates[1][2] = x[1][2];
9901
coordinates[2][0] = x[2][0];
9902
coordinates[2][1] = x[2][1];
9903
coordinates[2][2] = x[2][2];
9904
coordinates[3][0] = x[3][0];
9905
coordinates[3][1] = x[3][1];
9906
coordinates[3][2] = x[3][2];
9909
/// Return the number of sub dof maps (for a mixed element)
9910
virtual unsigned int num_sub_dof_maps() const
9915
/// Create a new dof_map for sub dof map i (for a mixed element)
9916
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
9918
return new hyperelasticity_0_dof_map_1_2();
9923
/// This class defines the interface for a local-to-global mapping of
9924
/// degrees of freedom (dofs).
9926
class hyperelasticity_0_dof_map_1: public ufc::dof_map
9930
unsigned int __global_dimension;
9935
hyperelasticity_0_dof_map_1() : ufc::dof_map()
9937
__global_dimension = 0;
9941
virtual ~hyperelasticity_0_dof_map_1()
9946
/// Return a string identifying the dof map
9947
virtual const char* signature() const
9949
return "FFC dof map for VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
9952
/// Return true iff mesh entities of topological dimension d are needed
9953
virtual bool needs_mesh_entities(unsigned int d) const
9973
/// Initialize dof map for mesh (return true iff init_cell() is needed)
9974
virtual bool init_mesh(const ufc::mesh& m)
9976
__global_dimension = 3*m.num_entities[0];
9980
/// Initialize dof map for given cell
9981
virtual void init_cell(const ufc::mesh& m,
9987
/// Finish initialization of dof map for cells
9988
virtual void init_cell_finalize()
9993
/// Return the dimension of the global finite element function space
9994
virtual unsigned int global_dimension() const
9996
return __global_dimension;
9999
/// Return the dimension of the local finite element function space for a cell
10000
virtual unsigned int local_dimension(const ufc::cell& c) const
10005
/// Return the maximum dimension of the local finite element function space
10006
virtual unsigned int max_local_dimension() const
10011
// Return the geometric dimension of the coordinates this dof map provides
10012
virtual unsigned int geometric_dimension() const
10017
/// Return the number of dofs on each cell facet
10018
virtual unsigned int num_facet_dofs() const
10023
/// Return the number of dofs associated with each cell entity of dimension d
10024
virtual unsigned int num_entity_dofs(unsigned int d) const
10026
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10029
/// Tabulate the local-to-global mapping of dofs on a cell
10030
virtual void tabulate_dofs(unsigned int* dofs,
10031
const ufc::mesh& m,
10032
const ufc::cell& c) const
10034
dofs[0] = c.entity_indices[0][0];
10035
dofs[1] = c.entity_indices[0][1];
10036
dofs[2] = c.entity_indices[0][2];
10037
dofs[3] = c.entity_indices[0][3];
10038
unsigned int offset = m.num_entities[0];
10039
dofs[4] = offset + c.entity_indices[0][0];
10040
dofs[5] = offset + c.entity_indices[0][1];
10041
dofs[6] = offset + c.entity_indices[0][2];
10042
dofs[7] = offset + c.entity_indices[0][3];
10043
offset = offset + m.num_entities[0];
10044
dofs[8] = offset + c.entity_indices[0][0];
10045
dofs[9] = offset + c.entity_indices[0][1];
10046
dofs[10] = offset + c.entity_indices[0][2];
10047
dofs[11] = offset + c.entity_indices[0][3];
10050
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
10051
virtual void tabulate_facet_dofs(unsigned int* dofs,
10052
unsigned int facet) const
10103
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
10104
virtual void tabulate_entity_dofs(unsigned int* dofs,
10105
unsigned int d, unsigned int i) const
10107
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10110
/// Tabulate the coordinates of all dofs on a cell
10111
virtual void tabulate_coordinates(double** coordinates,
10112
const ufc::cell& c) const
10114
const double * const * x = c.coordinates;
10115
coordinates[0][0] = x[0][0];
10116
coordinates[0][1] = x[0][1];
10117
coordinates[0][2] = x[0][2];
10118
coordinates[1][0] = x[1][0];
10119
coordinates[1][1] = x[1][1];
10120
coordinates[1][2] = x[1][2];
10121
coordinates[2][0] = x[2][0];
10122
coordinates[2][1] = x[2][1];
10123
coordinates[2][2] = x[2][2];
10124
coordinates[3][0] = x[3][0];
10125
coordinates[3][1] = x[3][1];
10126
coordinates[3][2] = x[3][2];
10127
coordinates[4][0] = x[0][0];
10128
coordinates[4][1] = x[0][1];
10129
coordinates[4][2] = x[0][2];
10130
coordinates[5][0] = x[1][0];
10131
coordinates[5][1] = x[1][1];
10132
coordinates[5][2] = x[1][2];
10133
coordinates[6][0] = x[2][0];
10134
coordinates[6][1] = x[2][1];
10135
coordinates[6][2] = x[2][2];
10136
coordinates[7][0] = x[3][0];
10137
coordinates[7][1] = x[3][1];
10138
coordinates[7][2] = x[3][2];
10139
coordinates[8][0] = x[0][0];
10140
coordinates[8][1] = x[0][1];
10141
coordinates[8][2] = x[0][2];
10142
coordinates[9][0] = x[1][0];
10143
coordinates[9][1] = x[1][1];
10144
coordinates[9][2] = x[1][2];
10145
coordinates[10][0] = x[2][0];
10146
coordinates[10][1] = x[2][1];
10147
coordinates[10][2] = x[2][2];
10148
coordinates[11][0] = x[3][0];
10149
coordinates[11][1] = x[3][1];
10150
coordinates[11][2] = x[3][2];
10153
/// Return the number of sub dof maps (for a mixed element)
10154
virtual unsigned int num_sub_dof_maps() const
10159
/// Create a new dof_map for sub dof map i (for a mixed element)
10160
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
10165
return new hyperelasticity_0_dof_map_1_0();
10168
return new hyperelasticity_0_dof_map_1_1();
10171
return new hyperelasticity_0_dof_map_1_2();
10179
/// This class defines the interface for a local-to-global mapping of
10180
/// degrees of freedom (dofs).
10182
class hyperelasticity_0_dof_map_2_0: public ufc::dof_map
10186
unsigned int __global_dimension;
10191
hyperelasticity_0_dof_map_2_0() : ufc::dof_map()
10193
__global_dimension = 0;
10197
virtual ~hyperelasticity_0_dof_map_2_0()
10202
/// Return a string identifying the dof map
10203
virtual const char* signature() const
10205
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
10208
/// Return true iff mesh entities of topological dimension d are needed
10209
virtual bool needs_mesh_entities(unsigned int d) const
10229
/// Initialize dof map for mesh (return true iff init_cell() is needed)
10230
virtual bool init_mesh(const ufc::mesh& m)
10232
__global_dimension = m.num_entities[0];
10236
/// Initialize dof map for given cell
10237
virtual void init_cell(const ufc::mesh& m,
10238
const ufc::cell& c)
10243
/// Finish initialization of dof map for cells
10244
virtual void init_cell_finalize()
10249
/// Return the dimension of the global finite element function space
10250
virtual unsigned int global_dimension() const
10252
return __global_dimension;
10255
/// Return the dimension of the local finite element function space for a cell
10256
virtual unsigned int local_dimension(const ufc::cell& c) const
10261
/// Return the maximum dimension of the local finite element function space
10262
virtual unsigned int max_local_dimension() const
10267
// Return the geometric dimension of the coordinates this dof map provides
10268
virtual unsigned int geometric_dimension() const
10273
/// Return the number of dofs on each cell facet
10274
virtual unsigned int num_facet_dofs() const
10279
/// Return the number of dofs associated with each cell entity of dimension d
10280
virtual unsigned int num_entity_dofs(unsigned int d) const
10282
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10285
/// Tabulate the local-to-global mapping of dofs on a cell
10286
virtual void tabulate_dofs(unsigned int* dofs,
10287
const ufc::mesh& m,
10288
const ufc::cell& c) const
10290
dofs[0] = c.entity_indices[0][0];
10291
dofs[1] = c.entity_indices[0][1];
10292
dofs[2] = c.entity_indices[0][2];
10293
dofs[3] = c.entity_indices[0][3];
10296
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
10297
virtual void tabulate_facet_dofs(unsigned int* dofs,
10298
unsigned int facet) const
10325
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
10326
virtual void tabulate_entity_dofs(unsigned int* dofs,
10327
unsigned int d, unsigned int i) const
10329
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10332
/// Tabulate the coordinates of all dofs on a cell
10333
virtual void tabulate_coordinates(double** coordinates,
10334
const ufc::cell& c) const
10336
const double * const * x = c.coordinates;
10337
coordinates[0][0] = x[0][0];
10338
coordinates[0][1] = x[0][1];
10339
coordinates[0][2] = x[0][2];
10340
coordinates[1][0] = x[1][0];
10341
coordinates[1][1] = x[1][1];
10342
coordinates[1][2] = x[1][2];
10343
coordinates[2][0] = x[2][0];
10344
coordinates[2][1] = x[2][1];
10345
coordinates[2][2] = x[2][2];
10346
coordinates[3][0] = x[3][0];
10347
coordinates[3][1] = x[3][1];
10348
coordinates[3][2] = x[3][2];
10351
/// Return the number of sub dof maps (for a mixed element)
10352
virtual unsigned int num_sub_dof_maps() const
10357
/// Create a new dof_map for sub dof map i (for a mixed element)
10358
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
10360
return new hyperelasticity_0_dof_map_2_0();
10365
/// This class defines the interface for a local-to-global mapping of
10366
/// degrees of freedom (dofs).
10368
class hyperelasticity_0_dof_map_2_1: public ufc::dof_map
10372
unsigned int __global_dimension;
10377
hyperelasticity_0_dof_map_2_1() : ufc::dof_map()
10379
__global_dimension = 0;
10383
virtual ~hyperelasticity_0_dof_map_2_1()
10388
/// Return a string identifying the dof map
10389
virtual const char* signature() const
10391
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
10394
/// Return true iff mesh entities of topological dimension d are needed
10395
virtual bool needs_mesh_entities(unsigned int d) const
10415
/// Initialize dof map for mesh (return true iff init_cell() is needed)
10416
virtual bool init_mesh(const ufc::mesh& m)
10418
__global_dimension = m.num_entities[0];
10422
/// Initialize dof map for given cell
10423
virtual void init_cell(const ufc::mesh& m,
10424
const ufc::cell& c)
10429
/// Finish initialization of dof map for cells
10430
virtual void init_cell_finalize()
10435
/// Return the dimension of the global finite element function space
10436
virtual unsigned int global_dimension() const
10438
return __global_dimension;
10441
/// Return the dimension of the local finite element function space for a cell
10442
virtual unsigned int local_dimension(const ufc::cell& c) const
10447
/// Return the maximum dimension of the local finite element function space
10448
virtual unsigned int max_local_dimension() const
10453
// Return the geometric dimension of the coordinates this dof map provides
10454
virtual unsigned int geometric_dimension() const
10459
/// Return the number of dofs on each cell facet
10460
virtual unsigned int num_facet_dofs() const
10465
/// Return the number of dofs associated with each cell entity of dimension d
10466
virtual unsigned int num_entity_dofs(unsigned int d) const
10468
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10471
/// Tabulate the local-to-global mapping of dofs on a cell
10472
virtual void tabulate_dofs(unsigned int* dofs,
10473
const ufc::mesh& m,
10474
const ufc::cell& c) const
10476
dofs[0] = c.entity_indices[0][0];
10477
dofs[1] = c.entity_indices[0][1];
10478
dofs[2] = c.entity_indices[0][2];
10479
dofs[3] = c.entity_indices[0][3];
10482
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
10483
virtual void tabulate_facet_dofs(unsigned int* dofs,
10484
unsigned int facet) const
10511
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
10512
virtual void tabulate_entity_dofs(unsigned int* dofs,
10513
unsigned int d, unsigned int i) const
10515
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10518
/// Tabulate the coordinates of all dofs on a cell
10519
virtual void tabulate_coordinates(double** coordinates,
10520
const ufc::cell& c) const
10522
const double * const * x = c.coordinates;
10523
coordinates[0][0] = x[0][0];
10524
coordinates[0][1] = x[0][1];
10525
coordinates[0][2] = x[0][2];
10526
coordinates[1][0] = x[1][0];
10527
coordinates[1][1] = x[1][1];
10528
coordinates[1][2] = x[1][2];
10529
coordinates[2][0] = x[2][0];
10530
coordinates[2][1] = x[2][1];
10531
coordinates[2][2] = x[2][2];
10532
coordinates[3][0] = x[3][0];
10533
coordinates[3][1] = x[3][1];
10534
coordinates[3][2] = x[3][2];
10537
/// Return the number of sub dof maps (for a mixed element)
10538
virtual unsigned int num_sub_dof_maps() const
10543
/// Create a new dof_map for sub dof map i (for a mixed element)
10544
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
10546
return new hyperelasticity_0_dof_map_2_1();
10551
/// This class defines the interface for a local-to-global mapping of
10552
/// degrees of freedom (dofs).
10554
class hyperelasticity_0_dof_map_2_2: public ufc::dof_map
10558
unsigned int __global_dimension;
10563
hyperelasticity_0_dof_map_2_2() : ufc::dof_map()
10565
__global_dimension = 0;
10569
virtual ~hyperelasticity_0_dof_map_2_2()
10574
/// Return a string identifying the dof map
10575
virtual const char* signature() const
10577
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
10580
/// Return true iff mesh entities of topological dimension d are needed
10581
virtual bool needs_mesh_entities(unsigned int d) const
10601
/// Initialize dof map for mesh (return true iff init_cell() is needed)
10602
virtual bool init_mesh(const ufc::mesh& m)
10604
__global_dimension = m.num_entities[0];
10608
/// Initialize dof map for given cell
10609
virtual void init_cell(const ufc::mesh& m,
10610
const ufc::cell& c)
10615
/// Finish initialization of dof map for cells
10616
virtual void init_cell_finalize()
10621
/// Return the dimension of the global finite element function space
10622
virtual unsigned int global_dimension() const
10624
return __global_dimension;
10627
/// Return the dimension of the local finite element function space for a cell
10628
virtual unsigned int local_dimension(const ufc::cell& c) const
10633
/// Return the maximum dimension of the local finite element function space
10634
virtual unsigned int max_local_dimension() const
10639
// Return the geometric dimension of the coordinates this dof map provides
10640
virtual unsigned int geometric_dimension() const
10645
/// Return the number of dofs on each cell facet
10646
virtual unsigned int num_facet_dofs() const
10651
/// Return the number of dofs associated with each cell entity of dimension d
10652
virtual unsigned int num_entity_dofs(unsigned int d) const
10654
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10657
/// Tabulate the local-to-global mapping of dofs on a cell
10658
virtual void tabulate_dofs(unsigned int* dofs,
10659
const ufc::mesh& m,
10660
const ufc::cell& c) const
10662
dofs[0] = c.entity_indices[0][0];
10663
dofs[1] = c.entity_indices[0][1];
10664
dofs[2] = c.entity_indices[0][2];
10665
dofs[3] = c.entity_indices[0][3];
10668
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
10669
virtual void tabulate_facet_dofs(unsigned int* dofs,
10670
unsigned int facet) const
10697
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
10698
virtual void tabulate_entity_dofs(unsigned int* dofs,
10699
unsigned int d, unsigned int i) const
10701
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10704
/// Tabulate the coordinates of all dofs on a cell
10705
virtual void tabulate_coordinates(double** coordinates,
10706
const ufc::cell& c) const
10708
const double * const * x = c.coordinates;
10709
coordinates[0][0] = x[0][0];
10710
coordinates[0][1] = x[0][1];
10711
coordinates[0][2] = x[0][2];
10712
coordinates[1][0] = x[1][0];
10713
coordinates[1][1] = x[1][1];
10714
coordinates[1][2] = x[1][2];
10715
coordinates[2][0] = x[2][0];
10716
coordinates[2][1] = x[2][1];
10717
coordinates[2][2] = x[2][2];
10718
coordinates[3][0] = x[3][0];
10719
coordinates[3][1] = x[3][1];
10720
coordinates[3][2] = x[3][2];
10723
/// Return the number of sub dof maps (for a mixed element)
10724
virtual unsigned int num_sub_dof_maps() const
10729
/// Create a new dof_map for sub dof map i (for a mixed element)
10730
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
10732
return new hyperelasticity_0_dof_map_2_2();
10737
/// This class defines the interface for a local-to-global mapping of
10738
/// degrees of freedom (dofs).
10740
class hyperelasticity_0_dof_map_2: public ufc::dof_map
10744
unsigned int __global_dimension;
10749
hyperelasticity_0_dof_map_2() : ufc::dof_map()
10751
__global_dimension = 0;
10755
virtual ~hyperelasticity_0_dof_map_2()
10760
/// Return a string identifying the dof map
10761
virtual const char* signature() const
10763
return "FFC dof map for VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
10766
/// Return true iff mesh entities of topological dimension d are needed
10767
virtual bool needs_mesh_entities(unsigned int d) const
10787
/// Initialize dof map for mesh (return true iff init_cell() is needed)
10788
virtual bool init_mesh(const ufc::mesh& m)
10790
__global_dimension = 3*m.num_entities[0];
10794
/// Initialize dof map for given cell
10795
virtual void init_cell(const ufc::mesh& m,
10796
const ufc::cell& c)
10801
/// Finish initialization of dof map for cells
10802
virtual void init_cell_finalize()
10807
/// Return the dimension of the global finite element function space
10808
virtual unsigned int global_dimension() const
10810
return __global_dimension;
10813
/// Return the dimension of the local finite element function space for a cell
10814
virtual unsigned int local_dimension(const ufc::cell& c) const
10819
/// Return the maximum dimension of the local finite element function space
10820
virtual unsigned int max_local_dimension() const
10825
// Return the geometric dimension of the coordinates this dof map provides
10826
virtual unsigned int geometric_dimension() const
10831
/// Return the number of dofs on each cell facet
10832
virtual unsigned int num_facet_dofs() const
10837
/// Return the number of dofs associated with each cell entity of dimension d
10838
virtual unsigned int num_entity_dofs(unsigned int d) const
10840
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10843
/// Tabulate the local-to-global mapping of dofs on a cell
10844
virtual void tabulate_dofs(unsigned int* dofs,
10845
const ufc::mesh& m,
10846
const ufc::cell& c) const
10848
dofs[0] = c.entity_indices[0][0];
10849
dofs[1] = c.entity_indices[0][1];
10850
dofs[2] = c.entity_indices[0][2];
10851
dofs[3] = c.entity_indices[0][3];
10852
unsigned int offset = m.num_entities[0];
10853
dofs[4] = offset + c.entity_indices[0][0];
10854
dofs[5] = offset + c.entity_indices[0][1];
10855
dofs[6] = offset + c.entity_indices[0][2];
10856
dofs[7] = offset + c.entity_indices[0][3];
10857
offset = offset + m.num_entities[0];
10858
dofs[8] = offset + c.entity_indices[0][0];
10859
dofs[9] = offset + c.entity_indices[0][1];
10860
dofs[10] = offset + c.entity_indices[0][2];
10861
dofs[11] = offset + c.entity_indices[0][3];
10864
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
10865
virtual void tabulate_facet_dofs(unsigned int* dofs,
10866
unsigned int facet) const
10917
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
10918
virtual void tabulate_entity_dofs(unsigned int* dofs,
10919
unsigned int d, unsigned int i) const
10921
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10924
/// Tabulate the coordinates of all dofs on a cell
10925
virtual void tabulate_coordinates(double** coordinates,
10926
const ufc::cell& c) const
10928
const double * const * x = c.coordinates;
10929
coordinates[0][0] = x[0][0];
10930
coordinates[0][1] = x[0][1];
10931
coordinates[0][2] = x[0][2];
10932
coordinates[1][0] = x[1][0];
10933
coordinates[1][1] = x[1][1];
10934
coordinates[1][2] = x[1][2];
10935
coordinates[2][0] = x[2][0];
10936
coordinates[2][1] = x[2][1];
10937
coordinates[2][2] = x[2][2];
10938
coordinates[3][0] = x[3][0];
10939
coordinates[3][1] = x[3][1];
10940
coordinates[3][2] = x[3][2];
10941
coordinates[4][0] = x[0][0];
10942
coordinates[4][1] = x[0][1];
10943
coordinates[4][2] = x[0][2];
10944
coordinates[5][0] = x[1][0];
10945
coordinates[5][1] = x[1][1];
10946
coordinates[5][2] = x[1][2];
10947
coordinates[6][0] = x[2][0];
10948
coordinates[6][1] = x[2][1];
10949
coordinates[6][2] = x[2][2];
10950
coordinates[7][0] = x[3][0];
10951
coordinates[7][1] = x[3][1];
10952
coordinates[7][2] = x[3][2];
10953
coordinates[8][0] = x[0][0];
10954
coordinates[8][1] = x[0][1];
10955
coordinates[8][2] = x[0][2];
10956
coordinates[9][0] = x[1][0];
10957
coordinates[9][1] = x[1][1];
10958
coordinates[9][2] = x[1][2];
10959
coordinates[10][0] = x[2][0];
10960
coordinates[10][1] = x[2][1];
10961
coordinates[10][2] = x[2][2];
10962
coordinates[11][0] = x[3][0];
10963
coordinates[11][1] = x[3][1];
10964
coordinates[11][2] = x[3][2];
10967
/// Return the number of sub dof maps (for a mixed element)
10968
virtual unsigned int num_sub_dof_maps() const
10973
/// Create a new dof_map for sub dof map i (for a mixed element)
10974
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
10979
return new hyperelasticity_0_dof_map_2_0();
10982
return new hyperelasticity_0_dof_map_2_1();
10985
return new hyperelasticity_0_dof_map_2_2();
10993
/// This class defines the interface for a local-to-global mapping of
10994
/// degrees of freedom (dofs).
10996
class hyperelasticity_0_dof_map_3: public ufc::dof_map
11000
unsigned int __global_dimension;
11005
hyperelasticity_0_dof_map_3() : ufc::dof_map()
11007
__global_dimension = 0;
11011
virtual ~hyperelasticity_0_dof_map_3()
11016
/// Return a string identifying the dof map
11017
virtual const char* signature() const
11019
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
11022
/// Return true iff mesh entities of topological dimension d are needed
11023
virtual bool needs_mesh_entities(unsigned int d) const
11043
/// Initialize dof map for mesh (return true iff init_cell() is needed)
11044
virtual bool init_mesh(const ufc::mesh& m)
11046
__global_dimension = m.num_entities[3];
11050
/// Initialize dof map for given cell
11051
virtual void init_cell(const ufc::mesh& m,
11052
const ufc::cell& c)
11057
/// Finish initialization of dof map for cells
11058
virtual void init_cell_finalize()
11063
/// Return the dimension of the global finite element function space
11064
virtual unsigned int global_dimension() const
11066
return __global_dimension;
11069
/// Return the dimension of the local finite element function space for a cell
11070
virtual unsigned int local_dimension(const ufc::cell& c) const
11075
/// Return the maximum dimension of the local finite element function space
11076
virtual unsigned int max_local_dimension() const
11081
// Return the geometric dimension of the coordinates this dof map provides
11082
virtual unsigned int geometric_dimension() const
11087
/// Return the number of dofs on each cell facet
11088
virtual unsigned int num_facet_dofs() const
11093
/// Return the number of dofs associated with each cell entity of dimension d
11094
virtual unsigned int num_entity_dofs(unsigned int d) const
11096
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11099
/// Tabulate the local-to-global mapping of dofs on a cell
11100
virtual void tabulate_dofs(unsigned int* dofs,
11101
const ufc::mesh& m,
11102
const ufc::cell& c) const
11104
dofs[0] = c.entity_indices[3][0];
11107
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
11108
virtual void tabulate_facet_dofs(unsigned int* dofs,
11109
unsigned int facet) const
11128
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
11129
virtual void tabulate_entity_dofs(unsigned int* dofs,
11130
unsigned int d, unsigned int i) const
11132
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11135
/// Tabulate the coordinates of all dofs on a cell
11136
virtual void tabulate_coordinates(double** coordinates,
11137
const ufc::cell& c) const
11139
const double * const * x = c.coordinates;
11140
coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
11141
coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
11142
coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
11145
/// Return the number of sub dof maps (for a mixed element)
11146
virtual unsigned int num_sub_dof_maps() const
11151
/// Create a new dof_map for sub dof map i (for a mixed element)
11152
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
11154
return new hyperelasticity_0_dof_map_3();
11159
/// This class defines the interface for a local-to-global mapping of
11160
/// degrees of freedom (dofs).
11162
class hyperelasticity_0_dof_map_4: public ufc::dof_map
11166
unsigned int __global_dimension;
11171
hyperelasticity_0_dof_map_4() : ufc::dof_map()
11173
__global_dimension = 0;
11177
virtual ~hyperelasticity_0_dof_map_4()
11182
/// Return a string identifying the dof map
11183
virtual const char* signature() const
11185
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
11188
/// Return true iff mesh entities of topological dimension d are needed
11189
virtual bool needs_mesh_entities(unsigned int d) const
11209
/// Initialize dof map for mesh (return true iff init_cell() is needed)
11210
virtual bool init_mesh(const ufc::mesh& m)
11212
__global_dimension = m.num_entities[3];
11216
/// Initialize dof map for given cell
11217
virtual void init_cell(const ufc::mesh& m,
11218
const ufc::cell& c)
11223
/// Finish initialization of dof map for cells
11224
virtual void init_cell_finalize()
11229
/// Return the dimension of the global finite element function space
11230
virtual unsigned int global_dimension() const
11232
return __global_dimension;
11235
/// Return the dimension of the local finite element function space for a cell
11236
virtual unsigned int local_dimension(const ufc::cell& c) const
11241
/// Return the maximum dimension of the local finite element function space
11242
virtual unsigned int max_local_dimension() const
11247
// Return the geometric dimension of the coordinates this dof map provides
11248
virtual unsigned int geometric_dimension() const
11253
/// Return the number of dofs on each cell facet
11254
virtual unsigned int num_facet_dofs() const
11259
/// Return the number of dofs associated with each cell entity of dimension d
11260
virtual unsigned int num_entity_dofs(unsigned int d) const
11262
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11265
/// Tabulate the local-to-global mapping of dofs on a cell
11266
virtual void tabulate_dofs(unsigned int* dofs,
11267
const ufc::mesh& m,
11268
const ufc::cell& c) const
11270
dofs[0] = c.entity_indices[3][0];
11273
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
11274
virtual void tabulate_facet_dofs(unsigned int* dofs,
11275
unsigned int facet) const
11294
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
11295
virtual void tabulate_entity_dofs(unsigned int* dofs,
11296
unsigned int d, unsigned int i) const
11298
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11301
/// Tabulate the coordinates of all dofs on a cell
11302
virtual void tabulate_coordinates(double** coordinates,
11303
const ufc::cell& c) const
11305
const double * const * x = c.coordinates;
11306
coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
11307
coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
11308
coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
11311
/// Return the number of sub dof maps (for a mixed element)
11312
virtual unsigned int num_sub_dof_maps() const
11317
/// Create a new dof_map for sub dof map i (for a mixed element)
11318
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
11320
return new hyperelasticity_0_dof_map_4();
11325
/// This class defines the interface for the tabulation of the cell
11326
/// tensor corresponding to the local contribution to a form from
11327
/// the integral over a cell.
11329
class hyperelasticity_0_cell_integral_0_quadrature: public ufc::cell_integral
11334
hyperelasticity_0_cell_integral_0_quadrature() : ufc::cell_integral()
11340
virtual ~hyperelasticity_0_cell_integral_0_quadrature()
11345
/// Tabulate the tensor for the contribution from a local cell
11346
virtual void tabulate_tensor(double* A,
11347
const double * const * w,
11348
const ufc::cell& c) const
11350
// Extract vertex coordinates
11351
const double * const * x = c.coordinates;
11353
// Compute Jacobian of affine map from reference cell
11354
const double J_00 = x[1][0] - x[0][0];
11355
const double J_01 = x[2][0] - x[0][0];
11356
const double J_02 = x[3][0] - x[0][0];
11357
const double J_10 = x[1][1] - x[0][1];
11358
const double J_11 = x[2][1] - x[0][1];
11359
const double J_12 = x[3][1] - x[0][1];
11360
const double J_20 = x[1][2] - x[0][2];
11361
const double J_21 = x[2][2] - x[0][2];
11362
const double J_22 = x[3][2] - x[0][2];
11364
// Compute sub determinants
11365
const double d_00 = J_11*J_22 - J_12*J_21;
11366
const double d_01 = J_12*J_20 - J_10*J_22;
11367
const double d_02 = J_10*J_21 - J_11*J_20;
11369
const double d_10 = J_02*J_21 - J_01*J_22;
11370
const double d_11 = J_00*J_22 - J_02*J_20;
11371
const double d_12 = J_01*J_20 - J_00*J_21;
11373
const double d_20 = J_01*J_12 - J_02*J_11;
11374
const double d_21 = J_02*J_10 - J_00*J_12;
11375
const double d_22 = J_00*J_11 - J_01*J_10;
11377
// Compute determinant of Jacobian
11378
double detJ = J_00*d_00 + J_10*d_10 + J_20*d_20;
11380
// Compute inverse of Jacobian
11381
const double Jinv_00 = d_00 / detJ;
11382
const double Jinv_01 = d_10 / detJ;
11383
const double Jinv_02 = d_20 / detJ;
11384
const double Jinv_10 = d_01 / detJ;
11385
const double Jinv_11 = d_11 / detJ;
11386
const double Jinv_12 = d_21 / detJ;
11387
const double Jinv_20 = d_02 / detJ;
11388
const double Jinv_21 = d_12 / detJ;
11389
const double Jinv_22 = d_22 / detJ;
11391
// Set scale factor
11392
const double det = std::abs(detJ);
11395
// Array of quadrature weights
11396
static const double W1 = 0.166666667;
11397
// Quadrature points on the UFC reference element: (0.25, 0.25, 0.25)
11399
// Value of basis functions at quadrature points.
11400
static const double FE1_C0_D001[1][12] = \
11401
{{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}};
11403
static const double FE1_C0_D010[1][12] = \
11404
{{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
11406
static const double FE1_C0_D100[1][12] = \
11407
{{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
11409
static const double FE1_C1_D001[1][12] = \
11410
{{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0}};
11412
static const double FE1_C1_D010[1][12] = \
11413
{{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0}};
11415
static const double FE1_C1_D100[1][12] = \
11416
{{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0}};
11418
static const double FE1_C2_D001[1][12] = \
11419
{{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1}};
11421
static const double FE1_C2_D010[1][12] = \
11422
{{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0}};
11424
static const double FE1_C2_D100[1][12] = \
11425
{{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0}};
11428
// Compute element tensor using UFL quadrature representation
11429
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
11430
// Total number of operations to compute element tensor: 776808
11432
// Loop quadrature points for integral
11433
// Number of operations to compute element tensor for following IP loop = 776808
11434
// Only 1 integration point, omitting IP loop.
11436
// Function declarations
11447
// Total number of operations to compute function values = 216
11448
for (unsigned int r = 0; r < 12; r++)
11450
F0 += FE1_C0_D100[0][r]*w[0][r];
11451
F1 += FE1_C0_D010[0][r]*w[0][r];
11452
F2 += FE1_C0_D001[0][r]*w[0][r];
11453
F3 += FE1_C1_D100[0][r]*w[0][r];
11454
F4 += FE1_C1_D010[0][r]*w[0][r];
11455
F5 += FE1_C1_D001[0][r]*w[0][r];
11456
F6 += FE1_C2_D100[0][r]*w[0][r];
11457
F7 += FE1_C2_D010[0][r]*w[0][r];
11458
F8 += FE1_C2_D001[0][r]*w[0][r];
11459
}// end loop over 'r'
11461
// Number of operations for primary indices: 776592
11462
for (unsigned int j = 0; j < 12; j++)
11464
for (unsigned int k = 0; k < 12; k++)
11466
// Number of operations to compute entry: 5393
11467
A[j*12 + k] += (((((Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2)) + (2*(2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2)*w[1][0] + ((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2))*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)) + (2*(((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)))/(2)*w[1][0]*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*w[1][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2))/(2)) + ((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*w[1][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5))/(2) + 2*(((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + ((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)))/(2)*w[1][0]*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))))*(Jinv_00*FE1_C2_D100[0][j] + Jinv_10*FE1_C2_D010[0][j] + Jinv_20*FE1_C2_D001[0][j]) + ((2*(((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + ((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)))/(2)*w[1][0]*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*w[1][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5))/(2)) + ((Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*w[1][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2))/(2) + 2*(((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)))/(2)*w[1][0]*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + ((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2)) + (2*(2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2)*w[1][0] + ((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2))*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)))*(Jinv_00*FE1_C1_D100[0][j] + Jinv_10*FE1_C1_D010[0][j] + Jinv_20*FE1_C1_D001[0][j]) + (((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*w[1][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5))/(2) + 2*(((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + ((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)))/(2)*w[1][0]*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((2*(2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2)*w[1][0] + ((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2))) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*w[1][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2))/(2) + 2*(((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)))/(2)*w[1][0]*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)))*(Jinv_00*FE1_C0_D100[0][j] + Jinv_10*FE1_C0_D010[0][j] + Jinv_20*FE1_C0_D001[0][j])) + (((2*(((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)))/(2)*w[1][0]*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*w[1][0]*2*((Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2)) + ((((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2) + 2*(2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2)*w[1][0])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))) + ((Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*w[1][0]*2*((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + 2*(((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + ((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)))/(2)*w[1][0]*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)))*(Jinv_02*FE1_C2_D100[0][j] + Jinv_12*FE1_C2_D010[0][j] + Jinv_22*FE1_C2_D001[0][j]) + (((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*w[1][0]*2*((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + 2*(((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + ((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)))/(2)*w[1][0]*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + (2*(((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)))/(2)*w[1][0]*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*w[1][0]*2*((Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2)) + ((((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2) + 2*(2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2)*w[1][0])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))))*(Jinv_02*FE1_C1_D100[0][j] + Jinv_12*FE1_C1_D010[0][j] + Jinv_22*FE1_C1_D001[0][j]) + (((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2)) + (((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2) + 2*(2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2)*w[1][0])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*w[1][0]*2*((Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + 2*(((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)))/(2)*w[1][0]*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)) + ((Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*w[1][0]*2*((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + 2*(((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + ((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)))/(2)*w[1][0]*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))))*(Jinv_02*FE1_C0_D100[0][j] + Jinv_12*FE1_C0_D010[0][j] + Jinv_22*FE1_C0_D001[0][j])) + ((((Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*w[1][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)))/(2) + 2*(((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)))/(2)*w[1][0]*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + (2*(((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)))/(2)*w[1][0]*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*w[1][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2)) + (((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2) + 2*(2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2)*w[1][0])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)))*(Jinv_01*FE1_C2_D100[0][j] + Jinv_11*FE1_C2_D010[0][j] + Jinv_21*FE1_C2_D001[0][j]) + (((Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2)) + (((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2) + 2*(2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2)*w[1][0])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + ((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*w[1][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + 2*(((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)))/(2)*w[1][0]*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + ((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*w[1][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)))/(2) + 2*(((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)))/(2)*w[1][0]*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)))*(Jinv_01*FE1_C1_D100[0][j] + Jinv_11*FE1_C1_D010[0][j] + Jinv_21*FE1_C1_D001[0][j]) + (((Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*w[1][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + 2*(((Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + (Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)))/(2)*w[1][0]*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + ((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*w[1][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)))/(2) + 2*(((Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)) + ((Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)) + ((Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)))/(2)*w[1][0]*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)) + ((((2*(Jinv_02*FE1_C1_D100[0][k] + Jinv_12*FE1_C1_D010[0][k] + Jinv_22*FE1_C1_D001[0][k])*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + 2*(Jinv_02*FE1_C2_D100[0][k] + Jinv_12*FE1_C2_D010[0][k] + Jinv_22*FE1_C2_D001[0][k])*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + 2*(Jinv_02*FE1_C0_D100[0][k] + Jinv_12*FE1_C0_D010[0][k] + Jinv_22*FE1_C0_D001[0][k])*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2))/(2) + (2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (2*(Jinv_00*FE1_C1_D100[0][k] + Jinv_10*FE1_C1_D010[0][k] + Jinv_20*FE1_C1_D001[0][k])*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + 2*(Jinv_00*FE1_C0_D100[0][k] + Jinv_10*FE1_C0_D010[0][k] + Jinv_20*FE1_C0_D001[0][k])*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)) + 2*(Jinv_00*FE1_C2_D100[0][k] + Jinv_10*FE1_C2_D010[0][k] + Jinv_20*FE1_C2_D001[0][k])*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8))/(2))*2*w[2][0]/(2) + 2*(2*(Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + 2*(Jinv_01*FE1_C1_D100[0][k] + Jinv_11*FE1_C1_D010[0][k] + Jinv_21*FE1_C1_D001[0][k])*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + 2*(Jinv_01*FE1_C2_D100[0][k] + Jinv_11*FE1_C2_D010[0][k] + Jinv_21*FE1_C2_D001[0][k])*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2)*w[1][0])*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_01*FE1_C0_D100[0][k] + Jinv_11*FE1_C0_D010[0][k] + Jinv_21*FE1_C0_D001[0][k])*(w[2][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[1][0]*2*(((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2))))*(Jinv_01*FE1_C0_D100[0][j] + Jinv_11*FE1_C0_D010[0][j] + Jinv_21*FE1_C0_D001[0][j])))*W1*det;
11468
}// end loop over 'k'
11469
}// end loop over 'j'
11474
/// This class defines the interface for the tabulation of the cell
11475
/// tensor corresponding to the local contribution to a form from
11476
/// the integral over a cell.
11478
class hyperelasticity_0_cell_integral_0: public ufc::cell_integral
11482
hyperelasticity_0_cell_integral_0_quadrature integral_0_quadrature;
11487
hyperelasticity_0_cell_integral_0() : ufc::cell_integral()
11493
virtual ~hyperelasticity_0_cell_integral_0()
11498
/// Tabulate the tensor for the contribution from a local cell
11499
virtual void tabulate_tensor(double* A,
11500
const double * const * w,
11501
const ufc::cell& c) const
11503
// Reset values of the element tensor block
11504
for (unsigned int j = 0; j < 144; j++)
11507
// Add all contributions to element tensor
11508
integral_0_quadrature.tabulate_tensor(A, w, c);
11513
/// This class defines the interface for the assembly of the global
11514
/// tensor corresponding to a form with r + n arguments, that is, a
11517
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
11519
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
11520
/// global tensor A is defined by
11522
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
11524
/// where each argument Vj represents the application to the
11525
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
11526
/// fixed functions (coefficients).
11528
class hyperelasticity_form_0: public ufc::form
11533
hyperelasticity_form_0() : ufc::form()
11539
virtual ~hyperelasticity_form_0()
11544
/// Return a string identifying the form
11545
virtual const char* signature() const
11547
return "Form([Integral(IndexSum(IndexSum(Product(Indexed(ComponentTensor(IndexSum(Sum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), MultiIndex((Index(1), Index(0)), {Index(0): 3, Index(1): 3})), MultiIndex((Index(2), Index(3)), {Index(2): 3, Index(3): 3})), Indexed(Sum(ComponentTensor(Product(Constant(Cell('tetrahedron', 1, Space(3)), 1), Indexed(IndexSum(ComponentTensor(Indexed(ComponentTensor(Indexed(IndexSum(Sum(ComponentTensor(Product(Indexed(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(8), Index(9), Index(10), Index(11)), {Index(11): 3, Index(8): 3, Index(9): 3, Index(10): 3})), MultiIndex((Index(10), Index(11)), {Index(11): 3, Index(10): 3})), MultiIndex((Index(12), Index(13)), {Index(13): 3, Index(12): 3})), Indexed(Variable(ComponentTensor(Division(Indexed(Sum(ComponentTensor(IndexSum(Product(Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), ComponentTensor(Product(IntValue(-1, (), (), {}), Indexed(Identity(3), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), Label(0)), MultiIndex((Index(9), Index(27)), {Index(9): 3, Index(27): 3}))), MultiIndex((Index(12), Index(13)), {Index(13): 3, Index(12): 3})), ComponentTensor(Product(Indexed(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(9), Index(27), Index(28), Index(29)), {Index(29): 3, Index(9): 3, Index(28): 3, Index(27): 3})), MultiIndex((Index(28), Index(29)), {Index(29): 3, Index(28): 3})), MultiIndex((Index(30), Index(31)), {Index(31): 3, Index(30): 3})), Indexed(Variable(ComponentTensor(Division(Indexed(Sum(ComponentTensor(IndexSum(Product(Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), ComponentTensor(Product(IntValue(-1, (), (), {}), Indexed(Identity(3), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), Label(0)), MultiIndex((Index(8), Index(9)), {Index(8): 3, Index(9): 3}))), MultiIndex((Index(30), Index(31)), {Index(31): 3, Index(30): 3}))), MultiIndex((Index(9),), {Index(9): 3})), MultiIndex((Index(32), Index(33)), {Index(33): 3, Index(32): 3})), MultiIndex((Index(8), Index(27), Index(32), Index(33)), {Index(33): 3, Index(27): 3, Index(32): 3, Index(8): 3})), MultiIndex((Index(34), Index(34), Index(35), Index(36)), {Index(35): 3, Index(36): 3, Index(34): 3})), MultiIndex((Index(35), Index(36)), {Index(35): 3, Index(36): 3})), MultiIndex((Index(34),), {Index(34): 3})), MultiIndex((Index(37), Index(38)), {Index(37): 3, Index(38): 3}))), MultiIndex((Index(37), Index(38)), {Index(37): 3, Index(38): 3})), ComponentTensor(Product(Division(Constant(Cell('tetrahedron', 1, Space(3)), 2), IntValue(2, (), (), {})), Indexed(ComponentTensor(Product(IndexSum(Indexed(Variable(ComponentTensor(Division(Indexed(Sum(ComponentTensor(IndexSum(Product(Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), ComponentTensor(Product(IntValue(-1, (), (), {}), Indexed(Identity(3), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), Label(0)), MultiIndex((Index(39), Index(39)), {Index(39): 3})), MultiIndex((Index(39),), {Index(39): 3})), Indexed(ComponentTensor(Product(IntValue(2, (), (), {}), Indexed(IndexSum(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(39), Index(39), Index(40), Index(41)), {Index(40): 3, Index(41): 3, Index(39): 3})), MultiIndex((Index(40), Index(41)), {Index(40): 3, Index(41): 3})), MultiIndex((Index(39),), {Index(39): 3})), MultiIndex((Index(42), Index(43)), {Index(43): 3, Index(42): 3}))), MultiIndex((Index(42), Index(43)), {Index(43): 3, Index(42): 3})), MultiIndex((Index(44), Index(45)), {Index(44): 3, Index(45): 3}))), MultiIndex((Index(44), Index(45)), {Index(44): 3, Index(45): 3})), MultiIndex((Index(46), Index(47)), {Index(46): 3, Index(47): 3}))), MultiIndex((Index(46), Index(47)), {Index(46): 3, Index(47): 3}))), MultiIndex((Index(3), Index(48)), {Index(48): 3, Index(3): 3}))), Product(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), MultiIndex((Index(1), Index(0)), {Index(0): 3, Index(1): 3})), Identity(3)), MultiIndex((Index(2), Index(3)), {Index(2): 3, Index(3): 3})), Indexed(Sum(ComponentTensor(Product(Constant(Cell('tetrahedron', 1, Space(3)), 1), Indexed(IndexSum(ComponentTensor(Indexed(ComponentTensor(Indexed(IndexSum(Sum(ComponentTensor(Product(Indexed(ComponentTensor(Division(Indexed(ComponentTensor(IndexSum(Sum(Product(Indexed(ComponentTensor(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3})), Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), MultiIndex((Index(9), Index(27)), {Index(9): 3, Index(27): 3})), Indexed(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(8), Index(9), Index(10), Index(11)), {Index(11): 3, Index(8): 3, Index(9): 3, Index(10): 3})), MultiIndex((Index(10), Index(11)), {Index(11): 3, Index(10): 3})), MultiIndex((Index(12), Index(13)), {Index(13): 3, Index(12): 3}))), MultiIndex((Index(12), Index(13)), {Index(13): 3, Index(12): 3})), ComponentTensor(Product(Indexed(ComponentTensor(Division(Indexed(ComponentTensor(IndexSum(Sum(Product(Indexed(ComponentTensor(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3})), Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), MultiIndex((Index(8), Index(9)), {Index(8): 3, Index(9): 3})), Indexed(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(9), Index(27), Index(28), Index(29)), {Index(29): 3, Index(9): 3, Index(28): 3, Index(27): 3})), MultiIndex((Index(28), Index(29)), {Index(29): 3, Index(28): 3})), MultiIndex((Index(30), Index(31)), {Index(31): 3, Index(30): 3}))), MultiIndex((Index(30), Index(31)), {Index(31): 3, Index(30): 3}))), MultiIndex((Index(9),), {Index(9): 3})), MultiIndex((Index(32), Index(33)), {Index(33): 3, Index(32): 3})), MultiIndex((Index(8), Index(27), Index(32), Index(33)), {Index(33): 3, Index(27): 3, Index(32): 3, Index(8): 3})), MultiIndex((Index(34), Index(34), Index(35), Index(36)), {Index(35): 3, Index(36): 3, Index(34): 3})), MultiIndex((Index(35), Index(36)), {Index(35): 3, Index(36): 3})), MultiIndex((Index(34),), {Index(34): 3})), MultiIndex((Index(37), Index(38)), {Index(37): 3, Index(38): 3}))), MultiIndex((Index(37), Index(38)), {Index(37): 3, Index(38): 3})), ComponentTensor(Product(Division(Constant(Cell('tetrahedron', 1, Space(3)), 2), IntValue(2, (), (), {})), Indexed(ComponentTensor(Product(IndexSum(Indexed(ComponentTensor(Division(Indexed(ComponentTensor(IndexSum(Sum(Product(Indexed(ComponentTensor(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3})), Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), MultiIndex((Index(39), Index(39)), {Index(39): 3})), MultiIndex((Index(39),), {Index(39): 3})), Indexed(ComponentTensor(Product(IntValue(2, (), (), {}), Indexed(IndexSum(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(39), Index(39), Index(40), Index(41)), {Index(40): 3, Index(41): 3, Index(39): 3})), MultiIndex((Index(40), Index(41)), {Index(40): 3, Index(41): 3})), MultiIndex((Index(39),), {Index(39): 3})), MultiIndex((Index(42), Index(43)), {Index(43): 3, Index(42): 3}))), MultiIndex((Index(42), Index(43)), {Index(43): 3, Index(42): 3})), MultiIndex((Index(44), Index(45)), {Index(44): 3, Index(45): 3}))), MultiIndex((Index(44), Index(45)), {Index(44): 3, Index(45): 3})), MultiIndex((Index(46), Index(47)), {Index(46): 3, Index(47): 3}))), MultiIndex((Index(46), Index(47)), {Index(46): 3, Index(47): 3}))), MultiIndex((Index(3), Index(48)), {Index(48): 3, Index(3): 3})))), MultiIndex((Index(3),), {Index(3): 3})), MultiIndex((Index(2), Index(48)), {Index(48): 3, Index(2): 3})), MultiIndex((Index(49), Index(50)), {Index(50): 3, Index(49): 3})), Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(51),), {Index(51): 3})), MultiIndex((Index(52),), {Index(52): 3})), MultiIndex((Index(52), Index(51)), {Index(52): 3, Index(51): 3})), MultiIndex((Index(49), Index(50)), {Index(50): 3, Index(49): 3}))), MultiIndex((Index(49),), {Index(49): 3})), MultiIndex((Index(50),), {Index(50): 3})), Measure('cell', 0, None))])";
11550
/// Return the rank of the global tensor (r)
11551
virtual unsigned int rank() const
11556
/// Return the number of coefficients (n)
11557
virtual unsigned int num_coefficients() const
11562
/// Return the number of cell integrals
11563
virtual unsigned int num_cell_integrals() const
11568
/// Return the number of exterior facet integrals
11569
virtual unsigned int num_exterior_facet_integrals() const
11574
/// Return the number of interior facet integrals
11575
virtual unsigned int num_interior_facet_integrals() const
11580
/// Create a new finite element for argument function i
11581
virtual ufc::finite_element* create_finite_element(unsigned int i) const
11586
return new hyperelasticity_0_finite_element_0();
11589
return new hyperelasticity_0_finite_element_1();
11592
return new hyperelasticity_0_finite_element_2();
11595
return new hyperelasticity_0_finite_element_3();
11598
return new hyperelasticity_0_finite_element_4();
11604
/// Create a new dof map for argument function i
11605
virtual ufc::dof_map* create_dof_map(unsigned int i) const
11610
return new hyperelasticity_0_dof_map_0();
11613
return new hyperelasticity_0_dof_map_1();
11616
return new hyperelasticity_0_dof_map_2();
11619
return new hyperelasticity_0_dof_map_3();
11622
return new hyperelasticity_0_dof_map_4();
11628
/// Create a new cell integral on sub domain i
11629
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
11631
return new hyperelasticity_0_cell_integral_0();
11634
/// Create a new exterior facet integral on sub domain i
11635
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
11640
/// Create a new interior facet integral on sub domain i
11641
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
11648
/// This class defines the interface for a finite element.
11650
class hyperelasticity_1_finite_element_0_0: public ufc::finite_element
11655
hyperelasticity_1_finite_element_0_0() : ufc::finite_element()
11661
virtual ~hyperelasticity_1_finite_element_0_0()
11666
/// Return a string identifying the finite element
11667
virtual const char* signature() const
11669
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
11672
/// Return the cell shape
11673
virtual ufc::shape cell_shape() const
11675
return ufc::tetrahedron;
11678
/// Return the dimension of the finite element function space
11679
virtual unsigned int space_dimension() const
11684
/// Return the rank of the value space
11685
virtual unsigned int value_rank() const
11690
/// Return the dimension of the value space for axis i
11691
virtual unsigned int value_dimension(unsigned int i) const
11696
/// Evaluate basis function i at given point in cell
11697
virtual void evaluate_basis(unsigned int i,
11699
const double* coordinates,
11700
const ufc::cell& c) const
11702
// Extract vertex coordinates
11703
const double * const * element_coordinates = c.coordinates;
11705
// Compute Jacobian of affine map from reference cell
11706
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11707
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11708
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
11709
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11710
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11711
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
11712
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
11713
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
11714
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
11716
// Compute sub determinants
11717
const double d00 = J_11*J_22 - J_12*J_21;
11718
const double d01 = J_12*J_20 - J_10*J_22;
11719
const double d02 = J_10*J_21 - J_11*J_20;
11721
const double d10 = J_02*J_21 - J_01*J_22;
11722
const double d11 = J_00*J_22 - J_02*J_20;
11723
const double d12 = J_01*J_20 - J_00*J_21;
11725
const double d20 = J_01*J_12 - J_02*J_11;
11726
const double d21 = J_02*J_10 - J_00*J_12;
11727
const double d22 = J_00*J_11 - J_01*J_10;
11729
// Compute determinant of Jacobian
11730
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
11732
// Compute inverse of Jacobian
11734
// Compute constants
11735
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
11736
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
11737
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
11739
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
11740
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
11741
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
11743
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
11744
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
11745
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
11747
// Get coordinates and map to the UFC reference element
11748
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
11749
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
11750
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
11752
// Map coordinates to the reference cube
11753
if (std::abs(y + z - 1.0) < 1e-08)
11756
x = -2.0 * x/(y + z - 1.0) - 1.0;
11757
if (std::abs(z - 1.0) < 1e-08)
11760
y = 2.0 * y/(1.0 - z) - 1.0;
11766
// Map degree of freedom to element degree of freedom
11767
const unsigned int dof = i;
11769
// Generate scalings
11770
const double scalings_y_0 = 1;
11771
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11772
const double scalings_z_0 = 1;
11773
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
11775
// Compute psitilde_a
11776
const double psitilde_a_0 = 1;
11777
const double psitilde_a_1 = x;
11779
// Compute psitilde_bs
11780
const double psitilde_bs_0_0 = 1;
11781
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11782
const double psitilde_bs_1_0 = 1;
11784
// Compute psitilde_cs
11785
const double psitilde_cs_00_0 = 1;
11786
const double psitilde_cs_00_1 = 2*z + 1;
11787
const double psitilde_cs_01_0 = 1;
11788
const double psitilde_cs_10_0 = 1;
11790
// Compute basisvalues
11791
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
11792
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
11793
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
11794
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
11796
// Table(s) of coefficients
11797
static const double coefficients0[4][4] = \
11798
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
11799
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
11800
{0.288675135, 0, 0.210818511, -0.0745355992},
11801
{0.288675135, 0, 0, 0.223606798}};
11803
// Extract relevant coefficients
11804
const double coeff0_0 = coefficients0[dof][0];
11805
const double coeff0_1 = coefficients0[dof][1];
11806
const double coeff0_2 = coefficients0[dof][2];
11807
const double coeff0_3 = coefficients0[dof][3];
11809
// Compute value(s)
11810
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
11813
/// Evaluate all basis functions at given point in cell
11814
virtual void evaluate_basis_all(double* values,
11815
const double* coordinates,
11816
const ufc::cell& c) const
11818
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11821
/// Evaluate order n derivatives of basis function i at given point in cell
11822
virtual void evaluate_basis_derivatives(unsigned int i,
11825
const double* coordinates,
11826
const ufc::cell& c) const
11828
// Extract vertex coordinates
11829
const double * const * element_coordinates = c.coordinates;
11831
// Compute Jacobian of affine map from reference cell
11832
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11833
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11834
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
11835
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11836
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11837
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
11838
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
11839
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
11840
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
11842
// Compute sub determinants
11843
const double d00 = J_11*J_22 - J_12*J_21;
11844
const double d01 = J_12*J_20 - J_10*J_22;
11845
const double d02 = J_10*J_21 - J_11*J_20;
11847
const double d10 = J_02*J_21 - J_01*J_22;
11848
const double d11 = J_00*J_22 - J_02*J_20;
11849
const double d12 = J_01*J_20 - J_00*J_21;
11851
const double d20 = J_01*J_12 - J_02*J_11;
11852
const double d21 = J_02*J_10 - J_00*J_12;
11853
const double d22 = J_00*J_11 - J_01*J_10;
11855
// Compute determinant of Jacobian
11856
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
11858
// Compute inverse of Jacobian
11860
// Compute constants
11861
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
11862
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
11863
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
11865
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
11866
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
11867
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
11869
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
11870
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
11871
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
11873
// Get coordinates and map to the UFC reference element
11874
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
11875
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
11876
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
11878
// Map coordinates to the reference cube
11879
if (std::abs(y + z - 1.0) < 1e-08)
11882
x = -2.0 * x/(y + z - 1.0) - 1.0;
11883
if (std::abs(z - 1.0) < 1e-08)
11886
y = 2.0 * y/(1.0 - z) - 1.0;
11889
// Compute number of derivatives
11890
unsigned int num_derivatives = 1;
11892
for (unsigned int j = 0; j < n; j++)
11893
num_derivatives *= 3;
11896
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11897
unsigned int **combinations = new unsigned int *[num_derivatives];
11899
for (unsigned int j = 0; j < num_derivatives; j++)
11901
combinations[j] = new unsigned int [n];
11902
for (unsigned int k = 0; k < n; k++)
11903
combinations[j][k] = 0;
11906
// Generate combinations of derivatives
11907
for (unsigned int row = 1; row < num_derivatives; row++)
11909
for (unsigned int num = 0; num < row; num++)
11911
for (unsigned int col = n-1; col+1 > 0; col--)
11913
if (combinations[row][col] + 1 > 2)
11914
combinations[row][col] = 0;
11917
combinations[row][col] += 1;
11924
// Compute inverse of Jacobian
11925
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
11927
// Declare transformation matrix
11928
// Declare pointer to two dimensional array and initialise
11929
double **transform = new double *[num_derivatives];
11931
for (unsigned int j = 0; j < num_derivatives; j++)
11933
transform[j] = new double [num_derivatives];
11934
for (unsigned int k = 0; k < num_derivatives; k++)
11935
transform[j][k] = 1;
11938
// Construct transformation matrix
11939
for (unsigned int row = 0; row < num_derivatives; row++)
11941
for (unsigned int col = 0; col < num_derivatives; col++)
11943
for (unsigned int k = 0; k < n; k++)
11944
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11949
for (unsigned int j = 0; j < 1*num_derivatives; j++)
11952
// Map degree of freedom to element degree of freedom
11953
const unsigned int dof = i;
11955
// Generate scalings
11956
const double scalings_y_0 = 1;
11957
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11958
const double scalings_z_0 = 1;
11959
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
11961
// Compute psitilde_a
11962
const double psitilde_a_0 = 1;
11963
const double psitilde_a_1 = x;
11965
// Compute psitilde_bs
11966
const double psitilde_bs_0_0 = 1;
11967
const double psitilde_bs_0_1 = 1.5*y + 0.5;
11968
const double psitilde_bs_1_0 = 1;
11970
// Compute psitilde_cs
11971
const double psitilde_cs_00_0 = 1;
11972
const double psitilde_cs_00_1 = 2*z + 1;
11973
const double psitilde_cs_01_0 = 1;
11974
const double psitilde_cs_10_0 = 1;
11976
// Compute basisvalues
11977
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
11978
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
11979
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
11980
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
11982
// Table(s) of coefficients
11983
static const double coefficients0[4][4] = \
11984
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
11985
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
11986
{0.288675135, 0, 0.210818511, -0.0745355992},
11987
{0.288675135, 0, 0, 0.223606798}};
11989
// Interesting (new) part
11990
// Tables of derivatives of the polynomial base (transpose)
11991
static const double dmats0[4][4] = \
11993
{6.32455532, 0, 0, 0},
11997
static const double dmats1[4][4] = \
11999
{3.16227766, 0, 0, 0},
12000
{5.47722558, 0, 0, 0},
12003
static const double dmats2[4][4] = \
12005
{3.16227766, 0, 0, 0},
12006
{1.82574186, 0, 0, 0},
12007
{5.16397779, 0, 0, 0}};
12009
// Compute reference derivatives
12010
// Declare pointer to array of derivatives on FIAT element
12011
double *derivatives = new double [num_derivatives];
12013
// Declare coefficients
12014
double coeff0_0 = 0;
12015
double coeff0_1 = 0;
12016
double coeff0_2 = 0;
12017
double coeff0_3 = 0;
12019
// Declare new coefficients
12020
double new_coeff0_0 = 0;
12021
double new_coeff0_1 = 0;
12022
double new_coeff0_2 = 0;
12023
double new_coeff0_3 = 0;
12025
// Loop possible derivatives
12026
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12028
// Get values from coefficients array
12029
new_coeff0_0 = coefficients0[dof][0];
12030
new_coeff0_1 = coefficients0[dof][1];
12031
new_coeff0_2 = coefficients0[dof][2];
12032
new_coeff0_3 = coefficients0[dof][3];
12034
// Loop derivative order
12035
for (unsigned int j = 0; j < n; j++)
12037
// Update old coefficients
12038
coeff0_0 = new_coeff0_0;
12039
coeff0_1 = new_coeff0_1;
12040
coeff0_2 = new_coeff0_2;
12041
coeff0_3 = new_coeff0_3;
12043
if(combinations[deriv_num][j] == 0)
12045
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
12046
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
12047
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
12048
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
12050
if(combinations[deriv_num][j] == 1)
12052
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
12053
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
12054
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
12055
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
12057
if(combinations[deriv_num][j] == 2)
12059
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
12060
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
12061
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
12062
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
12066
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12067
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
12070
// Transform derivatives back to physical element
12071
for (unsigned int row = 0; row < num_derivatives; row++)
12073
for (unsigned int col = 0; col < num_derivatives; col++)
12075
values[row] += transform[row][col]*derivatives[col];
12078
// Delete pointer to array of derivatives on FIAT element
12079
delete [] derivatives;
12081
// Delete pointer to array of combinations of derivatives and transform
12082
for (unsigned int row = 0; row < num_derivatives; row++)
12084
delete [] combinations[row];
12085
delete [] transform[row];
12088
delete [] combinations;
12089
delete [] transform;
12092
/// Evaluate order n derivatives of all basis functions at given point in cell
12093
virtual void evaluate_basis_derivatives_all(unsigned int n,
12095
const double* coordinates,
12096
const ufc::cell& c) const
12098
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12101
/// Evaluate linear functional for dof i on the function f
12102
virtual double evaluate_dof(unsigned int i,
12103
const ufc::function& f,
12104
const ufc::cell& c) const
12106
// The reference points, direction and weights:
12107
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
12108
static const double W[4][1] = {{1}, {1}, {1}, {1}};
12109
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
12111
const double * const * x = c.coordinates;
12112
double result = 0.0;
12113
// Iterate over the points:
12114
// Evaluate basis functions for affine mapping
12115
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
12116
const double w1 = X[i][0][0];
12117
const double w2 = X[i][0][1];
12118
const double w3 = X[i][0][2];
12120
// Compute affine mapping y = F(X)
12122
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
12123
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
12124
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
12126
// Evaluate function at physical points
12128
f.evaluate(values, y, c);
12130
// Map function values using appropriate mapping
12131
// Affine map: Do nothing
12133
// Note that we do not map the weights (yet).
12135
// Take directional components
12136
for(int k = 0; k < 1; k++)
12137
result += values[k]*D[i][0][k];
12138
// Multiply by weights
12144
/// Evaluate linear functionals for all dofs on the function f
12145
virtual void evaluate_dofs(double* values,
12146
const ufc::function& f,
12147
const ufc::cell& c) const
12149
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12152
/// Interpolate vertex values from dof values
12153
virtual void interpolate_vertex_values(double* vertex_values,
12154
const double* dof_values,
12155
const ufc::cell& c) const
12157
// Evaluate at vertices and use affine mapping
12158
vertex_values[0] = dof_values[0];
12159
vertex_values[1] = dof_values[1];
12160
vertex_values[2] = dof_values[2];
12161
vertex_values[3] = dof_values[3];
12164
/// Return the number of sub elements (for a mixed element)
12165
virtual unsigned int num_sub_elements() const
12170
/// Create a new finite element for sub element i (for a mixed element)
12171
virtual ufc::finite_element* create_sub_element(unsigned int i) const
12173
return new hyperelasticity_1_finite_element_0_0();
12178
/// This class defines the interface for a finite element.
12180
class hyperelasticity_1_finite_element_0_1: public ufc::finite_element
12185
hyperelasticity_1_finite_element_0_1() : ufc::finite_element()
12191
virtual ~hyperelasticity_1_finite_element_0_1()
12196
/// Return a string identifying the finite element
12197
virtual const char* signature() const
12199
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
12202
/// Return the cell shape
12203
virtual ufc::shape cell_shape() const
12205
return ufc::tetrahedron;
12208
/// Return the dimension of the finite element function space
12209
virtual unsigned int space_dimension() const
12214
/// Return the rank of the value space
12215
virtual unsigned int value_rank() const
12220
/// Return the dimension of the value space for axis i
12221
virtual unsigned int value_dimension(unsigned int i) const
12226
/// Evaluate basis function i at given point in cell
12227
virtual void evaluate_basis(unsigned int i,
12229
const double* coordinates,
12230
const ufc::cell& c) const
12232
// Extract vertex coordinates
12233
const double * const * element_coordinates = c.coordinates;
12235
// Compute Jacobian of affine map from reference cell
12236
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12237
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12238
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
12239
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12240
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12241
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
12242
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
12243
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
12244
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
12246
// Compute sub determinants
12247
const double d00 = J_11*J_22 - J_12*J_21;
12248
const double d01 = J_12*J_20 - J_10*J_22;
12249
const double d02 = J_10*J_21 - J_11*J_20;
12251
const double d10 = J_02*J_21 - J_01*J_22;
12252
const double d11 = J_00*J_22 - J_02*J_20;
12253
const double d12 = J_01*J_20 - J_00*J_21;
12255
const double d20 = J_01*J_12 - J_02*J_11;
12256
const double d21 = J_02*J_10 - J_00*J_12;
12257
const double d22 = J_00*J_11 - J_01*J_10;
12259
// Compute determinant of Jacobian
12260
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
12262
// Compute inverse of Jacobian
12264
// Compute constants
12265
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
12266
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
12267
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
12269
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
12270
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
12271
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
12273
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
12274
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
12275
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
12277
// Get coordinates and map to the UFC reference element
12278
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
12279
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
12280
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
12282
// Map coordinates to the reference cube
12283
if (std::abs(y + z - 1.0) < 1e-08)
12286
x = -2.0 * x/(y + z - 1.0) - 1.0;
12287
if (std::abs(z - 1.0) < 1e-08)
12290
y = 2.0 * y/(1.0 - z) - 1.0;
12296
// Map degree of freedom to element degree of freedom
12297
const unsigned int dof = i;
12299
// Generate scalings
12300
const double scalings_y_0 = 1;
12301
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12302
const double scalings_z_0 = 1;
12303
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
12305
// Compute psitilde_a
12306
const double psitilde_a_0 = 1;
12307
const double psitilde_a_1 = x;
12309
// Compute psitilde_bs
12310
const double psitilde_bs_0_0 = 1;
12311
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12312
const double psitilde_bs_1_0 = 1;
12314
// Compute psitilde_cs
12315
const double psitilde_cs_00_0 = 1;
12316
const double psitilde_cs_00_1 = 2*z + 1;
12317
const double psitilde_cs_01_0 = 1;
12318
const double psitilde_cs_10_0 = 1;
12320
// Compute basisvalues
12321
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
12322
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
12323
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
12324
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
12326
// Table(s) of coefficients
12327
static const double coefficients0[4][4] = \
12328
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
12329
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
12330
{0.288675135, 0, 0.210818511, -0.0745355992},
12331
{0.288675135, 0, 0, 0.223606798}};
12333
// Extract relevant coefficients
12334
const double coeff0_0 = coefficients0[dof][0];
12335
const double coeff0_1 = coefficients0[dof][1];
12336
const double coeff0_2 = coefficients0[dof][2];
12337
const double coeff0_3 = coefficients0[dof][3];
12339
// Compute value(s)
12340
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
12343
/// Evaluate all basis functions at given point in cell
12344
virtual void evaluate_basis_all(double* values,
12345
const double* coordinates,
12346
const ufc::cell& c) const
12348
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12351
/// Evaluate order n derivatives of basis function i at given point in cell
12352
virtual void evaluate_basis_derivatives(unsigned int i,
12355
const double* coordinates,
12356
const ufc::cell& c) const
12358
// Extract vertex coordinates
12359
const double * const * element_coordinates = c.coordinates;
12361
// Compute Jacobian of affine map from reference cell
12362
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12363
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12364
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
12365
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12366
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12367
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
12368
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
12369
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
12370
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
12372
// Compute sub determinants
12373
const double d00 = J_11*J_22 - J_12*J_21;
12374
const double d01 = J_12*J_20 - J_10*J_22;
12375
const double d02 = J_10*J_21 - J_11*J_20;
12377
const double d10 = J_02*J_21 - J_01*J_22;
12378
const double d11 = J_00*J_22 - J_02*J_20;
12379
const double d12 = J_01*J_20 - J_00*J_21;
12381
const double d20 = J_01*J_12 - J_02*J_11;
12382
const double d21 = J_02*J_10 - J_00*J_12;
12383
const double d22 = J_00*J_11 - J_01*J_10;
12385
// Compute determinant of Jacobian
12386
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
12388
// Compute inverse of Jacobian
12390
// Compute constants
12391
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
12392
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
12393
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
12395
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
12396
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
12397
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
12399
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
12400
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
12401
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
12403
// Get coordinates and map to the UFC reference element
12404
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
12405
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
12406
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
12408
// Map coordinates to the reference cube
12409
if (std::abs(y + z - 1.0) < 1e-08)
12412
x = -2.0 * x/(y + z - 1.0) - 1.0;
12413
if (std::abs(z - 1.0) < 1e-08)
12416
y = 2.0 * y/(1.0 - z) - 1.0;
12419
// Compute number of derivatives
12420
unsigned int num_derivatives = 1;
12422
for (unsigned int j = 0; j < n; j++)
12423
num_derivatives *= 3;
12426
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12427
unsigned int **combinations = new unsigned int *[num_derivatives];
12429
for (unsigned int j = 0; j < num_derivatives; j++)
12431
combinations[j] = new unsigned int [n];
12432
for (unsigned int k = 0; k < n; k++)
12433
combinations[j][k] = 0;
12436
// Generate combinations of derivatives
12437
for (unsigned int row = 1; row < num_derivatives; row++)
12439
for (unsigned int num = 0; num < row; num++)
12441
for (unsigned int col = n-1; col+1 > 0; col--)
12443
if (combinations[row][col] + 1 > 2)
12444
combinations[row][col] = 0;
12447
combinations[row][col] += 1;
12454
// Compute inverse of Jacobian
12455
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
12457
// Declare transformation matrix
12458
// Declare pointer to two dimensional array and initialise
12459
double **transform = new double *[num_derivatives];
12461
for (unsigned int j = 0; j < num_derivatives; j++)
12463
transform[j] = new double [num_derivatives];
12464
for (unsigned int k = 0; k < num_derivatives; k++)
12465
transform[j][k] = 1;
12468
// Construct transformation matrix
12469
for (unsigned int row = 0; row < num_derivatives; row++)
12471
for (unsigned int col = 0; col < num_derivatives; col++)
12473
for (unsigned int k = 0; k < n; k++)
12474
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12479
for (unsigned int j = 0; j < 1*num_derivatives; j++)
12482
// Map degree of freedom to element degree of freedom
12483
const unsigned int dof = i;
12485
// Generate scalings
12486
const double scalings_y_0 = 1;
12487
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12488
const double scalings_z_0 = 1;
12489
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
12491
// Compute psitilde_a
12492
const double psitilde_a_0 = 1;
12493
const double psitilde_a_1 = x;
12495
// Compute psitilde_bs
12496
const double psitilde_bs_0_0 = 1;
12497
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12498
const double psitilde_bs_1_0 = 1;
12500
// Compute psitilde_cs
12501
const double psitilde_cs_00_0 = 1;
12502
const double psitilde_cs_00_1 = 2*z + 1;
12503
const double psitilde_cs_01_0 = 1;
12504
const double psitilde_cs_10_0 = 1;
12506
// Compute basisvalues
12507
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
12508
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
12509
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
12510
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
12512
// Table(s) of coefficients
12513
static const double coefficients0[4][4] = \
12514
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
12515
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
12516
{0.288675135, 0, 0.210818511, -0.0745355992},
12517
{0.288675135, 0, 0, 0.223606798}};
12519
// Interesting (new) part
12520
// Tables of derivatives of the polynomial base (transpose)
12521
static const double dmats0[4][4] = \
12523
{6.32455532, 0, 0, 0},
12527
static const double dmats1[4][4] = \
12529
{3.16227766, 0, 0, 0},
12530
{5.47722558, 0, 0, 0},
12533
static const double dmats2[4][4] = \
12535
{3.16227766, 0, 0, 0},
12536
{1.82574186, 0, 0, 0},
12537
{5.16397779, 0, 0, 0}};
12539
// Compute reference derivatives
12540
// Declare pointer to array of derivatives on FIAT element
12541
double *derivatives = new double [num_derivatives];
12543
// Declare coefficients
12544
double coeff0_0 = 0;
12545
double coeff0_1 = 0;
12546
double coeff0_2 = 0;
12547
double coeff0_3 = 0;
12549
// Declare new coefficients
12550
double new_coeff0_0 = 0;
12551
double new_coeff0_1 = 0;
12552
double new_coeff0_2 = 0;
12553
double new_coeff0_3 = 0;
12555
// Loop possible derivatives
12556
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12558
// Get values from coefficients array
12559
new_coeff0_0 = coefficients0[dof][0];
12560
new_coeff0_1 = coefficients0[dof][1];
12561
new_coeff0_2 = coefficients0[dof][2];
12562
new_coeff0_3 = coefficients0[dof][3];
12564
// Loop derivative order
12565
for (unsigned int j = 0; j < n; j++)
12567
// Update old coefficients
12568
coeff0_0 = new_coeff0_0;
12569
coeff0_1 = new_coeff0_1;
12570
coeff0_2 = new_coeff0_2;
12571
coeff0_3 = new_coeff0_3;
12573
if(combinations[deriv_num][j] == 0)
12575
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
12576
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
12577
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
12578
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
12580
if(combinations[deriv_num][j] == 1)
12582
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
12583
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
12584
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
12585
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
12587
if(combinations[deriv_num][j] == 2)
12589
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
12590
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
12591
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
12592
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
12596
// Compute derivatives on reference element as dot product of coefficients and basisvalues
12597
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
12600
// Transform derivatives back to physical element
12601
for (unsigned int row = 0; row < num_derivatives; row++)
12603
for (unsigned int col = 0; col < num_derivatives; col++)
12605
values[row] += transform[row][col]*derivatives[col];
12608
// Delete pointer to array of derivatives on FIAT element
12609
delete [] derivatives;
12611
// Delete pointer to array of combinations of derivatives and transform
12612
for (unsigned int row = 0; row < num_derivatives; row++)
12614
delete [] combinations[row];
12615
delete [] transform[row];
12618
delete [] combinations;
12619
delete [] transform;
12622
/// Evaluate order n derivatives of all basis functions at given point in cell
12623
virtual void evaluate_basis_derivatives_all(unsigned int n,
12625
const double* coordinates,
12626
const ufc::cell& c) const
12628
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12631
/// Evaluate linear functional for dof i on the function f
12632
virtual double evaluate_dof(unsigned int i,
12633
const ufc::function& f,
12634
const ufc::cell& c) const
12636
// The reference points, direction and weights:
12637
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
12638
static const double W[4][1] = {{1}, {1}, {1}, {1}};
12639
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
12641
const double * const * x = c.coordinates;
12642
double result = 0.0;
12643
// Iterate over the points:
12644
// Evaluate basis functions for affine mapping
12645
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
12646
const double w1 = X[i][0][0];
12647
const double w2 = X[i][0][1];
12648
const double w3 = X[i][0][2];
12650
// Compute affine mapping y = F(X)
12652
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
12653
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
12654
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
12656
// Evaluate function at physical points
12658
f.evaluate(values, y, c);
12660
// Map function values using appropriate mapping
12661
// Affine map: Do nothing
12663
// Note that we do not map the weights (yet).
12665
// Take directional components
12666
for(int k = 0; k < 1; k++)
12667
result += values[k]*D[i][0][k];
12668
// Multiply by weights
12674
/// Evaluate linear functionals for all dofs on the function f
12675
virtual void evaluate_dofs(double* values,
12676
const ufc::function& f,
12677
const ufc::cell& c) const
12679
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12682
/// Interpolate vertex values from dof values
12683
virtual void interpolate_vertex_values(double* vertex_values,
12684
const double* dof_values,
12685
const ufc::cell& c) const
12687
// Evaluate at vertices and use affine mapping
12688
vertex_values[0] = dof_values[0];
12689
vertex_values[1] = dof_values[1];
12690
vertex_values[2] = dof_values[2];
12691
vertex_values[3] = dof_values[3];
12694
/// Return the number of sub elements (for a mixed element)
12695
virtual unsigned int num_sub_elements() const
12700
/// Create a new finite element for sub element i (for a mixed element)
12701
virtual ufc::finite_element* create_sub_element(unsigned int i) const
12703
return new hyperelasticity_1_finite_element_0_1();
12708
/// This class defines the interface for a finite element.
12710
class hyperelasticity_1_finite_element_0_2: public ufc::finite_element
12715
hyperelasticity_1_finite_element_0_2() : ufc::finite_element()
12721
virtual ~hyperelasticity_1_finite_element_0_2()
12726
/// Return a string identifying the finite element
12727
virtual const char* signature() const
12729
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
12732
/// Return the cell shape
12733
virtual ufc::shape cell_shape() const
12735
return ufc::tetrahedron;
12738
/// Return the dimension of the finite element function space
12739
virtual unsigned int space_dimension() const
12744
/// Return the rank of the value space
12745
virtual unsigned int value_rank() const
12750
/// Return the dimension of the value space for axis i
12751
virtual unsigned int value_dimension(unsigned int i) const
12756
/// Evaluate basis function i at given point in cell
12757
virtual void evaluate_basis(unsigned int i,
12759
const double* coordinates,
12760
const ufc::cell& c) const
12762
// Extract vertex coordinates
12763
const double * const * element_coordinates = c.coordinates;
12765
// Compute Jacobian of affine map from reference cell
12766
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12767
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12768
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
12769
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12770
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12771
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
12772
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
12773
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
12774
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
12776
// Compute sub determinants
12777
const double d00 = J_11*J_22 - J_12*J_21;
12778
const double d01 = J_12*J_20 - J_10*J_22;
12779
const double d02 = J_10*J_21 - J_11*J_20;
12781
const double d10 = J_02*J_21 - J_01*J_22;
12782
const double d11 = J_00*J_22 - J_02*J_20;
12783
const double d12 = J_01*J_20 - J_00*J_21;
12785
const double d20 = J_01*J_12 - J_02*J_11;
12786
const double d21 = J_02*J_10 - J_00*J_12;
12787
const double d22 = J_00*J_11 - J_01*J_10;
12789
// Compute determinant of Jacobian
12790
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
12792
// Compute inverse of Jacobian
12794
// Compute constants
12795
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
12796
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
12797
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
12799
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
12800
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
12801
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
12803
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
12804
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
12805
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
12807
// Get coordinates and map to the UFC reference element
12808
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
12809
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
12810
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
12812
// Map coordinates to the reference cube
12813
if (std::abs(y + z - 1.0) < 1e-08)
12816
x = -2.0 * x/(y + z - 1.0) - 1.0;
12817
if (std::abs(z - 1.0) < 1e-08)
12820
y = 2.0 * y/(1.0 - z) - 1.0;
12826
// Map degree of freedom to element degree of freedom
12827
const unsigned int dof = i;
12829
// Generate scalings
12830
const double scalings_y_0 = 1;
12831
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12832
const double scalings_z_0 = 1;
12833
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
12835
// Compute psitilde_a
12836
const double psitilde_a_0 = 1;
12837
const double psitilde_a_1 = x;
12839
// Compute psitilde_bs
12840
const double psitilde_bs_0_0 = 1;
12841
const double psitilde_bs_0_1 = 1.5*y + 0.5;
12842
const double psitilde_bs_1_0 = 1;
12844
// Compute psitilde_cs
12845
const double psitilde_cs_00_0 = 1;
12846
const double psitilde_cs_00_1 = 2*z + 1;
12847
const double psitilde_cs_01_0 = 1;
12848
const double psitilde_cs_10_0 = 1;
12850
// Compute basisvalues
12851
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
12852
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
12853
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
12854
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
12856
// Table(s) of coefficients
12857
static const double coefficients0[4][4] = \
12858
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
12859
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
12860
{0.288675135, 0, 0.210818511, -0.0745355992},
12861
{0.288675135, 0, 0, 0.223606798}};
12863
// Extract relevant coefficients
12864
const double coeff0_0 = coefficients0[dof][0];
12865
const double coeff0_1 = coefficients0[dof][1];
12866
const double coeff0_2 = coefficients0[dof][2];
12867
const double coeff0_3 = coefficients0[dof][3];
12869
// Compute value(s)
12870
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
12873
/// Evaluate all basis functions at given point in cell
12874
virtual void evaluate_basis_all(double* values,
12875
const double* coordinates,
12876
const ufc::cell& c) const
12878
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12881
/// Evaluate order n derivatives of basis function i at given point in cell
12882
virtual void evaluate_basis_derivatives(unsigned int i,
12885
const double* coordinates,
12886
const ufc::cell& c) const
12888
// Extract vertex coordinates
12889
const double * const * element_coordinates = c.coordinates;
12891
// Compute Jacobian of affine map from reference cell
12892
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12893
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12894
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
12895
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12896
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12897
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
12898
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
12899
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
12900
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
12902
// Compute sub determinants
12903
const double d00 = J_11*J_22 - J_12*J_21;
12904
const double d01 = J_12*J_20 - J_10*J_22;
12905
const double d02 = J_10*J_21 - J_11*J_20;
12907
const double d10 = J_02*J_21 - J_01*J_22;
12908
const double d11 = J_00*J_22 - J_02*J_20;
12909
const double d12 = J_01*J_20 - J_00*J_21;
12911
const double d20 = J_01*J_12 - J_02*J_11;
12912
const double d21 = J_02*J_10 - J_00*J_12;
12913
const double d22 = J_00*J_11 - J_01*J_10;
12915
// Compute determinant of Jacobian
12916
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
12918
// Compute inverse of Jacobian
12920
// Compute constants
12921
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
12922
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
12923
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
12925
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
12926
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
12927
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
12929
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
12930
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
12931
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
12933
// Get coordinates and map to the UFC reference element
12934
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
12935
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
12936
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
12938
// Map coordinates to the reference cube
12939
if (std::abs(y + z - 1.0) < 1e-08)
12942
x = -2.0 * x/(y + z - 1.0) - 1.0;
12943
if (std::abs(z - 1.0) < 1e-08)
12946
y = 2.0 * y/(1.0 - z) - 1.0;
12949
// Compute number of derivatives
12950
unsigned int num_derivatives = 1;
12952
for (unsigned int j = 0; j < n; j++)
12953
num_derivatives *= 3;
12956
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12957
unsigned int **combinations = new unsigned int *[num_derivatives];
12959
for (unsigned int j = 0; j < num_derivatives; j++)
12961
combinations[j] = new unsigned int [n];
12962
for (unsigned int k = 0; k < n; k++)
12963
combinations[j][k] = 0;
12966
// Generate combinations of derivatives
12967
for (unsigned int row = 1; row < num_derivatives; row++)
12969
for (unsigned int num = 0; num < row; num++)
12971
for (unsigned int col = n-1; col+1 > 0; col--)
12973
if (combinations[row][col] + 1 > 2)
12974
combinations[row][col] = 0;
12977
combinations[row][col] += 1;
12984
// Compute inverse of Jacobian
12985
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
12987
// Declare transformation matrix
12988
// Declare pointer to two dimensional array and initialise
12989
double **transform = new double *[num_derivatives];
12991
for (unsigned int j = 0; j < num_derivatives; j++)
12993
transform[j] = new double [num_derivatives];
12994
for (unsigned int k = 0; k < num_derivatives; k++)
12995
transform[j][k] = 1;
12998
// Construct transformation matrix
12999
for (unsigned int row = 0; row < num_derivatives; row++)
13001
for (unsigned int col = 0; col < num_derivatives; col++)
13003
for (unsigned int k = 0; k < n; k++)
13004
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13009
for (unsigned int j = 0; j < 1*num_derivatives; j++)
13012
// Map degree of freedom to element degree of freedom
13013
const unsigned int dof = i;
13015
// Generate scalings
13016
const double scalings_y_0 = 1;
13017
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
13018
const double scalings_z_0 = 1;
13019
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
13021
// Compute psitilde_a
13022
const double psitilde_a_0 = 1;
13023
const double psitilde_a_1 = x;
13025
// Compute psitilde_bs
13026
const double psitilde_bs_0_0 = 1;
13027
const double psitilde_bs_0_1 = 1.5*y + 0.5;
13028
const double psitilde_bs_1_0 = 1;
13030
// Compute psitilde_cs
13031
const double psitilde_cs_00_0 = 1;
13032
const double psitilde_cs_00_1 = 2*z + 1;
13033
const double psitilde_cs_01_0 = 1;
13034
const double psitilde_cs_10_0 = 1;
13036
// Compute basisvalues
13037
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
13038
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
13039
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
13040
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
13042
// Table(s) of coefficients
13043
static const double coefficients0[4][4] = \
13044
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
13045
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
13046
{0.288675135, 0, 0.210818511, -0.0745355992},
13047
{0.288675135, 0, 0, 0.223606798}};
13049
// Interesting (new) part
13050
// Tables of derivatives of the polynomial base (transpose)
13051
static const double dmats0[4][4] = \
13053
{6.32455532, 0, 0, 0},
13057
static const double dmats1[4][4] = \
13059
{3.16227766, 0, 0, 0},
13060
{5.47722558, 0, 0, 0},
13063
static const double dmats2[4][4] = \
13065
{3.16227766, 0, 0, 0},
13066
{1.82574186, 0, 0, 0},
13067
{5.16397779, 0, 0, 0}};
13069
// Compute reference derivatives
13070
// Declare pointer to array of derivatives on FIAT element
13071
double *derivatives = new double [num_derivatives];
13073
// Declare coefficients
13074
double coeff0_0 = 0;
13075
double coeff0_1 = 0;
13076
double coeff0_2 = 0;
13077
double coeff0_3 = 0;
13079
// Declare new coefficients
13080
double new_coeff0_0 = 0;
13081
double new_coeff0_1 = 0;
13082
double new_coeff0_2 = 0;
13083
double new_coeff0_3 = 0;
13085
// Loop possible derivatives
13086
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13088
// Get values from coefficients array
13089
new_coeff0_0 = coefficients0[dof][0];
13090
new_coeff0_1 = coefficients0[dof][1];
13091
new_coeff0_2 = coefficients0[dof][2];
13092
new_coeff0_3 = coefficients0[dof][3];
13094
// Loop derivative order
13095
for (unsigned int j = 0; j < n; j++)
13097
// Update old coefficients
13098
coeff0_0 = new_coeff0_0;
13099
coeff0_1 = new_coeff0_1;
13100
coeff0_2 = new_coeff0_2;
13101
coeff0_3 = new_coeff0_3;
13103
if(combinations[deriv_num][j] == 0)
13105
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
13106
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
13107
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
13108
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
13110
if(combinations[deriv_num][j] == 1)
13112
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
13113
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
13114
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
13115
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
13117
if(combinations[deriv_num][j] == 2)
13119
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
13120
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
13121
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
13122
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
13126
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13127
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
13130
// Transform derivatives back to physical element
13131
for (unsigned int row = 0; row < num_derivatives; row++)
13133
for (unsigned int col = 0; col < num_derivatives; col++)
13135
values[row] += transform[row][col]*derivatives[col];
13138
// Delete pointer to array of derivatives on FIAT element
13139
delete [] derivatives;
13141
// Delete pointer to array of combinations of derivatives and transform
13142
for (unsigned int row = 0; row < num_derivatives; row++)
13144
delete [] combinations[row];
13145
delete [] transform[row];
13148
delete [] combinations;
13149
delete [] transform;
13152
/// Evaluate order n derivatives of all basis functions at given point in cell
13153
virtual void evaluate_basis_derivatives_all(unsigned int n,
13155
const double* coordinates,
13156
const ufc::cell& c) const
13158
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13161
/// Evaluate linear functional for dof i on the function f
13162
virtual double evaluate_dof(unsigned int i,
13163
const ufc::function& f,
13164
const ufc::cell& c) const
13166
// The reference points, direction and weights:
13167
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
13168
static const double W[4][1] = {{1}, {1}, {1}, {1}};
13169
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
13171
const double * const * x = c.coordinates;
13172
double result = 0.0;
13173
// Iterate over the points:
13174
// Evaluate basis functions for affine mapping
13175
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
13176
const double w1 = X[i][0][0];
13177
const double w2 = X[i][0][1];
13178
const double w3 = X[i][0][2];
13180
// Compute affine mapping y = F(X)
13182
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
13183
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
13184
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
13186
// Evaluate function at physical points
13188
f.evaluate(values, y, c);
13190
// Map function values using appropriate mapping
13191
// Affine map: Do nothing
13193
// Note that we do not map the weights (yet).
13195
// Take directional components
13196
for(int k = 0; k < 1; k++)
13197
result += values[k]*D[i][0][k];
13198
// Multiply by weights
13204
/// Evaluate linear functionals for all dofs on the function f
13205
virtual void evaluate_dofs(double* values,
13206
const ufc::function& f,
13207
const ufc::cell& c) const
13209
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13212
/// Interpolate vertex values from dof values
13213
virtual void interpolate_vertex_values(double* vertex_values,
13214
const double* dof_values,
13215
const ufc::cell& c) const
13217
// Evaluate at vertices and use affine mapping
13218
vertex_values[0] = dof_values[0];
13219
vertex_values[1] = dof_values[1];
13220
vertex_values[2] = dof_values[2];
13221
vertex_values[3] = dof_values[3];
13224
/// Return the number of sub elements (for a mixed element)
13225
virtual unsigned int num_sub_elements() const
13230
/// Create a new finite element for sub element i (for a mixed element)
13231
virtual ufc::finite_element* create_sub_element(unsigned int i) const
13233
return new hyperelasticity_1_finite_element_0_2();
13238
/// This class defines the interface for a finite element.
13240
class hyperelasticity_1_finite_element_0: public ufc::finite_element
13245
hyperelasticity_1_finite_element_0() : ufc::finite_element()
13251
virtual ~hyperelasticity_1_finite_element_0()
13256
/// Return a string identifying the finite element
13257
virtual const char* signature() const
13259
return "VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
13262
/// Return the cell shape
13263
virtual ufc::shape cell_shape() const
13265
return ufc::tetrahedron;
13268
/// Return the dimension of the finite element function space
13269
virtual unsigned int space_dimension() const
13274
/// Return the rank of the value space
13275
virtual unsigned int value_rank() const
13280
/// Return the dimension of the value space for axis i
13281
virtual unsigned int value_dimension(unsigned int i) const
13286
/// Evaluate basis function i at given point in cell
13287
virtual void evaluate_basis(unsigned int i,
13289
const double* coordinates,
13290
const ufc::cell& c) const
13292
// Extract vertex coordinates
13293
const double * const * element_coordinates = c.coordinates;
13295
// Compute Jacobian of affine map from reference cell
13296
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13297
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13298
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
13299
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13300
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13301
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
13302
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
13303
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
13304
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
13306
// Compute sub determinants
13307
const double d00 = J_11*J_22 - J_12*J_21;
13308
const double d01 = J_12*J_20 - J_10*J_22;
13309
const double d02 = J_10*J_21 - J_11*J_20;
13311
const double d10 = J_02*J_21 - J_01*J_22;
13312
const double d11 = J_00*J_22 - J_02*J_20;
13313
const double d12 = J_01*J_20 - J_00*J_21;
13315
const double d20 = J_01*J_12 - J_02*J_11;
13316
const double d21 = J_02*J_10 - J_00*J_12;
13317
const double d22 = J_00*J_11 - J_01*J_10;
13319
// Compute determinant of Jacobian
13320
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
13322
// Compute inverse of Jacobian
13324
// Compute constants
13325
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
13326
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
13327
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
13329
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
13330
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
13331
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
13333
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
13334
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
13335
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
13337
// Get coordinates and map to the UFC reference element
13338
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
13339
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
13340
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
13342
// Map coordinates to the reference cube
13343
if (std::abs(y + z - 1.0) < 1e-08)
13346
x = -2.0 * x/(y + z - 1.0) - 1.0;
13347
if (std::abs(z - 1.0) < 1e-08)
13350
y = 2.0 * y/(1.0 - z) - 1.0;
13358
if (0 <= i && i <= 3)
13360
// Map degree of freedom to element degree of freedom
13361
const unsigned int dof = i;
13363
// Generate scalings
13364
const double scalings_y_0 = 1;
13365
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
13366
const double scalings_z_0 = 1;
13367
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
13369
// Compute psitilde_a
13370
const double psitilde_a_0 = 1;
13371
const double psitilde_a_1 = x;
13373
// Compute psitilde_bs
13374
const double psitilde_bs_0_0 = 1;
13375
const double psitilde_bs_0_1 = 1.5*y + 0.5;
13376
const double psitilde_bs_1_0 = 1;
13378
// Compute psitilde_cs
13379
const double psitilde_cs_00_0 = 1;
13380
const double psitilde_cs_00_1 = 2*z + 1;
13381
const double psitilde_cs_01_0 = 1;
13382
const double psitilde_cs_10_0 = 1;
13384
// Compute basisvalues
13385
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
13386
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
13387
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
13388
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
13390
// Table(s) of coefficients
13391
static const double coefficients0[4][4] = \
13392
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
13393
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
13394
{0.288675135, 0, 0.210818511, -0.0745355992},
13395
{0.288675135, 0, 0, 0.223606798}};
13397
// Extract relevant coefficients
13398
const double coeff0_0 = coefficients0[dof][0];
13399
const double coeff0_1 = coefficients0[dof][1];
13400
const double coeff0_2 = coefficients0[dof][2];
13401
const double coeff0_3 = coefficients0[dof][3];
13403
// Compute value(s)
13404
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
13407
if (4 <= i && i <= 7)
13409
// Map degree of freedom to element degree of freedom
13410
const unsigned int dof = i - 4;
13412
// Generate scalings
13413
const double scalings_y_0 = 1;
13414
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
13415
const double scalings_z_0 = 1;
13416
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
13418
// Compute psitilde_a
13419
const double psitilde_a_0 = 1;
13420
const double psitilde_a_1 = x;
13422
// Compute psitilde_bs
13423
const double psitilde_bs_0_0 = 1;
13424
const double psitilde_bs_0_1 = 1.5*y + 0.5;
13425
const double psitilde_bs_1_0 = 1;
13427
// Compute psitilde_cs
13428
const double psitilde_cs_00_0 = 1;
13429
const double psitilde_cs_00_1 = 2*z + 1;
13430
const double psitilde_cs_01_0 = 1;
13431
const double psitilde_cs_10_0 = 1;
13433
// Compute basisvalues
13434
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
13435
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
13436
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
13437
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
13439
// Table(s) of coefficients
13440
static const double coefficients0[4][4] = \
13441
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
13442
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
13443
{0.288675135, 0, 0.210818511, -0.0745355992},
13444
{0.288675135, 0, 0, 0.223606798}};
13446
// Extract relevant coefficients
13447
const double coeff0_0 = coefficients0[dof][0];
13448
const double coeff0_1 = coefficients0[dof][1];
13449
const double coeff0_2 = coefficients0[dof][2];
13450
const double coeff0_3 = coefficients0[dof][3];
13452
// Compute value(s)
13453
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
13456
if (8 <= i && i <= 11)
13458
// Map degree of freedom to element degree of freedom
13459
const unsigned int dof = i - 8;
13461
// Generate scalings
13462
const double scalings_y_0 = 1;
13463
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
13464
const double scalings_z_0 = 1;
13465
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
13467
// Compute psitilde_a
13468
const double psitilde_a_0 = 1;
13469
const double psitilde_a_1 = x;
13471
// Compute psitilde_bs
13472
const double psitilde_bs_0_0 = 1;
13473
const double psitilde_bs_0_1 = 1.5*y + 0.5;
13474
const double psitilde_bs_1_0 = 1;
13476
// Compute psitilde_cs
13477
const double psitilde_cs_00_0 = 1;
13478
const double psitilde_cs_00_1 = 2*z + 1;
13479
const double psitilde_cs_01_0 = 1;
13480
const double psitilde_cs_10_0 = 1;
13482
// Compute basisvalues
13483
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
13484
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
13485
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
13486
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
13488
// Table(s) of coefficients
13489
static const double coefficients0[4][4] = \
13490
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
13491
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
13492
{0.288675135, 0, 0.210818511, -0.0745355992},
13493
{0.288675135, 0, 0, 0.223606798}};
13495
// Extract relevant coefficients
13496
const double coeff0_0 = coefficients0[dof][0];
13497
const double coeff0_1 = coefficients0[dof][1];
13498
const double coeff0_2 = coefficients0[dof][2];
13499
const double coeff0_3 = coefficients0[dof][3];
13501
// Compute value(s)
13502
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
13507
/// Evaluate all basis functions at given point in cell
13508
virtual void evaluate_basis_all(double* values,
13509
const double* coordinates,
13510
const ufc::cell& c) const
13512
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
13515
/// Evaluate order n derivatives of basis function i at given point in cell
13516
virtual void evaluate_basis_derivatives(unsigned int i,
13519
const double* coordinates,
13520
const ufc::cell& c) const
13522
// Extract vertex coordinates
13523
const double * const * element_coordinates = c.coordinates;
13525
// Compute Jacobian of affine map from reference cell
13526
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13527
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13528
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
13529
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13530
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13531
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
13532
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
13533
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
13534
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
13536
// Compute sub determinants
13537
const double d00 = J_11*J_22 - J_12*J_21;
13538
const double d01 = J_12*J_20 - J_10*J_22;
13539
const double d02 = J_10*J_21 - J_11*J_20;
13541
const double d10 = J_02*J_21 - J_01*J_22;
13542
const double d11 = J_00*J_22 - J_02*J_20;
13543
const double d12 = J_01*J_20 - J_00*J_21;
13545
const double d20 = J_01*J_12 - J_02*J_11;
13546
const double d21 = J_02*J_10 - J_00*J_12;
13547
const double d22 = J_00*J_11 - J_01*J_10;
13549
// Compute determinant of Jacobian
13550
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
13552
// Compute inverse of Jacobian
13554
// Compute constants
13555
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
13556
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
13557
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
13559
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
13560
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
13561
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
13563
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
13564
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
13565
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
13567
// Get coordinates and map to the UFC reference element
13568
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
13569
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
13570
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
13572
// Map coordinates to the reference cube
13573
if (std::abs(y + z - 1.0) < 1e-08)
13576
x = -2.0 * x/(y + z - 1.0) - 1.0;
13577
if (std::abs(z - 1.0) < 1e-08)
13580
y = 2.0 * y/(1.0 - z) - 1.0;
13583
// Compute number of derivatives
13584
unsigned int num_derivatives = 1;
13586
for (unsigned int j = 0; j < n; j++)
13587
num_derivatives *= 3;
13590
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
13591
unsigned int **combinations = new unsigned int *[num_derivatives];
13593
for (unsigned int j = 0; j < num_derivatives; j++)
13595
combinations[j] = new unsigned int [n];
13596
for (unsigned int k = 0; k < n; k++)
13597
combinations[j][k] = 0;
13600
// Generate combinations of derivatives
13601
for (unsigned int row = 1; row < num_derivatives; row++)
13603
for (unsigned int num = 0; num < row; num++)
13605
for (unsigned int col = n-1; col+1 > 0; col--)
13607
if (combinations[row][col] + 1 > 2)
13608
combinations[row][col] = 0;
13611
combinations[row][col] += 1;
13618
// Compute inverse of Jacobian
13619
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
13621
// Declare transformation matrix
13622
// Declare pointer to two dimensional array and initialise
13623
double **transform = new double *[num_derivatives];
13625
for (unsigned int j = 0; j < num_derivatives; j++)
13627
transform[j] = new double [num_derivatives];
13628
for (unsigned int k = 0; k < num_derivatives; k++)
13629
transform[j][k] = 1;
13632
// Construct transformation matrix
13633
for (unsigned int row = 0; row < num_derivatives; row++)
13635
for (unsigned int col = 0; col < num_derivatives; col++)
13637
for (unsigned int k = 0; k < n; k++)
13638
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13643
for (unsigned int j = 0; j < 3*num_derivatives; j++)
13646
if (0 <= i && i <= 3)
13648
// Map degree of freedom to element degree of freedom
13649
const unsigned int dof = i;
13651
// Generate scalings
13652
const double scalings_y_0 = 1;
13653
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
13654
const double scalings_z_0 = 1;
13655
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
13657
// Compute psitilde_a
13658
const double psitilde_a_0 = 1;
13659
const double psitilde_a_1 = x;
13661
// Compute psitilde_bs
13662
const double psitilde_bs_0_0 = 1;
13663
const double psitilde_bs_0_1 = 1.5*y + 0.5;
13664
const double psitilde_bs_1_0 = 1;
13666
// Compute psitilde_cs
13667
const double psitilde_cs_00_0 = 1;
13668
const double psitilde_cs_00_1 = 2*z + 1;
13669
const double psitilde_cs_01_0 = 1;
13670
const double psitilde_cs_10_0 = 1;
13672
// Compute basisvalues
13673
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
13674
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
13675
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
13676
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
13678
// Table(s) of coefficients
13679
static const double coefficients0[4][4] = \
13680
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
13681
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
13682
{0.288675135, 0, 0.210818511, -0.0745355992},
13683
{0.288675135, 0, 0, 0.223606798}};
13685
// Interesting (new) part
13686
// Tables of derivatives of the polynomial base (transpose)
13687
static const double dmats0[4][4] = \
13689
{6.32455532, 0, 0, 0},
13693
static const double dmats1[4][4] = \
13695
{3.16227766, 0, 0, 0},
13696
{5.47722558, 0, 0, 0},
13699
static const double dmats2[4][4] = \
13701
{3.16227766, 0, 0, 0},
13702
{1.82574186, 0, 0, 0},
13703
{5.16397779, 0, 0, 0}};
13705
// Compute reference derivatives
13706
// Declare pointer to array of derivatives on FIAT element
13707
double *derivatives = new double [num_derivatives];
13709
// Declare coefficients
13710
double coeff0_0 = 0;
13711
double coeff0_1 = 0;
13712
double coeff0_2 = 0;
13713
double coeff0_3 = 0;
13715
// Declare new coefficients
13716
double new_coeff0_0 = 0;
13717
double new_coeff0_1 = 0;
13718
double new_coeff0_2 = 0;
13719
double new_coeff0_3 = 0;
13721
// Loop possible derivatives
13722
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13724
// Get values from coefficients array
13725
new_coeff0_0 = coefficients0[dof][0];
13726
new_coeff0_1 = coefficients0[dof][1];
13727
new_coeff0_2 = coefficients0[dof][2];
13728
new_coeff0_3 = coefficients0[dof][3];
13730
// Loop derivative order
13731
for (unsigned int j = 0; j < n; j++)
13733
// Update old coefficients
13734
coeff0_0 = new_coeff0_0;
13735
coeff0_1 = new_coeff0_1;
13736
coeff0_2 = new_coeff0_2;
13737
coeff0_3 = new_coeff0_3;
13739
if(combinations[deriv_num][j] == 0)
13741
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
13742
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
13743
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
13744
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
13746
if(combinations[deriv_num][j] == 1)
13748
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
13749
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
13750
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
13751
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
13753
if(combinations[deriv_num][j] == 2)
13755
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
13756
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
13757
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
13758
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
13762
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13763
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
13766
// Transform derivatives back to physical element
13767
for (unsigned int row = 0; row < num_derivatives; row++)
13769
for (unsigned int col = 0; col < num_derivatives; col++)
13771
values[row] += transform[row][col]*derivatives[col];
13774
// Delete pointer to array of derivatives on FIAT element
13775
delete [] derivatives;
13777
// Delete pointer to array of combinations of derivatives and transform
13778
for (unsigned int row = 0; row < num_derivatives; row++)
13780
delete [] combinations[row];
13781
delete [] transform[row];
13784
delete [] combinations;
13785
delete [] transform;
13788
if (4 <= i && i <= 7)
13790
// Map degree of freedom to element degree of freedom
13791
const unsigned int dof = i - 4;
13793
// Generate scalings
13794
const double scalings_y_0 = 1;
13795
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
13796
const double scalings_z_0 = 1;
13797
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
13799
// Compute psitilde_a
13800
const double psitilde_a_0 = 1;
13801
const double psitilde_a_1 = x;
13803
// Compute psitilde_bs
13804
const double psitilde_bs_0_0 = 1;
13805
const double psitilde_bs_0_1 = 1.5*y + 0.5;
13806
const double psitilde_bs_1_0 = 1;
13808
// Compute psitilde_cs
13809
const double psitilde_cs_00_0 = 1;
13810
const double psitilde_cs_00_1 = 2*z + 1;
13811
const double psitilde_cs_01_0 = 1;
13812
const double psitilde_cs_10_0 = 1;
13814
// Compute basisvalues
13815
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
13816
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
13817
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
13818
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
13820
// Table(s) of coefficients
13821
static const double coefficients0[4][4] = \
13822
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
13823
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
13824
{0.288675135, 0, 0.210818511, -0.0745355992},
13825
{0.288675135, 0, 0, 0.223606798}};
13827
// Interesting (new) part
13828
// Tables of derivatives of the polynomial base (transpose)
13829
static const double dmats0[4][4] = \
13831
{6.32455532, 0, 0, 0},
13835
static const double dmats1[4][4] = \
13837
{3.16227766, 0, 0, 0},
13838
{5.47722558, 0, 0, 0},
13841
static const double dmats2[4][4] = \
13843
{3.16227766, 0, 0, 0},
13844
{1.82574186, 0, 0, 0},
13845
{5.16397779, 0, 0, 0}};
13847
// Compute reference derivatives
13848
// Declare pointer to array of derivatives on FIAT element
13849
double *derivatives = new double [num_derivatives];
13851
// Declare coefficients
13852
double coeff0_0 = 0;
13853
double coeff0_1 = 0;
13854
double coeff0_2 = 0;
13855
double coeff0_3 = 0;
13857
// Declare new coefficients
13858
double new_coeff0_0 = 0;
13859
double new_coeff0_1 = 0;
13860
double new_coeff0_2 = 0;
13861
double new_coeff0_3 = 0;
13863
// Loop possible derivatives
13864
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13866
// Get values from coefficients array
13867
new_coeff0_0 = coefficients0[dof][0];
13868
new_coeff0_1 = coefficients0[dof][1];
13869
new_coeff0_2 = coefficients0[dof][2];
13870
new_coeff0_3 = coefficients0[dof][3];
13872
// Loop derivative order
13873
for (unsigned int j = 0; j < n; j++)
13875
// Update old coefficients
13876
coeff0_0 = new_coeff0_0;
13877
coeff0_1 = new_coeff0_1;
13878
coeff0_2 = new_coeff0_2;
13879
coeff0_3 = new_coeff0_3;
13881
if(combinations[deriv_num][j] == 0)
13883
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
13884
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
13885
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
13886
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
13888
if(combinations[deriv_num][j] == 1)
13890
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
13891
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
13892
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
13893
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
13895
if(combinations[deriv_num][j] == 2)
13897
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
13898
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
13899
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
13900
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
13904
// Compute derivatives on reference element as dot product of coefficients and basisvalues
13905
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
13908
// Transform derivatives back to physical element
13909
for (unsigned int row = 0; row < num_derivatives; row++)
13911
for (unsigned int col = 0; col < num_derivatives; col++)
13913
values[num_derivatives + row] += transform[row][col]*derivatives[col];
13916
// Delete pointer to array of derivatives on FIAT element
13917
delete [] derivatives;
13919
// Delete pointer to array of combinations of derivatives and transform
13920
for (unsigned int row = 0; row < num_derivatives; row++)
13922
delete [] combinations[row];
13923
delete [] transform[row];
13926
delete [] combinations;
13927
delete [] transform;
13930
if (8 <= i && i <= 11)
13932
// Map degree of freedom to element degree of freedom
13933
const unsigned int dof = i - 8;
13935
// Generate scalings
13936
const double scalings_y_0 = 1;
13937
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
13938
const double scalings_z_0 = 1;
13939
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
13941
// Compute psitilde_a
13942
const double psitilde_a_0 = 1;
13943
const double psitilde_a_1 = x;
13945
// Compute psitilde_bs
13946
const double psitilde_bs_0_0 = 1;
13947
const double psitilde_bs_0_1 = 1.5*y + 0.5;
13948
const double psitilde_bs_1_0 = 1;
13950
// Compute psitilde_cs
13951
const double psitilde_cs_00_0 = 1;
13952
const double psitilde_cs_00_1 = 2*z + 1;
13953
const double psitilde_cs_01_0 = 1;
13954
const double psitilde_cs_10_0 = 1;
13956
// Compute basisvalues
13957
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
13958
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
13959
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
13960
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
13962
// Table(s) of coefficients
13963
static const double coefficients0[4][4] = \
13964
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
13965
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
13966
{0.288675135, 0, 0.210818511, -0.0745355992},
13967
{0.288675135, 0, 0, 0.223606798}};
13969
// Interesting (new) part
13970
// Tables of derivatives of the polynomial base (transpose)
13971
static const double dmats0[4][4] = \
13973
{6.32455532, 0, 0, 0},
13977
static const double dmats1[4][4] = \
13979
{3.16227766, 0, 0, 0},
13980
{5.47722558, 0, 0, 0},
13983
static const double dmats2[4][4] = \
13985
{3.16227766, 0, 0, 0},
13986
{1.82574186, 0, 0, 0},
13987
{5.16397779, 0, 0, 0}};
13989
// Compute reference derivatives
13990
// Declare pointer to array of derivatives on FIAT element
13991
double *derivatives = new double [num_derivatives];
13993
// Declare coefficients
13994
double coeff0_0 = 0;
13995
double coeff0_1 = 0;
13996
double coeff0_2 = 0;
13997
double coeff0_3 = 0;
13999
// Declare new coefficients
14000
double new_coeff0_0 = 0;
14001
double new_coeff0_1 = 0;
14002
double new_coeff0_2 = 0;
14003
double new_coeff0_3 = 0;
14005
// Loop possible derivatives
14006
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
14008
// Get values from coefficients array
14009
new_coeff0_0 = coefficients0[dof][0];
14010
new_coeff0_1 = coefficients0[dof][1];
14011
new_coeff0_2 = coefficients0[dof][2];
14012
new_coeff0_3 = coefficients0[dof][3];
14014
// Loop derivative order
14015
for (unsigned int j = 0; j < n; j++)
14017
// Update old coefficients
14018
coeff0_0 = new_coeff0_0;
14019
coeff0_1 = new_coeff0_1;
14020
coeff0_2 = new_coeff0_2;
14021
coeff0_3 = new_coeff0_3;
14023
if(combinations[deriv_num][j] == 0)
14025
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
14026
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
14027
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
14028
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
14030
if(combinations[deriv_num][j] == 1)
14032
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
14033
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
14034
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
14035
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
14037
if(combinations[deriv_num][j] == 2)
14039
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
14040
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
14041
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
14042
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
14046
// Compute derivatives on reference element as dot product of coefficients and basisvalues
14047
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
14050
// Transform derivatives back to physical element
14051
for (unsigned int row = 0; row < num_derivatives; row++)
14053
for (unsigned int col = 0; col < num_derivatives; col++)
14055
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
14058
// Delete pointer to array of derivatives on FIAT element
14059
delete [] derivatives;
14061
// Delete pointer to array of combinations of derivatives and transform
14062
for (unsigned int row = 0; row < num_derivatives; row++)
14064
delete [] combinations[row];
14065
delete [] transform[row];
14068
delete [] combinations;
14069
delete [] transform;
14074
/// Evaluate order n derivatives of all basis functions at given point in cell
14075
virtual void evaluate_basis_derivatives_all(unsigned int n,
14077
const double* coordinates,
14078
const ufc::cell& c) const
14080
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
14083
/// Evaluate linear functional for dof i on the function f
14084
virtual double evaluate_dof(unsigned int i,
14085
const ufc::function& f,
14086
const ufc::cell& c) const
14088
// The reference points, direction and weights:
14089
static const double X[12][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
14090
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
14091
static const double D[12][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
14093
const double * const * x = c.coordinates;
14094
double result = 0.0;
14095
// Iterate over the points:
14096
// Evaluate basis functions for affine mapping
14097
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
14098
const double w1 = X[i][0][0];
14099
const double w2 = X[i][0][1];
14100
const double w3 = X[i][0][2];
14102
// Compute affine mapping y = F(X)
14104
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
14105
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
14106
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
14108
// Evaluate function at physical points
14110
f.evaluate(values, y, c);
14112
// Map function values using appropriate mapping
14113
// Affine map: Do nothing
14115
// Note that we do not map the weights (yet).
14117
// Take directional components
14118
for(int k = 0; k < 3; k++)
14119
result += values[k]*D[i][0][k];
14120
// Multiply by weights
14126
/// Evaluate linear functionals for all dofs on the function f
14127
virtual void evaluate_dofs(double* values,
14128
const ufc::function& f,
14129
const ufc::cell& c) const
14131
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14134
/// Interpolate vertex values from dof values
14135
virtual void interpolate_vertex_values(double* vertex_values,
14136
const double* dof_values,
14137
const ufc::cell& c) const
14139
// Evaluate at vertices and use affine mapping
14140
vertex_values[0] = dof_values[0];
14141
vertex_values[3] = dof_values[1];
14142
vertex_values[6] = dof_values[2];
14143
vertex_values[9] = dof_values[3];
14144
// Evaluate at vertices and use affine mapping
14145
vertex_values[1] = dof_values[4];
14146
vertex_values[4] = dof_values[5];
14147
vertex_values[7] = dof_values[6];
14148
vertex_values[10] = dof_values[7];
14149
// Evaluate at vertices and use affine mapping
14150
vertex_values[2] = dof_values[8];
14151
vertex_values[5] = dof_values[9];
14152
vertex_values[8] = dof_values[10];
14153
vertex_values[11] = dof_values[11];
14156
/// Return the number of sub elements (for a mixed element)
14157
virtual unsigned int num_sub_elements() const
14162
/// Create a new finite element for sub element i (for a mixed element)
14163
virtual ufc::finite_element* create_sub_element(unsigned int i) const
14168
return new hyperelasticity_1_finite_element_0_0();
14171
return new hyperelasticity_1_finite_element_0_1();
14174
return new hyperelasticity_1_finite_element_0_2();
14182
/// This class defines the interface for a finite element.
14184
class hyperelasticity_1_finite_element_1_0: public ufc::finite_element
14189
hyperelasticity_1_finite_element_1_0() : ufc::finite_element()
14195
virtual ~hyperelasticity_1_finite_element_1_0()
14200
/// Return a string identifying the finite element
14201
virtual const char* signature() const
14203
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
14206
/// Return the cell shape
14207
virtual ufc::shape cell_shape() const
14209
return ufc::tetrahedron;
14212
/// Return the dimension of the finite element function space
14213
virtual unsigned int space_dimension() const
14218
/// Return the rank of the value space
14219
virtual unsigned int value_rank() const
14224
/// Return the dimension of the value space for axis i
14225
virtual unsigned int value_dimension(unsigned int i) const
14230
/// Evaluate basis function i at given point in cell
14231
virtual void evaluate_basis(unsigned int i,
14233
const double* coordinates,
14234
const ufc::cell& c) const
14236
// Extract vertex coordinates
14237
const double * const * element_coordinates = c.coordinates;
14239
// Compute Jacobian of affine map from reference cell
14240
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
14241
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
14242
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
14243
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
14244
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
14245
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
14246
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
14247
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
14248
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
14250
// Compute sub determinants
14251
const double d00 = J_11*J_22 - J_12*J_21;
14252
const double d01 = J_12*J_20 - J_10*J_22;
14253
const double d02 = J_10*J_21 - J_11*J_20;
14255
const double d10 = J_02*J_21 - J_01*J_22;
14256
const double d11 = J_00*J_22 - J_02*J_20;
14257
const double d12 = J_01*J_20 - J_00*J_21;
14259
const double d20 = J_01*J_12 - J_02*J_11;
14260
const double d21 = J_02*J_10 - J_00*J_12;
14261
const double d22 = J_00*J_11 - J_01*J_10;
14263
// Compute determinant of Jacobian
14264
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
14266
// Compute inverse of Jacobian
14268
// Compute constants
14269
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
14270
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
14271
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
14273
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
14274
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
14275
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
14277
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
14278
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
14279
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
14281
// Get coordinates and map to the UFC reference element
14282
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
14283
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
14284
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
14286
// Map coordinates to the reference cube
14287
if (std::abs(y + z - 1.0) < 1e-08)
14290
x = -2.0 * x/(y + z - 1.0) - 1.0;
14291
if (std::abs(z - 1.0) < 1e-08)
14294
y = 2.0 * y/(1.0 - z) - 1.0;
14300
// Map degree of freedom to element degree of freedom
14301
const unsigned int dof = i;
14303
// Generate scalings
14304
const double scalings_y_0 = 1;
14305
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
14306
const double scalings_z_0 = 1;
14307
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
14309
// Compute psitilde_a
14310
const double psitilde_a_0 = 1;
14311
const double psitilde_a_1 = x;
14313
// Compute psitilde_bs
14314
const double psitilde_bs_0_0 = 1;
14315
const double psitilde_bs_0_1 = 1.5*y + 0.5;
14316
const double psitilde_bs_1_0 = 1;
14318
// Compute psitilde_cs
14319
const double psitilde_cs_00_0 = 1;
14320
const double psitilde_cs_00_1 = 2*z + 1;
14321
const double psitilde_cs_01_0 = 1;
14322
const double psitilde_cs_10_0 = 1;
14324
// Compute basisvalues
14325
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
14326
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
14327
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
14328
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
14330
// Table(s) of coefficients
14331
static const double coefficients0[4][4] = \
14332
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
14333
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
14334
{0.288675135, 0, 0.210818511, -0.0745355992},
14335
{0.288675135, 0, 0, 0.223606798}};
14337
// Extract relevant coefficients
14338
const double coeff0_0 = coefficients0[dof][0];
14339
const double coeff0_1 = coefficients0[dof][1];
14340
const double coeff0_2 = coefficients0[dof][2];
14341
const double coeff0_3 = coefficients0[dof][3];
14343
// Compute value(s)
14344
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
14347
/// Evaluate all basis functions at given point in cell
14348
virtual void evaluate_basis_all(double* values,
14349
const double* coordinates,
14350
const ufc::cell& c) const
14352
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
14355
/// Evaluate order n derivatives of basis function i at given point in cell
14356
virtual void evaluate_basis_derivatives(unsigned int i,
14359
const double* coordinates,
14360
const ufc::cell& c) const
14362
// Extract vertex coordinates
14363
const double * const * element_coordinates = c.coordinates;
14365
// Compute Jacobian of affine map from reference cell
14366
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
14367
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
14368
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
14369
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
14370
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
14371
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
14372
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
14373
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
14374
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
14376
// Compute sub determinants
14377
const double d00 = J_11*J_22 - J_12*J_21;
14378
const double d01 = J_12*J_20 - J_10*J_22;
14379
const double d02 = J_10*J_21 - J_11*J_20;
14381
const double d10 = J_02*J_21 - J_01*J_22;
14382
const double d11 = J_00*J_22 - J_02*J_20;
14383
const double d12 = J_01*J_20 - J_00*J_21;
14385
const double d20 = J_01*J_12 - J_02*J_11;
14386
const double d21 = J_02*J_10 - J_00*J_12;
14387
const double d22 = J_00*J_11 - J_01*J_10;
14389
// Compute determinant of Jacobian
14390
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
14392
// Compute inverse of Jacobian
14394
// Compute constants
14395
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
14396
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
14397
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
14399
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
14400
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
14401
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
14403
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
14404
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
14405
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
14407
// Get coordinates and map to the UFC reference element
14408
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
14409
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
14410
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
14412
// Map coordinates to the reference cube
14413
if (std::abs(y + z - 1.0) < 1e-08)
14416
x = -2.0 * x/(y + z - 1.0) - 1.0;
14417
if (std::abs(z - 1.0) < 1e-08)
14420
y = 2.0 * y/(1.0 - z) - 1.0;
14423
// Compute number of derivatives
14424
unsigned int num_derivatives = 1;
14426
for (unsigned int j = 0; j < n; j++)
14427
num_derivatives *= 3;
14430
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
14431
unsigned int **combinations = new unsigned int *[num_derivatives];
14433
for (unsigned int j = 0; j < num_derivatives; j++)
14435
combinations[j] = new unsigned int [n];
14436
for (unsigned int k = 0; k < n; k++)
14437
combinations[j][k] = 0;
14440
// Generate combinations of derivatives
14441
for (unsigned int row = 1; row < num_derivatives; row++)
14443
for (unsigned int num = 0; num < row; num++)
14445
for (unsigned int col = n-1; col+1 > 0; col--)
14447
if (combinations[row][col] + 1 > 2)
14448
combinations[row][col] = 0;
14451
combinations[row][col] += 1;
14458
// Compute inverse of Jacobian
14459
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
14461
// Declare transformation matrix
14462
// Declare pointer to two dimensional array and initialise
14463
double **transform = new double *[num_derivatives];
14465
for (unsigned int j = 0; j < num_derivatives; j++)
14467
transform[j] = new double [num_derivatives];
14468
for (unsigned int k = 0; k < num_derivatives; k++)
14469
transform[j][k] = 1;
14472
// Construct transformation matrix
14473
for (unsigned int row = 0; row < num_derivatives; row++)
14475
for (unsigned int col = 0; col < num_derivatives; col++)
14477
for (unsigned int k = 0; k < n; k++)
14478
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
14483
for (unsigned int j = 0; j < 1*num_derivatives; j++)
14486
// Map degree of freedom to element degree of freedom
14487
const unsigned int dof = i;
14489
// Generate scalings
14490
const double scalings_y_0 = 1;
14491
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
14492
const double scalings_z_0 = 1;
14493
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
14495
// Compute psitilde_a
14496
const double psitilde_a_0 = 1;
14497
const double psitilde_a_1 = x;
14499
// Compute psitilde_bs
14500
const double psitilde_bs_0_0 = 1;
14501
const double psitilde_bs_0_1 = 1.5*y + 0.5;
14502
const double psitilde_bs_1_0 = 1;
14504
// Compute psitilde_cs
14505
const double psitilde_cs_00_0 = 1;
14506
const double psitilde_cs_00_1 = 2*z + 1;
14507
const double psitilde_cs_01_0 = 1;
14508
const double psitilde_cs_10_0 = 1;
14510
// Compute basisvalues
14511
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
14512
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
14513
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
14514
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
14516
// Table(s) of coefficients
14517
static const double coefficients0[4][4] = \
14518
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
14519
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
14520
{0.288675135, 0, 0.210818511, -0.0745355992},
14521
{0.288675135, 0, 0, 0.223606798}};
14523
// Interesting (new) part
14524
// Tables of derivatives of the polynomial base (transpose)
14525
static const double dmats0[4][4] = \
14527
{6.32455532, 0, 0, 0},
14531
static const double dmats1[4][4] = \
14533
{3.16227766, 0, 0, 0},
14534
{5.47722558, 0, 0, 0},
14537
static const double dmats2[4][4] = \
14539
{3.16227766, 0, 0, 0},
14540
{1.82574186, 0, 0, 0},
14541
{5.16397779, 0, 0, 0}};
14543
// Compute reference derivatives
14544
// Declare pointer to array of derivatives on FIAT element
14545
double *derivatives = new double [num_derivatives];
14547
// Declare coefficients
14548
double coeff0_0 = 0;
14549
double coeff0_1 = 0;
14550
double coeff0_2 = 0;
14551
double coeff0_3 = 0;
14553
// Declare new coefficients
14554
double new_coeff0_0 = 0;
14555
double new_coeff0_1 = 0;
14556
double new_coeff0_2 = 0;
14557
double new_coeff0_3 = 0;
14559
// Loop possible derivatives
14560
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
14562
// Get values from coefficients array
14563
new_coeff0_0 = coefficients0[dof][0];
14564
new_coeff0_1 = coefficients0[dof][1];
14565
new_coeff0_2 = coefficients0[dof][2];
14566
new_coeff0_3 = coefficients0[dof][3];
14568
// Loop derivative order
14569
for (unsigned int j = 0; j < n; j++)
14571
// Update old coefficients
14572
coeff0_0 = new_coeff0_0;
14573
coeff0_1 = new_coeff0_1;
14574
coeff0_2 = new_coeff0_2;
14575
coeff0_3 = new_coeff0_3;
14577
if(combinations[deriv_num][j] == 0)
14579
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
14580
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
14581
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
14582
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
14584
if(combinations[deriv_num][j] == 1)
14586
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
14587
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
14588
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
14589
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
14591
if(combinations[deriv_num][j] == 2)
14593
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
14594
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
14595
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
14596
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
14600
// Compute derivatives on reference element as dot product of coefficients and basisvalues
14601
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
14604
// Transform derivatives back to physical element
14605
for (unsigned int row = 0; row < num_derivatives; row++)
14607
for (unsigned int col = 0; col < num_derivatives; col++)
14609
values[row] += transform[row][col]*derivatives[col];
14612
// Delete pointer to array of derivatives on FIAT element
14613
delete [] derivatives;
14615
// Delete pointer to array of combinations of derivatives and transform
14616
for (unsigned int row = 0; row < num_derivatives; row++)
14618
delete [] combinations[row];
14619
delete [] transform[row];
14622
delete [] combinations;
14623
delete [] transform;
14626
/// Evaluate order n derivatives of all basis functions at given point in cell
14627
virtual void evaluate_basis_derivatives_all(unsigned int n,
14629
const double* coordinates,
14630
const ufc::cell& c) const
14632
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
14635
/// Evaluate linear functional for dof i on the function f
14636
virtual double evaluate_dof(unsigned int i,
14637
const ufc::function& f,
14638
const ufc::cell& c) const
14640
// The reference points, direction and weights:
14641
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
14642
static const double W[4][1] = {{1}, {1}, {1}, {1}};
14643
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
14645
const double * const * x = c.coordinates;
14646
double result = 0.0;
14647
// Iterate over the points:
14648
// Evaluate basis functions for affine mapping
14649
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
14650
const double w1 = X[i][0][0];
14651
const double w2 = X[i][0][1];
14652
const double w3 = X[i][0][2];
14654
// Compute affine mapping y = F(X)
14656
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
14657
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
14658
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
14660
// Evaluate function at physical points
14662
f.evaluate(values, y, c);
14664
// Map function values using appropriate mapping
14665
// Affine map: Do nothing
14667
// Note that we do not map the weights (yet).
14669
// Take directional components
14670
for(int k = 0; k < 1; k++)
14671
result += values[k]*D[i][0][k];
14672
// Multiply by weights
14678
/// Evaluate linear functionals for all dofs on the function f
14679
virtual void evaluate_dofs(double* values,
14680
const ufc::function& f,
14681
const ufc::cell& c) const
14683
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14686
/// Interpolate vertex values from dof values
14687
virtual void interpolate_vertex_values(double* vertex_values,
14688
const double* dof_values,
14689
const ufc::cell& c) const
14691
// Evaluate at vertices and use affine mapping
14692
vertex_values[0] = dof_values[0];
14693
vertex_values[1] = dof_values[1];
14694
vertex_values[2] = dof_values[2];
14695
vertex_values[3] = dof_values[3];
14698
/// Return the number of sub elements (for a mixed element)
14699
virtual unsigned int num_sub_elements() const
14704
/// Create a new finite element for sub element i (for a mixed element)
14705
virtual ufc::finite_element* create_sub_element(unsigned int i) const
14707
return new hyperelasticity_1_finite_element_1_0();
14712
/// This class defines the interface for a finite element.
14714
class hyperelasticity_1_finite_element_1_1: public ufc::finite_element
14719
hyperelasticity_1_finite_element_1_1() : ufc::finite_element()
14725
virtual ~hyperelasticity_1_finite_element_1_1()
14730
/// Return a string identifying the finite element
14731
virtual const char* signature() const
14733
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
14736
/// Return the cell shape
14737
virtual ufc::shape cell_shape() const
14739
return ufc::tetrahedron;
14742
/// Return the dimension of the finite element function space
14743
virtual unsigned int space_dimension() const
14748
/// Return the rank of the value space
14749
virtual unsigned int value_rank() const
14754
/// Return the dimension of the value space for axis i
14755
virtual unsigned int value_dimension(unsigned int i) const
14760
/// Evaluate basis function i at given point in cell
14761
virtual void evaluate_basis(unsigned int i,
14763
const double* coordinates,
14764
const ufc::cell& c) const
14766
// Extract vertex coordinates
14767
const double * const * element_coordinates = c.coordinates;
14769
// Compute Jacobian of affine map from reference cell
14770
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
14771
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
14772
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
14773
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
14774
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
14775
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
14776
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
14777
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
14778
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
14780
// Compute sub determinants
14781
const double d00 = J_11*J_22 - J_12*J_21;
14782
const double d01 = J_12*J_20 - J_10*J_22;
14783
const double d02 = J_10*J_21 - J_11*J_20;
14785
const double d10 = J_02*J_21 - J_01*J_22;
14786
const double d11 = J_00*J_22 - J_02*J_20;
14787
const double d12 = J_01*J_20 - J_00*J_21;
14789
const double d20 = J_01*J_12 - J_02*J_11;
14790
const double d21 = J_02*J_10 - J_00*J_12;
14791
const double d22 = J_00*J_11 - J_01*J_10;
14793
// Compute determinant of Jacobian
14794
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
14796
// Compute inverse of Jacobian
14798
// Compute constants
14799
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
14800
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
14801
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
14803
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
14804
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
14805
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
14807
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
14808
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
14809
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
14811
// Get coordinates and map to the UFC reference element
14812
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
14813
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
14814
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
14816
// Map coordinates to the reference cube
14817
if (std::abs(y + z - 1.0) < 1e-08)
14820
x = -2.0 * x/(y + z - 1.0) - 1.0;
14821
if (std::abs(z - 1.0) < 1e-08)
14824
y = 2.0 * y/(1.0 - z) - 1.0;
14830
// Map degree of freedom to element degree of freedom
14831
const unsigned int dof = i;
14833
// Generate scalings
14834
const double scalings_y_0 = 1;
14835
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
14836
const double scalings_z_0 = 1;
14837
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
14839
// Compute psitilde_a
14840
const double psitilde_a_0 = 1;
14841
const double psitilde_a_1 = x;
14843
// Compute psitilde_bs
14844
const double psitilde_bs_0_0 = 1;
14845
const double psitilde_bs_0_1 = 1.5*y + 0.5;
14846
const double psitilde_bs_1_0 = 1;
14848
// Compute psitilde_cs
14849
const double psitilde_cs_00_0 = 1;
14850
const double psitilde_cs_00_1 = 2*z + 1;
14851
const double psitilde_cs_01_0 = 1;
14852
const double psitilde_cs_10_0 = 1;
14854
// Compute basisvalues
14855
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
14856
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
14857
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
14858
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
14860
// Table(s) of coefficients
14861
static const double coefficients0[4][4] = \
14862
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
14863
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
14864
{0.288675135, 0, 0.210818511, -0.0745355992},
14865
{0.288675135, 0, 0, 0.223606798}};
14867
// Extract relevant coefficients
14868
const double coeff0_0 = coefficients0[dof][0];
14869
const double coeff0_1 = coefficients0[dof][1];
14870
const double coeff0_2 = coefficients0[dof][2];
14871
const double coeff0_3 = coefficients0[dof][3];
14873
// Compute value(s)
14874
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
14877
/// Evaluate all basis functions at given point in cell
14878
virtual void evaluate_basis_all(double* values,
14879
const double* coordinates,
14880
const ufc::cell& c) const
14882
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
14885
/// Evaluate order n derivatives of basis function i at given point in cell
14886
virtual void evaluate_basis_derivatives(unsigned int i,
14889
const double* coordinates,
14890
const ufc::cell& c) const
14892
// Extract vertex coordinates
14893
const double * const * element_coordinates = c.coordinates;
14895
// Compute Jacobian of affine map from reference cell
14896
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
14897
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
14898
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
14899
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
14900
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
14901
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
14902
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
14903
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
14904
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
14906
// Compute sub determinants
14907
const double d00 = J_11*J_22 - J_12*J_21;
14908
const double d01 = J_12*J_20 - J_10*J_22;
14909
const double d02 = J_10*J_21 - J_11*J_20;
14911
const double d10 = J_02*J_21 - J_01*J_22;
14912
const double d11 = J_00*J_22 - J_02*J_20;
14913
const double d12 = J_01*J_20 - J_00*J_21;
14915
const double d20 = J_01*J_12 - J_02*J_11;
14916
const double d21 = J_02*J_10 - J_00*J_12;
14917
const double d22 = J_00*J_11 - J_01*J_10;
14919
// Compute determinant of Jacobian
14920
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
14922
// Compute inverse of Jacobian
14924
// Compute constants
14925
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
14926
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
14927
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
14929
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
14930
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
14931
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
14933
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
14934
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
14935
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
14937
// Get coordinates and map to the UFC reference element
14938
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
14939
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
14940
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
14942
// Map coordinates to the reference cube
14943
if (std::abs(y + z - 1.0) < 1e-08)
14946
x = -2.0 * x/(y + z - 1.0) - 1.0;
14947
if (std::abs(z - 1.0) < 1e-08)
14950
y = 2.0 * y/(1.0 - z) - 1.0;
14953
// Compute number of derivatives
14954
unsigned int num_derivatives = 1;
14956
for (unsigned int j = 0; j < n; j++)
14957
num_derivatives *= 3;
14960
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
14961
unsigned int **combinations = new unsigned int *[num_derivatives];
14963
for (unsigned int j = 0; j < num_derivatives; j++)
14965
combinations[j] = new unsigned int [n];
14966
for (unsigned int k = 0; k < n; k++)
14967
combinations[j][k] = 0;
14970
// Generate combinations of derivatives
14971
for (unsigned int row = 1; row < num_derivatives; row++)
14973
for (unsigned int num = 0; num < row; num++)
14975
for (unsigned int col = n-1; col+1 > 0; col--)
14977
if (combinations[row][col] + 1 > 2)
14978
combinations[row][col] = 0;
14981
combinations[row][col] += 1;
14988
// Compute inverse of Jacobian
14989
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
14991
// Declare transformation matrix
14992
// Declare pointer to two dimensional array and initialise
14993
double **transform = new double *[num_derivatives];
14995
for (unsigned int j = 0; j < num_derivatives; j++)
14997
transform[j] = new double [num_derivatives];
14998
for (unsigned int k = 0; k < num_derivatives; k++)
14999
transform[j][k] = 1;
15002
// Construct transformation matrix
15003
for (unsigned int row = 0; row < num_derivatives; row++)
15005
for (unsigned int col = 0; col < num_derivatives; col++)
15007
for (unsigned int k = 0; k < n; k++)
15008
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
15013
for (unsigned int j = 0; j < 1*num_derivatives; j++)
15016
// Map degree of freedom to element degree of freedom
15017
const unsigned int dof = i;
15019
// Generate scalings
15020
const double scalings_y_0 = 1;
15021
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
15022
const double scalings_z_0 = 1;
15023
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
15025
// Compute psitilde_a
15026
const double psitilde_a_0 = 1;
15027
const double psitilde_a_1 = x;
15029
// Compute psitilde_bs
15030
const double psitilde_bs_0_0 = 1;
15031
const double psitilde_bs_0_1 = 1.5*y + 0.5;
15032
const double psitilde_bs_1_0 = 1;
15034
// Compute psitilde_cs
15035
const double psitilde_cs_00_0 = 1;
15036
const double psitilde_cs_00_1 = 2*z + 1;
15037
const double psitilde_cs_01_0 = 1;
15038
const double psitilde_cs_10_0 = 1;
15040
// Compute basisvalues
15041
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
15042
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
15043
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
15044
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
15046
// Table(s) of coefficients
15047
static const double coefficients0[4][4] = \
15048
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
15049
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
15050
{0.288675135, 0, 0.210818511, -0.0745355992},
15051
{0.288675135, 0, 0, 0.223606798}};
15053
// Interesting (new) part
15054
// Tables of derivatives of the polynomial base (transpose)
15055
static const double dmats0[4][4] = \
15057
{6.32455532, 0, 0, 0},
15061
static const double dmats1[4][4] = \
15063
{3.16227766, 0, 0, 0},
15064
{5.47722558, 0, 0, 0},
15067
static const double dmats2[4][4] = \
15069
{3.16227766, 0, 0, 0},
15070
{1.82574186, 0, 0, 0},
15071
{5.16397779, 0, 0, 0}};
15073
// Compute reference derivatives
15074
// Declare pointer to array of derivatives on FIAT element
15075
double *derivatives = new double [num_derivatives];
15077
// Declare coefficients
15078
double coeff0_0 = 0;
15079
double coeff0_1 = 0;
15080
double coeff0_2 = 0;
15081
double coeff0_3 = 0;
15083
// Declare new coefficients
15084
double new_coeff0_0 = 0;
15085
double new_coeff0_1 = 0;
15086
double new_coeff0_2 = 0;
15087
double new_coeff0_3 = 0;
15089
// Loop possible derivatives
15090
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
15092
// Get values from coefficients array
15093
new_coeff0_0 = coefficients0[dof][0];
15094
new_coeff0_1 = coefficients0[dof][1];
15095
new_coeff0_2 = coefficients0[dof][2];
15096
new_coeff0_3 = coefficients0[dof][3];
15098
// Loop derivative order
15099
for (unsigned int j = 0; j < n; j++)
15101
// Update old coefficients
15102
coeff0_0 = new_coeff0_0;
15103
coeff0_1 = new_coeff0_1;
15104
coeff0_2 = new_coeff0_2;
15105
coeff0_3 = new_coeff0_3;
15107
if(combinations[deriv_num][j] == 0)
15109
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
15110
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
15111
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
15112
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
15114
if(combinations[deriv_num][j] == 1)
15116
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
15117
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
15118
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
15119
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
15121
if(combinations[deriv_num][j] == 2)
15123
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
15124
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
15125
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
15126
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
15130
// Compute derivatives on reference element as dot product of coefficients and basisvalues
15131
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
15134
// Transform derivatives back to physical element
15135
for (unsigned int row = 0; row < num_derivatives; row++)
15137
for (unsigned int col = 0; col < num_derivatives; col++)
15139
values[row] += transform[row][col]*derivatives[col];
15142
// Delete pointer to array of derivatives on FIAT element
15143
delete [] derivatives;
15145
// Delete pointer to array of combinations of derivatives and transform
15146
for (unsigned int row = 0; row < num_derivatives; row++)
15148
delete [] combinations[row];
15149
delete [] transform[row];
15152
delete [] combinations;
15153
delete [] transform;
15156
/// Evaluate order n derivatives of all basis functions at given point in cell
15157
virtual void evaluate_basis_derivatives_all(unsigned int n,
15159
const double* coordinates,
15160
const ufc::cell& c) const
15162
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
15165
/// Evaluate linear functional for dof i on the function f
15166
virtual double evaluate_dof(unsigned int i,
15167
const ufc::function& f,
15168
const ufc::cell& c) const
15170
// The reference points, direction and weights:
15171
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
15172
static const double W[4][1] = {{1}, {1}, {1}, {1}};
15173
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
15175
const double * const * x = c.coordinates;
15176
double result = 0.0;
15177
// Iterate over the points:
15178
// Evaluate basis functions for affine mapping
15179
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
15180
const double w1 = X[i][0][0];
15181
const double w2 = X[i][0][1];
15182
const double w3 = X[i][0][2];
15184
// Compute affine mapping y = F(X)
15186
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
15187
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
15188
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
15190
// Evaluate function at physical points
15192
f.evaluate(values, y, c);
15194
// Map function values using appropriate mapping
15195
// Affine map: Do nothing
15197
// Note that we do not map the weights (yet).
15199
// Take directional components
15200
for(int k = 0; k < 1; k++)
15201
result += values[k]*D[i][0][k];
15202
// Multiply by weights
15208
/// Evaluate linear functionals for all dofs on the function f
15209
virtual void evaluate_dofs(double* values,
15210
const ufc::function& f,
15211
const ufc::cell& c) const
15213
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15216
/// Interpolate vertex values from dof values
15217
virtual void interpolate_vertex_values(double* vertex_values,
15218
const double* dof_values,
15219
const ufc::cell& c) const
15221
// Evaluate at vertices and use affine mapping
15222
vertex_values[0] = dof_values[0];
15223
vertex_values[1] = dof_values[1];
15224
vertex_values[2] = dof_values[2];
15225
vertex_values[3] = dof_values[3];
15228
/// Return the number of sub elements (for a mixed element)
15229
virtual unsigned int num_sub_elements() const
15234
/// Create a new finite element for sub element i (for a mixed element)
15235
virtual ufc::finite_element* create_sub_element(unsigned int i) const
15237
return new hyperelasticity_1_finite_element_1_1();
15242
/// This class defines the interface for a finite element.
15244
class hyperelasticity_1_finite_element_1_2: public ufc::finite_element
15249
hyperelasticity_1_finite_element_1_2() : ufc::finite_element()
15255
virtual ~hyperelasticity_1_finite_element_1_2()
15260
/// Return a string identifying the finite element
15261
virtual const char* signature() const
15263
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
15266
/// Return the cell shape
15267
virtual ufc::shape cell_shape() const
15269
return ufc::tetrahedron;
15272
/// Return the dimension of the finite element function space
15273
virtual unsigned int space_dimension() const
15278
/// Return the rank of the value space
15279
virtual unsigned int value_rank() const
15284
/// Return the dimension of the value space for axis i
15285
virtual unsigned int value_dimension(unsigned int i) const
15290
/// Evaluate basis function i at given point in cell
15291
virtual void evaluate_basis(unsigned int i,
15293
const double* coordinates,
15294
const ufc::cell& c) const
15296
// Extract vertex coordinates
15297
const double * const * element_coordinates = c.coordinates;
15299
// Compute Jacobian of affine map from reference cell
15300
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
15301
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
15302
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
15303
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
15304
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
15305
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
15306
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
15307
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
15308
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
15310
// Compute sub determinants
15311
const double d00 = J_11*J_22 - J_12*J_21;
15312
const double d01 = J_12*J_20 - J_10*J_22;
15313
const double d02 = J_10*J_21 - J_11*J_20;
15315
const double d10 = J_02*J_21 - J_01*J_22;
15316
const double d11 = J_00*J_22 - J_02*J_20;
15317
const double d12 = J_01*J_20 - J_00*J_21;
15319
const double d20 = J_01*J_12 - J_02*J_11;
15320
const double d21 = J_02*J_10 - J_00*J_12;
15321
const double d22 = J_00*J_11 - J_01*J_10;
15323
// Compute determinant of Jacobian
15324
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
15326
// Compute inverse of Jacobian
15328
// Compute constants
15329
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
15330
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
15331
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
15333
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
15334
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
15335
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
15337
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
15338
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
15339
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
15341
// Get coordinates and map to the UFC reference element
15342
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
15343
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
15344
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
15346
// Map coordinates to the reference cube
15347
if (std::abs(y + z - 1.0) < 1e-08)
15350
x = -2.0 * x/(y + z - 1.0) - 1.0;
15351
if (std::abs(z - 1.0) < 1e-08)
15354
y = 2.0 * y/(1.0 - z) - 1.0;
15360
// Map degree of freedom to element degree of freedom
15361
const unsigned int dof = i;
15363
// Generate scalings
15364
const double scalings_y_0 = 1;
15365
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
15366
const double scalings_z_0 = 1;
15367
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
15369
// Compute psitilde_a
15370
const double psitilde_a_0 = 1;
15371
const double psitilde_a_1 = x;
15373
// Compute psitilde_bs
15374
const double psitilde_bs_0_0 = 1;
15375
const double psitilde_bs_0_1 = 1.5*y + 0.5;
15376
const double psitilde_bs_1_0 = 1;
15378
// Compute psitilde_cs
15379
const double psitilde_cs_00_0 = 1;
15380
const double psitilde_cs_00_1 = 2*z + 1;
15381
const double psitilde_cs_01_0 = 1;
15382
const double psitilde_cs_10_0 = 1;
15384
// Compute basisvalues
15385
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
15386
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
15387
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
15388
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
15390
// Table(s) of coefficients
15391
static const double coefficients0[4][4] = \
15392
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
15393
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
15394
{0.288675135, 0, 0.210818511, -0.0745355992},
15395
{0.288675135, 0, 0, 0.223606798}};
15397
// Extract relevant coefficients
15398
const double coeff0_0 = coefficients0[dof][0];
15399
const double coeff0_1 = coefficients0[dof][1];
15400
const double coeff0_2 = coefficients0[dof][2];
15401
const double coeff0_3 = coefficients0[dof][3];
15403
// Compute value(s)
15404
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
15407
/// Evaluate all basis functions at given point in cell
15408
virtual void evaluate_basis_all(double* values,
15409
const double* coordinates,
15410
const ufc::cell& c) const
15412
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
15415
/// Evaluate order n derivatives of basis function i at given point in cell
15416
virtual void evaluate_basis_derivatives(unsigned int i,
15419
const double* coordinates,
15420
const ufc::cell& c) const
15422
// Extract vertex coordinates
15423
const double * const * element_coordinates = c.coordinates;
15425
// Compute Jacobian of affine map from reference cell
15426
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
15427
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
15428
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
15429
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
15430
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
15431
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
15432
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
15433
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
15434
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
15436
// Compute sub determinants
15437
const double d00 = J_11*J_22 - J_12*J_21;
15438
const double d01 = J_12*J_20 - J_10*J_22;
15439
const double d02 = J_10*J_21 - J_11*J_20;
15441
const double d10 = J_02*J_21 - J_01*J_22;
15442
const double d11 = J_00*J_22 - J_02*J_20;
15443
const double d12 = J_01*J_20 - J_00*J_21;
15445
const double d20 = J_01*J_12 - J_02*J_11;
15446
const double d21 = J_02*J_10 - J_00*J_12;
15447
const double d22 = J_00*J_11 - J_01*J_10;
15449
// Compute determinant of Jacobian
15450
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
15452
// Compute inverse of Jacobian
15454
// Compute constants
15455
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
15456
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
15457
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
15459
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
15460
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
15461
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
15463
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
15464
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
15465
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
15467
// Get coordinates and map to the UFC reference element
15468
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
15469
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
15470
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
15472
// Map coordinates to the reference cube
15473
if (std::abs(y + z - 1.0) < 1e-08)
15476
x = -2.0 * x/(y + z - 1.0) - 1.0;
15477
if (std::abs(z - 1.0) < 1e-08)
15480
y = 2.0 * y/(1.0 - z) - 1.0;
15483
// Compute number of derivatives
15484
unsigned int num_derivatives = 1;
15486
for (unsigned int j = 0; j < n; j++)
15487
num_derivatives *= 3;
15490
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
15491
unsigned int **combinations = new unsigned int *[num_derivatives];
15493
for (unsigned int j = 0; j < num_derivatives; j++)
15495
combinations[j] = new unsigned int [n];
15496
for (unsigned int k = 0; k < n; k++)
15497
combinations[j][k] = 0;
15500
// Generate combinations of derivatives
15501
for (unsigned int row = 1; row < num_derivatives; row++)
15503
for (unsigned int num = 0; num < row; num++)
15505
for (unsigned int col = n-1; col+1 > 0; col--)
15507
if (combinations[row][col] + 1 > 2)
15508
combinations[row][col] = 0;
15511
combinations[row][col] += 1;
15518
// Compute inverse of Jacobian
15519
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
15521
// Declare transformation matrix
15522
// Declare pointer to two dimensional array and initialise
15523
double **transform = new double *[num_derivatives];
15525
for (unsigned int j = 0; j < num_derivatives; j++)
15527
transform[j] = new double [num_derivatives];
15528
for (unsigned int k = 0; k < num_derivatives; k++)
15529
transform[j][k] = 1;
15532
// Construct transformation matrix
15533
for (unsigned int row = 0; row < num_derivatives; row++)
15535
for (unsigned int col = 0; col < num_derivatives; col++)
15537
for (unsigned int k = 0; k < n; k++)
15538
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
15543
for (unsigned int j = 0; j < 1*num_derivatives; j++)
15546
// Map degree of freedom to element degree of freedom
15547
const unsigned int dof = i;
15549
// Generate scalings
15550
const double scalings_y_0 = 1;
15551
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
15552
const double scalings_z_0 = 1;
15553
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
15555
// Compute psitilde_a
15556
const double psitilde_a_0 = 1;
15557
const double psitilde_a_1 = x;
15559
// Compute psitilde_bs
15560
const double psitilde_bs_0_0 = 1;
15561
const double psitilde_bs_0_1 = 1.5*y + 0.5;
15562
const double psitilde_bs_1_0 = 1;
15564
// Compute psitilde_cs
15565
const double psitilde_cs_00_0 = 1;
15566
const double psitilde_cs_00_1 = 2*z + 1;
15567
const double psitilde_cs_01_0 = 1;
15568
const double psitilde_cs_10_0 = 1;
15570
// Compute basisvalues
15571
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
15572
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
15573
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
15574
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
15576
// Table(s) of coefficients
15577
static const double coefficients0[4][4] = \
15578
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
15579
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
15580
{0.288675135, 0, 0.210818511, -0.0745355992},
15581
{0.288675135, 0, 0, 0.223606798}};
15583
// Interesting (new) part
15584
// Tables of derivatives of the polynomial base (transpose)
15585
static const double dmats0[4][4] = \
15587
{6.32455532, 0, 0, 0},
15591
static const double dmats1[4][4] = \
15593
{3.16227766, 0, 0, 0},
15594
{5.47722558, 0, 0, 0},
15597
static const double dmats2[4][4] = \
15599
{3.16227766, 0, 0, 0},
15600
{1.82574186, 0, 0, 0},
15601
{5.16397779, 0, 0, 0}};
15603
// Compute reference derivatives
15604
// Declare pointer to array of derivatives on FIAT element
15605
double *derivatives = new double [num_derivatives];
15607
// Declare coefficients
15608
double coeff0_0 = 0;
15609
double coeff0_1 = 0;
15610
double coeff0_2 = 0;
15611
double coeff0_3 = 0;
15613
// Declare new coefficients
15614
double new_coeff0_0 = 0;
15615
double new_coeff0_1 = 0;
15616
double new_coeff0_2 = 0;
15617
double new_coeff0_3 = 0;
15619
// Loop possible derivatives
15620
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
15622
// Get values from coefficients array
15623
new_coeff0_0 = coefficients0[dof][0];
15624
new_coeff0_1 = coefficients0[dof][1];
15625
new_coeff0_2 = coefficients0[dof][2];
15626
new_coeff0_3 = coefficients0[dof][3];
15628
// Loop derivative order
15629
for (unsigned int j = 0; j < n; j++)
15631
// Update old coefficients
15632
coeff0_0 = new_coeff0_0;
15633
coeff0_1 = new_coeff0_1;
15634
coeff0_2 = new_coeff0_2;
15635
coeff0_3 = new_coeff0_3;
15637
if(combinations[deriv_num][j] == 0)
15639
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
15640
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
15641
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
15642
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
15644
if(combinations[deriv_num][j] == 1)
15646
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
15647
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
15648
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
15649
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
15651
if(combinations[deriv_num][j] == 2)
15653
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
15654
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
15655
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
15656
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
15660
// Compute derivatives on reference element as dot product of coefficients and basisvalues
15661
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
15664
// Transform derivatives back to physical element
15665
for (unsigned int row = 0; row < num_derivatives; row++)
15667
for (unsigned int col = 0; col < num_derivatives; col++)
15669
values[row] += transform[row][col]*derivatives[col];
15672
// Delete pointer to array of derivatives on FIAT element
15673
delete [] derivatives;
15675
// Delete pointer to array of combinations of derivatives and transform
15676
for (unsigned int row = 0; row < num_derivatives; row++)
15678
delete [] combinations[row];
15679
delete [] transform[row];
15682
delete [] combinations;
15683
delete [] transform;
15686
/// Evaluate order n derivatives of all basis functions at given point in cell
15687
virtual void evaluate_basis_derivatives_all(unsigned int n,
15689
const double* coordinates,
15690
const ufc::cell& c) const
15692
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
15695
/// Evaluate linear functional for dof i on the function f
15696
virtual double evaluate_dof(unsigned int i,
15697
const ufc::function& f,
15698
const ufc::cell& c) const
15700
// The reference points, direction and weights:
15701
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
15702
static const double W[4][1] = {{1}, {1}, {1}, {1}};
15703
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
15705
const double * const * x = c.coordinates;
15706
double result = 0.0;
15707
// Iterate over the points:
15708
// Evaluate basis functions for affine mapping
15709
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
15710
const double w1 = X[i][0][0];
15711
const double w2 = X[i][0][1];
15712
const double w3 = X[i][0][2];
15714
// Compute affine mapping y = F(X)
15716
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
15717
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
15718
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
15720
// Evaluate function at physical points
15722
f.evaluate(values, y, c);
15724
// Map function values using appropriate mapping
15725
// Affine map: Do nothing
15727
// Note that we do not map the weights (yet).
15729
// Take directional components
15730
for(int k = 0; k < 1; k++)
15731
result += values[k]*D[i][0][k];
15732
// Multiply by weights
15738
/// Evaluate linear functionals for all dofs on the function f
15739
virtual void evaluate_dofs(double* values,
15740
const ufc::function& f,
15741
const ufc::cell& c) const
15743
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15746
/// Interpolate vertex values from dof values
15747
virtual void interpolate_vertex_values(double* vertex_values,
15748
const double* dof_values,
15749
const ufc::cell& c) const
15751
// Evaluate at vertices and use affine mapping
15752
vertex_values[0] = dof_values[0];
15753
vertex_values[1] = dof_values[1];
15754
vertex_values[2] = dof_values[2];
15755
vertex_values[3] = dof_values[3];
15758
/// Return the number of sub elements (for a mixed element)
15759
virtual unsigned int num_sub_elements() const
15764
/// Create a new finite element for sub element i (for a mixed element)
15765
virtual ufc::finite_element* create_sub_element(unsigned int i) const
15767
return new hyperelasticity_1_finite_element_1_2();
15772
/// This class defines the interface for a finite element.
15774
class hyperelasticity_1_finite_element_1: public ufc::finite_element
15779
hyperelasticity_1_finite_element_1() : ufc::finite_element()
15785
virtual ~hyperelasticity_1_finite_element_1()
15790
/// Return a string identifying the finite element
15791
virtual const char* signature() const
15793
return "VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
15796
/// Return the cell shape
15797
virtual ufc::shape cell_shape() const
15799
return ufc::tetrahedron;
15802
/// Return the dimension of the finite element function space
15803
virtual unsigned int space_dimension() const
15808
/// Return the rank of the value space
15809
virtual unsigned int value_rank() const
15814
/// Return the dimension of the value space for axis i
15815
virtual unsigned int value_dimension(unsigned int i) const
15820
/// Evaluate basis function i at given point in cell
15821
virtual void evaluate_basis(unsigned int i,
15823
const double* coordinates,
15824
const ufc::cell& c) const
15826
// Extract vertex coordinates
15827
const double * const * element_coordinates = c.coordinates;
15829
// Compute Jacobian of affine map from reference cell
15830
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
15831
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
15832
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
15833
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
15834
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
15835
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
15836
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
15837
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
15838
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
15840
// Compute sub determinants
15841
const double d00 = J_11*J_22 - J_12*J_21;
15842
const double d01 = J_12*J_20 - J_10*J_22;
15843
const double d02 = J_10*J_21 - J_11*J_20;
15845
const double d10 = J_02*J_21 - J_01*J_22;
15846
const double d11 = J_00*J_22 - J_02*J_20;
15847
const double d12 = J_01*J_20 - J_00*J_21;
15849
const double d20 = J_01*J_12 - J_02*J_11;
15850
const double d21 = J_02*J_10 - J_00*J_12;
15851
const double d22 = J_00*J_11 - J_01*J_10;
15853
// Compute determinant of Jacobian
15854
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
15856
// Compute inverse of Jacobian
15858
// Compute constants
15859
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
15860
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
15861
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
15863
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
15864
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
15865
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
15867
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
15868
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
15869
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
15871
// Get coordinates and map to the UFC reference element
15872
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
15873
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
15874
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
15876
// Map coordinates to the reference cube
15877
if (std::abs(y + z - 1.0) < 1e-08)
15880
x = -2.0 * x/(y + z - 1.0) - 1.0;
15881
if (std::abs(z - 1.0) < 1e-08)
15884
y = 2.0 * y/(1.0 - z) - 1.0;
15892
if (0 <= i && i <= 3)
15894
// Map degree of freedom to element degree of freedom
15895
const unsigned int dof = i;
15897
// Generate scalings
15898
const double scalings_y_0 = 1;
15899
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
15900
const double scalings_z_0 = 1;
15901
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
15903
// Compute psitilde_a
15904
const double psitilde_a_0 = 1;
15905
const double psitilde_a_1 = x;
15907
// Compute psitilde_bs
15908
const double psitilde_bs_0_0 = 1;
15909
const double psitilde_bs_0_1 = 1.5*y + 0.5;
15910
const double psitilde_bs_1_0 = 1;
15912
// Compute psitilde_cs
15913
const double psitilde_cs_00_0 = 1;
15914
const double psitilde_cs_00_1 = 2*z + 1;
15915
const double psitilde_cs_01_0 = 1;
15916
const double psitilde_cs_10_0 = 1;
15918
// Compute basisvalues
15919
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
15920
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
15921
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
15922
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
15924
// Table(s) of coefficients
15925
static const double coefficients0[4][4] = \
15926
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
15927
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
15928
{0.288675135, 0, 0.210818511, -0.0745355992},
15929
{0.288675135, 0, 0, 0.223606798}};
15931
// Extract relevant coefficients
15932
const double coeff0_0 = coefficients0[dof][0];
15933
const double coeff0_1 = coefficients0[dof][1];
15934
const double coeff0_2 = coefficients0[dof][2];
15935
const double coeff0_3 = coefficients0[dof][3];
15937
// Compute value(s)
15938
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
15941
if (4 <= i && i <= 7)
15943
// Map degree of freedom to element degree of freedom
15944
const unsigned int dof = i - 4;
15946
// Generate scalings
15947
const double scalings_y_0 = 1;
15948
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
15949
const double scalings_z_0 = 1;
15950
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
15952
// Compute psitilde_a
15953
const double psitilde_a_0 = 1;
15954
const double psitilde_a_1 = x;
15956
// Compute psitilde_bs
15957
const double psitilde_bs_0_0 = 1;
15958
const double psitilde_bs_0_1 = 1.5*y + 0.5;
15959
const double psitilde_bs_1_0 = 1;
15961
// Compute psitilde_cs
15962
const double psitilde_cs_00_0 = 1;
15963
const double psitilde_cs_00_1 = 2*z + 1;
15964
const double psitilde_cs_01_0 = 1;
15965
const double psitilde_cs_10_0 = 1;
15967
// Compute basisvalues
15968
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
15969
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
15970
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
15971
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
15973
// Table(s) of coefficients
15974
static const double coefficients0[4][4] = \
15975
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
15976
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
15977
{0.288675135, 0, 0.210818511, -0.0745355992},
15978
{0.288675135, 0, 0, 0.223606798}};
15980
// Extract relevant coefficients
15981
const double coeff0_0 = coefficients0[dof][0];
15982
const double coeff0_1 = coefficients0[dof][1];
15983
const double coeff0_2 = coefficients0[dof][2];
15984
const double coeff0_3 = coefficients0[dof][3];
15986
// Compute value(s)
15987
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
15990
if (8 <= i && i <= 11)
15992
// Map degree of freedom to element degree of freedom
15993
const unsigned int dof = i - 8;
15995
// Generate scalings
15996
const double scalings_y_0 = 1;
15997
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
15998
const double scalings_z_0 = 1;
15999
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
16001
// Compute psitilde_a
16002
const double psitilde_a_0 = 1;
16003
const double psitilde_a_1 = x;
16005
// Compute psitilde_bs
16006
const double psitilde_bs_0_0 = 1;
16007
const double psitilde_bs_0_1 = 1.5*y + 0.5;
16008
const double psitilde_bs_1_0 = 1;
16010
// Compute psitilde_cs
16011
const double psitilde_cs_00_0 = 1;
16012
const double psitilde_cs_00_1 = 2*z + 1;
16013
const double psitilde_cs_01_0 = 1;
16014
const double psitilde_cs_10_0 = 1;
16016
// Compute basisvalues
16017
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
16018
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
16019
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
16020
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
16022
// Table(s) of coefficients
16023
static const double coefficients0[4][4] = \
16024
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
16025
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
16026
{0.288675135, 0, 0.210818511, -0.0745355992},
16027
{0.288675135, 0, 0, 0.223606798}};
16029
// Extract relevant coefficients
16030
const double coeff0_0 = coefficients0[dof][0];
16031
const double coeff0_1 = coefficients0[dof][1];
16032
const double coeff0_2 = coefficients0[dof][2];
16033
const double coeff0_3 = coefficients0[dof][3];
16035
// Compute value(s)
16036
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
16041
/// Evaluate all basis functions at given point in cell
16042
virtual void evaluate_basis_all(double* values,
16043
const double* coordinates,
16044
const ufc::cell& c) const
16046
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
16049
/// Evaluate order n derivatives of basis function i at given point in cell
16050
virtual void evaluate_basis_derivatives(unsigned int i,
16053
const double* coordinates,
16054
const ufc::cell& c) const
16056
// Extract vertex coordinates
16057
const double * const * element_coordinates = c.coordinates;
16059
// Compute Jacobian of affine map from reference cell
16060
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
16061
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
16062
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
16063
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
16064
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
16065
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
16066
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
16067
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
16068
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
16070
// Compute sub determinants
16071
const double d00 = J_11*J_22 - J_12*J_21;
16072
const double d01 = J_12*J_20 - J_10*J_22;
16073
const double d02 = J_10*J_21 - J_11*J_20;
16075
const double d10 = J_02*J_21 - J_01*J_22;
16076
const double d11 = J_00*J_22 - J_02*J_20;
16077
const double d12 = J_01*J_20 - J_00*J_21;
16079
const double d20 = J_01*J_12 - J_02*J_11;
16080
const double d21 = J_02*J_10 - J_00*J_12;
16081
const double d22 = J_00*J_11 - J_01*J_10;
16083
// Compute determinant of Jacobian
16084
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
16086
// Compute inverse of Jacobian
16088
// Compute constants
16089
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
16090
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
16091
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
16093
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
16094
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
16095
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
16097
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
16098
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
16099
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
16101
// Get coordinates and map to the UFC reference element
16102
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
16103
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
16104
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
16106
// Map coordinates to the reference cube
16107
if (std::abs(y + z - 1.0) < 1e-08)
16110
x = -2.0 * x/(y + z - 1.0) - 1.0;
16111
if (std::abs(z - 1.0) < 1e-08)
16114
y = 2.0 * y/(1.0 - z) - 1.0;
16117
// Compute number of derivatives
16118
unsigned int num_derivatives = 1;
16120
for (unsigned int j = 0; j < n; j++)
16121
num_derivatives *= 3;
16124
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
16125
unsigned int **combinations = new unsigned int *[num_derivatives];
16127
for (unsigned int j = 0; j < num_derivatives; j++)
16129
combinations[j] = new unsigned int [n];
16130
for (unsigned int k = 0; k < n; k++)
16131
combinations[j][k] = 0;
16134
// Generate combinations of derivatives
16135
for (unsigned int row = 1; row < num_derivatives; row++)
16137
for (unsigned int num = 0; num < row; num++)
16139
for (unsigned int col = n-1; col+1 > 0; col--)
16141
if (combinations[row][col] + 1 > 2)
16142
combinations[row][col] = 0;
16145
combinations[row][col] += 1;
16152
// Compute inverse of Jacobian
16153
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
16155
// Declare transformation matrix
16156
// Declare pointer to two dimensional array and initialise
16157
double **transform = new double *[num_derivatives];
16159
for (unsigned int j = 0; j < num_derivatives; j++)
16161
transform[j] = new double [num_derivatives];
16162
for (unsigned int k = 0; k < num_derivatives; k++)
16163
transform[j][k] = 1;
16166
// Construct transformation matrix
16167
for (unsigned int row = 0; row < num_derivatives; row++)
16169
for (unsigned int col = 0; col < num_derivatives; col++)
16171
for (unsigned int k = 0; k < n; k++)
16172
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
16177
for (unsigned int j = 0; j < 3*num_derivatives; j++)
16180
if (0 <= i && i <= 3)
16182
// Map degree of freedom to element degree of freedom
16183
const unsigned int dof = i;
16185
// Generate scalings
16186
const double scalings_y_0 = 1;
16187
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
16188
const double scalings_z_0 = 1;
16189
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
16191
// Compute psitilde_a
16192
const double psitilde_a_0 = 1;
16193
const double psitilde_a_1 = x;
16195
// Compute psitilde_bs
16196
const double psitilde_bs_0_0 = 1;
16197
const double psitilde_bs_0_1 = 1.5*y + 0.5;
16198
const double psitilde_bs_1_0 = 1;
16200
// Compute psitilde_cs
16201
const double psitilde_cs_00_0 = 1;
16202
const double psitilde_cs_00_1 = 2*z + 1;
16203
const double psitilde_cs_01_0 = 1;
16204
const double psitilde_cs_10_0 = 1;
16206
// Compute basisvalues
16207
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
16208
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
16209
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
16210
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
16212
// Table(s) of coefficients
16213
static const double coefficients0[4][4] = \
16214
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
16215
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
16216
{0.288675135, 0, 0.210818511, -0.0745355992},
16217
{0.288675135, 0, 0, 0.223606798}};
16219
// Interesting (new) part
16220
// Tables of derivatives of the polynomial base (transpose)
16221
static const double dmats0[4][4] = \
16223
{6.32455532, 0, 0, 0},
16227
static const double dmats1[4][4] = \
16229
{3.16227766, 0, 0, 0},
16230
{5.47722558, 0, 0, 0},
16233
static const double dmats2[4][4] = \
16235
{3.16227766, 0, 0, 0},
16236
{1.82574186, 0, 0, 0},
16237
{5.16397779, 0, 0, 0}};
16239
// Compute reference derivatives
16240
// Declare pointer to array of derivatives on FIAT element
16241
double *derivatives = new double [num_derivatives];
16243
// Declare coefficients
16244
double coeff0_0 = 0;
16245
double coeff0_1 = 0;
16246
double coeff0_2 = 0;
16247
double coeff0_3 = 0;
16249
// Declare new coefficients
16250
double new_coeff0_0 = 0;
16251
double new_coeff0_1 = 0;
16252
double new_coeff0_2 = 0;
16253
double new_coeff0_3 = 0;
16255
// Loop possible derivatives
16256
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
16258
// Get values from coefficients array
16259
new_coeff0_0 = coefficients0[dof][0];
16260
new_coeff0_1 = coefficients0[dof][1];
16261
new_coeff0_2 = coefficients0[dof][2];
16262
new_coeff0_3 = coefficients0[dof][3];
16264
// Loop derivative order
16265
for (unsigned int j = 0; j < n; j++)
16267
// Update old coefficients
16268
coeff0_0 = new_coeff0_0;
16269
coeff0_1 = new_coeff0_1;
16270
coeff0_2 = new_coeff0_2;
16271
coeff0_3 = new_coeff0_3;
16273
if(combinations[deriv_num][j] == 0)
16275
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
16276
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
16277
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
16278
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
16280
if(combinations[deriv_num][j] == 1)
16282
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
16283
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
16284
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
16285
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
16287
if(combinations[deriv_num][j] == 2)
16289
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
16290
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
16291
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
16292
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
16296
// Compute derivatives on reference element as dot product of coefficients and basisvalues
16297
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
16300
// Transform derivatives back to physical element
16301
for (unsigned int row = 0; row < num_derivatives; row++)
16303
for (unsigned int col = 0; col < num_derivatives; col++)
16305
values[row] += transform[row][col]*derivatives[col];
16308
// Delete pointer to array of derivatives on FIAT element
16309
delete [] derivatives;
16311
// Delete pointer to array of combinations of derivatives and transform
16312
for (unsigned int row = 0; row < num_derivatives; row++)
16314
delete [] combinations[row];
16315
delete [] transform[row];
16318
delete [] combinations;
16319
delete [] transform;
16322
if (4 <= i && i <= 7)
16324
// Map degree of freedom to element degree of freedom
16325
const unsigned int dof = i - 4;
16327
// Generate scalings
16328
const double scalings_y_0 = 1;
16329
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
16330
const double scalings_z_0 = 1;
16331
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
16333
// Compute psitilde_a
16334
const double psitilde_a_0 = 1;
16335
const double psitilde_a_1 = x;
16337
// Compute psitilde_bs
16338
const double psitilde_bs_0_0 = 1;
16339
const double psitilde_bs_0_1 = 1.5*y + 0.5;
16340
const double psitilde_bs_1_0 = 1;
16342
// Compute psitilde_cs
16343
const double psitilde_cs_00_0 = 1;
16344
const double psitilde_cs_00_1 = 2*z + 1;
16345
const double psitilde_cs_01_0 = 1;
16346
const double psitilde_cs_10_0 = 1;
16348
// Compute basisvalues
16349
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
16350
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
16351
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
16352
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
16354
// Table(s) of coefficients
16355
static const double coefficients0[4][4] = \
16356
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
16357
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
16358
{0.288675135, 0, 0.210818511, -0.0745355992},
16359
{0.288675135, 0, 0, 0.223606798}};
16361
// Interesting (new) part
16362
// Tables of derivatives of the polynomial base (transpose)
16363
static const double dmats0[4][4] = \
16365
{6.32455532, 0, 0, 0},
16369
static const double dmats1[4][4] = \
16371
{3.16227766, 0, 0, 0},
16372
{5.47722558, 0, 0, 0},
16375
static const double dmats2[4][4] = \
16377
{3.16227766, 0, 0, 0},
16378
{1.82574186, 0, 0, 0},
16379
{5.16397779, 0, 0, 0}};
16381
// Compute reference derivatives
16382
// Declare pointer to array of derivatives on FIAT element
16383
double *derivatives = new double [num_derivatives];
16385
// Declare coefficients
16386
double coeff0_0 = 0;
16387
double coeff0_1 = 0;
16388
double coeff0_2 = 0;
16389
double coeff0_3 = 0;
16391
// Declare new coefficients
16392
double new_coeff0_0 = 0;
16393
double new_coeff0_1 = 0;
16394
double new_coeff0_2 = 0;
16395
double new_coeff0_3 = 0;
16397
// Loop possible derivatives
16398
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
16400
// Get values from coefficients array
16401
new_coeff0_0 = coefficients0[dof][0];
16402
new_coeff0_1 = coefficients0[dof][1];
16403
new_coeff0_2 = coefficients0[dof][2];
16404
new_coeff0_3 = coefficients0[dof][3];
16406
// Loop derivative order
16407
for (unsigned int j = 0; j < n; j++)
16409
// Update old coefficients
16410
coeff0_0 = new_coeff0_0;
16411
coeff0_1 = new_coeff0_1;
16412
coeff0_2 = new_coeff0_2;
16413
coeff0_3 = new_coeff0_3;
16415
if(combinations[deriv_num][j] == 0)
16417
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
16418
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
16419
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
16420
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
16422
if(combinations[deriv_num][j] == 1)
16424
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
16425
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
16426
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
16427
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
16429
if(combinations[deriv_num][j] == 2)
16431
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
16432
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
16433
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
16434
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
16438
// Compute derivatives on reference element as dot product of coefficients and basisvalues
16439
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
16442
// Transform derivatives back to physical element
16443
for (unsigned int row = 0; row < num_derivatives; row++)
16445
for (unsigned int col = 0; col < num_derivatives; col++)
16447
values[num_derivatives + row] += transform[row][col]*derivatives[col];
16450
// Delete pointer to array of derivatives on FIAT element
16451
delete [] derivatives;
16453
// Delete pointer to array of combinations of derivatives and transform
16454
for (unsigned int row = 0; row < num_derivatives; row++)
16456
delete [] combinations[row];
16457
delete [] transform[row];
16460
delete [] combinations;
16461
delete [] transform;
16464
if (8 <= i && i <= 11)
16466
// Map degree of freedom to element degree of freedom
16467
const unsigned int dof = i - 8;
16469
// Generate scalings
16470
const double scalings_y_0 = 1;
16471
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
16472
const double scalings_z_0 = 1;
16473
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
16475
// Compute psitilde_a
16476
const double psitilde_a_0 = 1;
16477
const double psitilde_a_1 = x;
16479
// Compute psitilde_bs
16480
const double psitilde_bs_0_0 = 1;
16481
const double psitilde_bs_0_1 = 1.5*y + 0.5;
16482
const double psitilde_bs_1_0 = 1;
16484
// Compute psitilde_cs
16485
const double psitilde_cs_00_0 = 1;
16486
const double psitilde_cs_00_1 = 2*z + 1;
16487
const double psitilde_cs_01_0 = 1;
16488
const double psitilde_cs_10_0 = 1;
16490
// Compute basisvalues
16491
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
16492
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
16493
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
16494
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
16496
// Table(s) of coefficients
16497
static const double coefficients0[4][4] = \
16498
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
16499
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
16500
{0.288675135, 0, 0.210818511, -0.0745355992},
16501
{0.288675135, 0, 0, 0.223606798}};
16503
// Interesting (new) part
16504
// Tables of derivatives of the polynomial base (transpose)
16505
static const double dmats0[4][4] = \
16507
{6.32455532, 0, 0, 0},
16511
static const double dmats1[4][4] = \
16513
{3.16227766, 0, 0, 0},
16514
{5.47722558, 0, 0, 0},
16517
static const double dmats2[4][4] = \
16519
{3.16227766, 0, 0, 0},
16520
{1.82574186, 0, 0, 0},
16521
{5.16397779, 0, 0, 0}};
16523
// Compute reference derivatives
16524
// Declare pointer to array of derivatives on FIAT element
16525
double *derivatives = new double [num_derivatives];
16527
// Declare coefficients
16528
double coeff0_0 = 0;
16529
double coeff0_1 = 0;
16530
double coeff0_2 = 0;
16531
double coeff0_3 = 0;
16533
// Declare new coefficients
16534
double new_coeff0_0 = 0;
16535
double new_coeff0_1 = 0;
16536
double new_coeff0_2 = 0;
16537
double new_coeff0_3 = 0;
16539
// Loop possible derivatives
16540
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
16542
// Get values from coefficients array
16543
new_coeff0_0 = coefficients0[dof][0];
16544
new_coeff0_1 = coefficients0[dof][1];
16545
new_coeff0_2 = coefficients0[dof][2];
16546
new_coeff0_3 = coefficients0[dof][3];
16548
// Loop derivative order
16549
for (unsigned int j = 0; j < n; j++)
16551
// Update old coefficients
16552
coeff0_0 = new_coeff0_0;
16553
coeff0_1 = new_coeff0_1;
16554
coeff0_2 = new_coeff0_2;
16555
coeff0_3 = new_coeff0_3;
16557
if(combinations[deriv_num][j] == 0)
16559
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
16560
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
16561
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
16562
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
16564
if(combinations[deriv_num][j] == 1)
16566
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
16567
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
16568
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
16569
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
16571
if(combinations[deriv_num][j] == 2)
16573
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
16574
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
16575
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
16576
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
16580
// Compute derivatives on reference element as dot product of coefficients and basisvalues
16581
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
16584
// Transform derivatives back to physical element
16585
for (unsigned int row = 0; row < num_derivatives; row++)
16587
for (unsigned int col = 0; col < num_derivatives; col++)
16589
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
16592
// Delete pointer to array of derivatives on FIAT element
16593
delete [] derivatives;
16595
// Delete pointer to array of combinations of derivatives and transform
16596
for (unsigned int row = 0; row < num_derivatives; row++)
16598
delete [] combinations[row];
16599
delete [] transform[row];
16602
delete [] combinations;
16603
delete [] transform;
16608
/// Evaluate order n derivatives of all basis functions at given point in cell
16609
virtual void evaluate_basis_derivatives_all(unsigned int n,
16611
const double* coordinates,
16612
const ufc::cell& c) const
16614
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
16617
/// Evaluate linear functional for dof i on the function f
16618
virtual double evaluate_dof(unsigned int i,
16619
const ufc::function& f,
16620
const ufc::cell& c) const
16622
// The reference points, direction and weights:
16623
static const double X[12][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
16624
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
16625
static const double D[12][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
16627
const double * const * x = c.coordinates;
16628
double result = 0.0;
16629
// Iterate over the points:
16630
// Evaluate basis functions for affine mapping
16631
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
16632
const double w1 = X[i][0][0];
16633
const double w2 = X[i][0][1];
16634
const double w3 = X[i][0][2];
16636
// Compute affine mapping y = F(X)
16638
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
16639
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
16640
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
16642
// Evaluate function at physical points
16644
f.evaluate(values, y, c);
16646
// Map function values using appropriate mapping
16647
// Affine map: Do nothing
16649
// Note that we do not map the weights (yet).
16651
// Take directional components
16652
for(int k = 0; k < 3; k++)
16653
result += values[k]*D[i][0][k];
16654
// Multiply by weights
16660
/// Evaluate linear functionals for all dofs on the function f
16661
virtual void evaluate_dofs(double* values,
16662
const ufc::function& f,
16663
const ufc::cell& c) const
16665
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
16668
/// Interpolate vertex values from dof values
16669
virtual void interpolate_vertex_values(double* vertex_values,
16670
const double* dof_values,
16671
const ufc::cell& c) const
16673
// Evaluate at vertices and use affine mapping
16674
vertex_values[0] = dof_values[0];
16675
vertex_values[3] = dof_values[1];
16676
vertex_values[6] = dof_values[2];
16677
vertex_values[9] = dof_values[3];
16678
// Evaluate at vertices and use affine mapping
16679
vertex_values[1] = dof_values[4];
16680
vertex_values[4] = dof_values[5];
16681
vertex_values[7] = dof_values[6];
16682
vertex_values[10] = dof_values[7];
16683
// Evaluate at vertices and use affine mapping
16684
vertex_values[2] = dof_values[8];
16685
vertex_values[5] = dof_values[9];
16686
vertex_values[8] = dof_values[10];
16687
vertex_values[11] = dof_values[11];
16690
/// Return the number of sub elements (for a mixed element)
16691
virtual unsigned int num_sub_elements() const
16696
/// Create a new finite element for sub element i (for a mixed element)
16697
virtual ufc::finite_element* create_sub_element(unsigned int i) const
16702
return new hyperelasticity_1_finite_element_1_0();
16705
return new hyperelasticity_1_finite_element_1_1();
16708
return new hyperelasticity_1_finite_element_1_2();
16716
/// This class defines the interface for a finite element.
16718
class hyperelasticity_1_finite_element_2_0: public ufc::finite_element
16723
hyperelasticity_1_finite_element_2_0() : ufc::finite_element()
16729
virtual ~hyperelasticity_1_finite_element_2_0()
16734
/// Return a string identifying the finite element
16735
virtual const char* signature() const
16737
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
16740
/// Return the cell shape
16741
virtual ufc::shape cell_shape() const
16743
return ufc::tetrahedron;
16746
/// Return the dimension of the finite element function space
16747
virtual unsigned int space_dimension() const
16752
/// Return the rank of the value space
16753
virtual unsigned int value_rank() const
16758
/// Return the dimension of the value space for axis i
16759
virtual unsigned int value_dimension(unsigned int i) const
16764
/// Evaluate basis function i at given point in cell
16765
virtual void evaluate_basis(unsigned int i,
16767
const double* coordinates,
16768
const ufc::cell& c) const
16770
// Extract vertex coordinates
16771
const double * const * element_coordinates = c.coordinates;
16773
// Compute Jacobian of affine map from reference cell
16774
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
16775
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
16776
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
16777
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
16778
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
16779
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
16780
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
16781
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
16782
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
16784
// Compute sub determinants
16785
const double d00 = J_11*J_22 - J_12*J_21;
16786
const double d01 = J_12*J_20 - J_10*J_22;
16787
const double d02 = J_10*J_21 - J_11*J_20;
16789
const double d10 = J_02*J_21 - J_01*J_22;
16790
const double d11 = J_00*J_22 - J_02*J_20;
16791
const double d12 = J_01*J_20 - J_00*J_21;
16793
const double d20 = J_01*J_12 - J_02*J_11;
16794
const double d21 = J_02*J_10 - J_00*J_12;
16795
const double d22 = J_00*J_11 - J_01*J_10;
16797
// Compute determinant of Jacobian
16798
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
16800
// Compute inverse of Jacobian
16802
// Compute constants
16803
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
16804
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
16805
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
16807
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
16808
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
16809
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
16811
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
16812
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
16813
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
16815
// Get coordinates and map to the UFC reference element
16816
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
16817
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
16818
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
16820
// Map coordinates to the reference cube
16821
if (std::abs(y + z - 1.0) < 1e-08)
16824
x = -2.0 * x/(y + z - 1.0) - 1.0;
16825
if (std::abs(z - 1.0) < 1e-08)
16828
y = 2.0 * y/(1.0 - z) - 1.0;
16834
// Map degree of freedom to element degree of freedom
16835
const unsigned int dof = i;
16837
// Generate scalings
16838
const double scalings_y_0 = 1;
16839
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
16840
const double scalings_z_0 = 1;
16841
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
16843
// Compute psitilde_a
16844
const double psitilde_a_0 = 1;
16845
const double psitilde_a_1 = x;
16847
// Compute psitilde_bs
16848
const double psitilde_bs_0_0 = 1;
16849
const double psitilde_bs_0_1 = 1.5*y + 0.5;
16850
const double psitilde_bs_1_0 = 1;
16852
// Compute psitilde_cs
16853
const double psitilde_cs_00_0 = 1;
16854
const double psitilde_cs_00_1 = 2*z + 1;
16855
const double psitilde_cs_01_0 = 1;
16856
const double psitilde_cs_10_0 = 1;
16858
// Compute basisvalues
16859
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
16860
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
16861
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
16862
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
16864
// Table(s) of coefficients
16865
static const double coefficients0[4][4] = \
16866
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
16867
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
16868
{0.288675135, 0, 0.210818511, -0.0745355992},
16869
{0.288675135, 0, 0, 0.223606798}};
16871
// Extract relevant coefficients
16872
const double coeff0_0 = coefficients0[dof][0];
16873
const double coeff0_1 = coefficients0[dof][1];
16874
const double coeff0_2 = coefficients0[dof][2];
16875
const double coeff0_3 = coefficients0[dof][3];
16877
// Compute value(s)
16878
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
16881
/// Evaluate all basis functions at given point in cell
16882
virtual void evaluate_basis_all(double* values,
16883
const double* coordinates,
16884
const ufc::cell& c) const
16886
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
16889
/// Evaluate order n derivatives of basis function i at given point in cell
16890
virtual void evaluate_basis_derivatives(unsigned int i,
16893
const double* coordinates,
16894
const ufc::cell& c) const
16896
// Extract vertex coordinates
16897
const double * const * element_coordinates = c.coordinates;
16899
// Compute Jacobian of affine map from reference cell
16900
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
16901
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
16902
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
16903
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
16904
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
16905
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
16906
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
16907
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
16908
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
16910
// Compute sub determinants
16911
const double d00 = J_11*J_22 - J_12*J_21;
16912
const double d01 = J_12*J_20 - J_10*J_22;
16913
const double d02 = J_10*J_21 - J_11*J_20;
16915
const double d10 = J_02*J_21 - J_01*J_22;
16916
const double d11 = J_00*J_22 - J_02*J_20;
16917
const double d12 = J_01*J_20 - J_00*J_21;
16919
const double d20 = J_01*J_12 - J_02*J_11;
16920
const double d21 = J_02*J_10 - J_00*J_12;
16921
const double d22 = J_00*J_11 - J_01*J_10;
16923
// Compute determinant of Jacobian
16924
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
16926
// Compute inverse of Jacobian
16928
// Compute constants
16929
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
16930
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
16931
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
16933
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
16934
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
16935
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
16937
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
16938
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
16939
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
16941
// Get coordinates and map to the UFC reference element
16942
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
16943
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
16944
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
16946
// Map coordinates to the reference cube
16947
if (std::abs(y + z - 1.0) < 1e-08)
16950
x = -2.0 * x/(y + z - 1.0) - 1.0;
16951
if (std::abs(z - 1.0) < 1e-08)
16954
y = 2.0 * y/(1.0 - z) - 1.0;
16957
// Compute number of derivatives
16958
unsigned int num_derivatives = 1;
16960
for (unsigned int j = 0; j < n; j++)
16961
num_derivatives *= 3;
16964
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
16965
unsigned int **combinations = new unsigned int *[num_derivatives];
16967
for (unsigned int j = 0; j < num_derivatives; j++)
16969
combinations[j] = new unsigned int [n];
16970
for (unsigned int k = 0; k < n; k++)
16971
combinations[j][k] = 0;
16974
// Generate combinations of derivatives
16975
for (unsigned int row = 1; row < num_derivatives; row++)
16977
for (unsigned int num = 0; num < row; num++)
16979
for (unsigned int col = n-1; col+1 > 0; col--)
16981
if (combinations[row][col] + 1 > 2)
16982
combinations[row][col] = 0;
16985
combinations[row][col] += 1;
16992
// Compute inverse of Jacobian
16993
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
16995
// Declare transformation matrix
16996
// Declare pointer to two dimensional array and initialise
16997
double **transform = new double *[num_derivatives];
16999
for (unsigned int j = 0; j < num_derivatives; j++)
17001
transform[j] = new double [num_derivatives];
17002
for (unsigned int k = 0; k < num_derivatives; k++)
17003
transform[j][k] = 1;
17006
// Construct transformation matrix
17007
for (unsigned int row = 0; row < num_derivatives; row++)
17009
for (unsigned int col = 0; col < num_derivatives; col++)
17011
for (unsigned int k = 0; k < n; k++)
17012
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
17017
for (unsigned int j = 0; j < 1*num_derivatives; j++)
17020
// Map degree of freedom to element degree of freedom
17021
const unsigned int dof = i;
17023
// Generate scalings
17024
const double scalings_y_0 = 1;
17025
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
17026
const double scalings_z_0 = 1;
17027
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
17029
// Compute psitilde_a
17030
const double psitilde_a_0 = 1;
17031
const double psitilde_a_1 = x;
17033
// Compute psitilde_bs
17034
const double psitilde_bs_0_0 = 1;
17035
const double psitilde_bs_0_1 = 1.5*y + 0.5;
17036
const double psitilde_bs_1_0 = 1;
17038
// Compute psitilde_cs
17039
const double psitilde_cs_00_0 = 1;
17040
const double psitilde_cs_00_1 = 2*z + 1;
17041
const double psitilde_cs_01_0 = 1;
17042
const double psitilde_cs_10_0 = 1;
17044
// Compute basisvalues
17045
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
17046
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
17047
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
17048
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
17050
// Table(s) of coefficients
17051
static const double coefficients0[4][4] = \
17052
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
17053
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
17054
{0.288675135, 0, 0.210818511, -0.0745355992},
17055
{0.288675135, 0, 0, 0.223606798}};
17057
// Interesting (new) part
17058
// Tables of derivatives of the polynomial base (transpose)
17059
static const double dmats0[4][4] = \
17061
{6.32455532, 0, 0, 0},
17065
static const double dmats1[4][4] = \
17067
{3.16227766, 0, 0, 0},
17068
{5.47722558, 0, 0, 0},
17071
static const double dmats2[4][4] = \
17073
{3.16227766, 0, 0, 0},
17074
{1.82574186, 0, 0, 0},
17075
{5.16397779, 0, 0, 0}};
17077
// Compute reference derivatives
17078
// Declare pointer to array of derivatives on FIAT element
17079
double *derivatives = new double [num_derivatives];
17081
// Declare coefficients
17082
double coeff0_0 = 0;
17083
double coeff0_1 = 0;
17084
double coeff0_2 = 0;
17085
double coeff0_3 = 0;
17087
// Declare new coefficients
17088
double new_coeff0_0 = 0;
17089
double new_coeff0_1 = 0;
17090
double new_coeff0_2 = 0;
17091
double new_coeff0_3 = 0;
17093
// Loop possible derivatives
17094
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
17096
// Get values from coefficients array
17097
new_coeff0_0 = coefficients0[dof][0];
17098
new_coeff0_1 = coefficients0[dof][1];
17099
new_coeff0_2 = coefficients0[dof][2];
17100
new_coeff0_3 = coefficients0[dof][3];
17102
// Loop derivative order
17103
for (unsigned int j = 0; j < n; j++)
17105
// Update old coefficients
17106
coeff0_0 = new_coeff0_0;
17107
coeff0_1 = new_coeff0_1;
17108
coeff0_2 = new_coeff0_2;
17109
coeff0_3 = new_coeff0_3;
17111
if(combinations[deriv_num][j] == 0)
17113
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
17114
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
17115
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
17116
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
17118
if(combinations[deriv_num][j] == 1)
17120
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
17121
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
17122
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
17123
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
17125
if(combinations[deriv_num][j] == 2)
17127
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
17128
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
17129
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
17130
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
17134
// Compute derivatives on reference element as dot product of coefficients and basisvalues
17135
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
17138
// Transform derivatives back to physical element
17139
for (unsigned int row = 0; row < num_derivatives; row++)
17141
for (unsigned int col = 0; col < num_derivatives; col++)
17143
values[row] += transform[row][col]*derivatives[col];
17146
// Delete pointer to array of derivatives on FIAT element
17147
delete [] derivatives;
17149
// Delete pointer to array of combinations of derivatives and transform
17150
for (unsigned int row = 0; row < num_derivatives; row++)
17152
delete [] combinations[row];
17153
delete [] transform[row];
17156
delete [] combinations;
17157
delete [] transform;
17160
/// Evaluate order n derivatives of all basis functions at given point in cell
17161
virtual void evaluate_basis_derivatives_all(unsigned int n,
17163
const double* coordinates,
17164
const ufc::cell& c) const
17166
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
17169
/// Evaluate linear functional for dof i on the function f
17170
virtual double evaluate_dof(unsigned int i,
17171
const ufc::function& f,
17172
const ufc::cell& c) const
17174
// The reference points, direction and weights:
17175
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
17176
static const double W[4][1] = {{1}, {1}, {1}, {1}};
17177
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
17179
const double * const * x = c.coordinates;
17180
double result = 0.0;
17181
// Iterate over the points:
17182
// Evaluate basis functions for affine mapping
17183
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
17184
const double w1 = X[i][0][0];
17185
const double w2 = X[i][0][1];
17186
const double w3 = X[i][0][2];
17188
// Compute affine mapping y = F(X)
17190
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
17191
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
17192
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
17194
// Evaluate function at physical points
17196
f.evaluate(values, y, c);
17198
// Map function values using appropriate mapping
17199
// Affine map: Do nothing
17201
// Note that we do not map the weights (yet).
17203
// Take directional components
17204
for(int k = 0; k < 1; k++)
17205
result += values[k]*D[i][0][k];
17206
// Multiply by weights
17212
/// Evaluate linear functionals for all dofs on the function f
17213
virtual void evaluate_dofs(double* values,
17214
const ufc::function& f,
17215
const ufc::cell& c) const
17217
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
17220
/// Interpolate vertex values from dof values
17221
virtual void interpolate_vertex_values(double* vertex_values,
17222
const double* dof_values,
17223
const ufc::cell& c) const
17225
// Evaluate at vertices and use affine mapping
17226
vertex_values[0] = dof_values[0];
17227
vertex_values[1] = dof_values[1];
17228
vertex_values[2] = dof_values[2];
17229
vertex_values[3] = dof_values[3];
17232
/// Return the number of sub elements (for a mixed element)
17233
virtual unsigned int num_sub_elements() const
17238
/// Create a new finite element for sub element i (for a mixed element)
17239
virtual ufc::finite_element* create_sub_element(unsigned int i) const
17241
return new hyperelasticity_1_finite_element_2_0();
17246
/// This class defines the interface for a finite element.
17248
class hyperelasticity_1_finite_element_2_1: public ufc::finite_element
17253
hyperelasticity_1_finite_element_2_1() : ufc::finite_element()
17259
virtual ~hyperelasticity_1_finite_element_2_1()
17264
/// Return a string identifying the finite element
17265
virtual const char* signature() const
17267
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
17270
/// Return the cell shape
17271
virtual ufc::shape cell_shape() const
17273
return ufc::tetrahedron;
17276
/// Return the dimension of the finite element function space
17277
virtual unsigned int space_dimension() const
17282
/// Return the rank of the value space
17283
virtual unsigned int value_rank() const
17288
/// Return the dimension of the value space for axis i
17289
virtual unsigned int value_dimension(unsigned int i) const
17294
/// Evaluate basis function i at given point in cell
17295
virtual void evaluate_basis(unsigned int i,
17297
const double* coordinates,
17298
const ufc::cell& c) const
17300
// Extract vertex coordinates
17301
const double * const * element_coordinates = c.coordinates;
17303
// Compute Jacobian of affine map from reference cell
17304
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
17305
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
17306
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
17307
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
17308
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
17309
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
17310
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
17311
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
17312
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
17314
// Compute sub determinants
17315
const double d00 = J_11*J_22 - J_12*J_21;
17316
const double d01 = J_12*J_20 - J_10*J_22;
17317
const double d02 = J_10*J_21 - J_11*J_20;
17319
const double d10 = J_02*J_21 - J_01*J_22;
17320
const double d11 = J_00*J_22 - J_02*J_20;
17321
const double d12 = J_01*J_20 - J_00*J_21;
17323
const double d20 = J_01*J_12 - J_02*J_11;
17324
const double d21 = J_02*J_10 - J_00*J_12;
17325
const double d22 = J_00*J_11 - J_01*J_10;
17327
// Compute determinant of Jacobian
17328
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
17330
// Compute inverse of Jacobian
17332
// Compute constants
17333
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
17334
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
17335
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
17337
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
17338
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
17339
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
17341
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
17342
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
17343
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
17345
// Get coordinates and map to the UFC reference element
17346
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
17347
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
17348
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
17350
// Map coordinates to the reference cube
17351
if (std::abs(y + z - 1.0) < 1e-08)
17354
x = -2.0 * x/(y + z - 1.0) - 1.0;
17355
if (std::abs(z - 1.0) < 1e-08)
17358
y = 2.0 * y/(1.0 - z) - 1.0;
17364
// Map degree of freedom to element degree of freedom
17365
const unsigned int dof = i;
17367
// Generate scalings
17368
const double scalings_y_0 = 1;
17369
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
17370
const double scalings_z_0 = 1;
17371
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
17373
// Compute psitilde_a
17374
const double psitilde_a_0 = 1;
17375
const double psitilde_a_1 = x;
17377
// Compute psitilde_bs
17378
const double psitilde_bs_0_0 = 1;
17379
const double psitilde_bs_0_1 = 1.5*y + 0.5;
17380
const double psitilde_bs_1_0 = 1;
17382
// Compute psitilde_cs
17383
const double psitilde_cs_00_0 = 1;
17384
const double psitilde_cs_00_1 = 2*z + 1;
17385
const double psitilde_cs_01_0 = 1;
17386
const double psitilde_cs_10_0 = 1;
17388
// Compute basisvalues
17389
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
17390
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
17391
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
17392
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
17394
// Table(s) of coefficients
17395
static const double coefficients0[4][4] = \
17396
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
17397
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
17398
{0.288675135, 0, 0.210818511, -0.0745355992},
17399
{0.288675135, 0, 0, 0.223606798}};
17401
// Extract relevant coefficients
17402
const double coeff0_0 = coefficients0[dof][0];
17403
const double coeff0_1 = coefficients0[dof][1];
17404
const double coeff0_2 = coefficients0[dof][2];
17405
const double coeff0_3 = coefficients0[dof][3];
17407
// Compute value(s)
17408
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
17411
/// Evaluate all basis functions at given point in cell
17412
virtual void evaluate_basis_all(double* values,
17413
const double* coordinates,
17414
const ufc::cell& c) const
17416
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
17419
/// Evaluate order n derivatives of basis function i at given point in cell
17420
virtual void evaluate_basis_derivatives(unsigned int i,
17423
const double* coordinates,
17424
const ufc::cell& c) const
17426
// Extract vertex coordinates
17427
const double * const * element_coordinates = c.coordinates;
17429
// Compute Jacobian of affine map from reference cell
17430
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
17431
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
17432
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
17433
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
17434
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
17435
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
17436
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
17437
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
17438
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
17440
// Compute sub determinants
17441
const double d00 = J_11*J_22 - J_12*J_21;
17442
const double d01 = J_12*J_20 - J_10*J_22;
17443
const double d02 = J_10*J_21 - J_11*J_20;
17445
const double d10 = J_02*J_21 - J_01*J_22;
17446
const double d11 = J_00*J_22 - J_02*J_20;
17447
const double d12 = J_01*J_20 - J_00*J_21;
17449
const double d20 = J_01*J_12 - J_02*J_11;
17450
const double d21 = J_02*J_10 - J_00*J_12;
17451
const double d22 = J_00*J_11 - J_01*J_10;
17453
// Compute determinant of Jacobian
17454
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
17456
// Compute inverse of Jacobian
17458
// Compute constants
17459
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
17460
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
17461
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
17463
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
17464
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
17465
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
17467
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
17468
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
17469
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
17471
// Get coordinates and map to the UFC reference element
17472
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
17473
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
17474
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
17476
// Map coordinates to the reference cube
17477
if (std::abs(y + z - 1.0) < 1e-08)
17480
x = -2.0 * x/(y + z - 1.0) - 1.0;
17481
if (std::abs(z - 1.0) < 1e-08)
17484
y = 2.0 * y/(1.0 - z) - 1.0;
17487
// Compute number of derivatives
17488
unsigned int num_derivatives = 1;
17490
for (unsigned int j = 0; j < n; j++)
17491
num_derivatives *= 3;
17494
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
17495
unsigned int **combinations = new unsigned int *[num_derivatives];
17497
for (unsigned int j = 0; j < num_derivatives; j++)
17499
combinations[j] = new unsigned int [n];
17500
for (unsigned int k = 0; k < n; k++)
17501
combinations[j][k] = 0;
17504
// Generate combinations of derivatives
17505
for (unsigned int row = 1; row < num_derivatives; row++)
17507
for (unsigned int num = 0; num < row; num++)
17509
for (unsigned int col = n-1; col+1 > 0; col--)
17511
if (combinations[row][col] + 1 > 2)
17512
combinations[row][col] = 0;
17515
combinations[row][col] += 1;
17522
// Compute inverse of Jacobian
17523
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
17525
// Declare transformation matrix
17526
// Declare pointer to two dimensional array and initialise
17527
double **transform = new double *[num_derivatives];
17529
for (unsigned int j = 0; j < num_derivatives; j++)
17531
transform[j] = new double [num_derivatives];
17532
for (unsigned int k = 0; k < num_derivatives; k++)
17533
transform[j][k] = 1;
17536
// Construct transformation matrix
17537
for (unsigned int row = 0; row < num_derivatives; row++)
17539
for (unsigned int col = 0; col < num_derivatives; col++)
17541
for (unsigned int k = 0; k < n; k++)
17542
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
17547
for (unsigned int j = 0; j < 1*num_derivatives; j++)
17550
// Map degree of freedom to element degree of freedom
17551
const unsigned int dof = i;
17553
// Generate scalings
17554
const double scalings_y_0 = 1;
17555
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
17556
const double scalings_z_0 = 1;
17557
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
17559
// Compute psitilde_a
17560
const double psitilde_a_0 = 1;
17561
const double psitilde_a_1 = x;
17563
// Compute psitilde_bs
17564
const double psitilde_bs_0_0 = 1;
17565
const double psitilde_bs_0_1 = 1.5*y + 0.5;
17566
const double psitilde_bs_1_0 = 1;
17568
// Compute psitilde_cs
17569
const double psitilde_cs_00_0 = 1;
17570
const double psitilde_cs_00_1 = 2*z + 1;
17571
const double psitilde_cs_01_0 = 1;
17572
const double psitilde_cs_10_0 = 1;
17574
// Compute basisvalues
17575
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
17576
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
17577
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
17578
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
17580
// Table(s) of coefficients
17581
static const double coefficients0[4][4] = \
17582
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
17583
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
17584
{0.288675135, 0, 0.210818511, -0.0745355992},
17585
{0.288675135, 0, 0, 0.223606798}};
17587
// Interesting (new) part
17588
// Tables of derivatives of the polynomial base (transpose)
17589
static const double dmats0[4][4] = \
17591
{6.32455532, 0, 0, 0},
17595
static const double dmats1[4][4] = \
17597
{3.16227766, 0, 0, 0},
17598
{5.47722558, 0, 0, 0},
17601
static const double dmats2[4][4] = \
17603
{3.16227766, 0, 0, 0},
17604
{1.82574186, 0, 0, 0},
17605
{5.16397779, 0, 0, 0}};
17607
// Compute reference derivatives
17608
// Declare pointer to array of derivatives on FIAT element
17609
double *derivatives = new double [num_derivatives];
17611
// Declare coefficients
17612
double coeff0_0 = 0;
17613
double coeff0_1 = 0;
17614
double coeff0_2 = 0;
17615
double coeff0_3 = 0;
17617
// Declare new coefficients
17618
double new_coeff0_0 = 0;
17619
double new_coeff0_1 = 0;
17620
double new_coeff0_2 = 0;
17621
double new_coeff0_3 = 0;
17623
// Loop possible derivatives
17624
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
17626
// Get values from coefficients array
17627
new_coeff0_0 = coefficients0[dof][0];
17628
new_coeff0_1 = coefficients0[dof][1];
17629
new_coeff0_2 = coefficients0[dof][2];
17630
new_coeff0_3 = coefficients0[dof][3];
17632
// Loop derivative order
17633
for (unsigned int j = 0; j < n; j++)
17635
// Update old coefficients
17636
coeff0_0 = new_coeff0_0;
17637
coeff0_1 = new_coeff0_1;
17638
coeff0_2 = new_coeff0_2;
17639
coeff0_3 = new_coeff0_3;
17641
if(combinations[deriv_num][j] == 0)
17643
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
17644
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
17645
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
17646
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
17648
if(combinations[deriv_num][j] == 1)
17650
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
17651
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
17652
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
17653
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
17655
if(combinations[deriv_num][j] == 2)
17657
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
17658
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
17659
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
17660
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
17664
// Compute derivatives on reference element as dot product of coefficients and basisvalues
17665
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
17668
// Transform derivatives back to physical element
17669
for (unsigned int row = 0; row < num_derivatives; row++)
17671
for (unsigned int col = 0; col < num_derivatives; col++)
17673
values[row] += transform[row][col]*derivatives[col];
17676
// Delete pointer to array of derivatives on FIAT element
17677
delete [] derivatives;
17679
// Delete pointer to array of combinations of derivatives and transform
17680
for (unsigned int row = 0; row < num_derivatives; row++)
17682
delete [] combinations[row];
17683
delete [] transform[row];
17686
delete [] combinations;
17687
delete [] transform;
17690
/// Evaluate order n derivatives of all basis functions at given point in cell
17691
virtual void evaluate_basis_derivatives_all(unsigned int n,
17693
const double* coordinates,
17694
const ufc::cell& c) const
17696
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
17699
/// Evaluate linear functional for dof i on the function f
17700
virtual double evaluate_dof(unsigned int i,
17701
const ufc::function& f,
17702
const ufc::cell& c) const
17704
// The reference points, direction and weights:
17705
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
17706
static const double W[4][1] = {{1}, {1}, {1}, {1}};
17707
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
17709
const double * const * x = c.coordinates;
17710
double result = 0.0;
17711
// Iterate over the points:
17712
// Evaluate basis functions for affine mapping
17713
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
17714
const double w1 = X[i][0][0];
17715
const double w2 = X[i][0][1];
17716
const double w3 = X[i][0][2];
17718
// Compute affine mapping y = F(X)
17720
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
17721
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
17722
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
17724
// Evaluate function at physical points
17726
f.evaluate(values, y, c);
17728
// Map function values using appropriate mapping
17729
// Affine map: Do nothing
17731
// Note that we do not map the weights (yet).
17733
// Take directional components
17734
for(int k = 0; k < 1; k++)
17735
result += values[k]*D[i][0][k];
17736
// Multiply by weights
17742
/// Evaluate linear functionals for all dofs on the function f
17743
virtual void evaluate_dofs(double* values,
17744
const ufc::function& f,
17745
const ufc::cell& c) const
17747
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
17750
/// Interpolate vertex values from dof values
17751
virtual void interpolate_vertex_values(double* vertex_values,
17752
const double* dof_values,
17753
const ufc::cell& c) const
17755
// Evaluate at vertices and use affine mapping
17756
vertex_values[0] = dof_values[0];
17757
vertex_values[1] = dof_values[1];
17758
vertex_values[2] = dof_values[2];
17759
vertex_values[3] = dof_values[3];
17762
/// Return the number of sub elements (for a mixed element)
17763
virtual unsigned int num_sub_elements() const
17768
/// Create a new finite element for sub element i (for a mixed element)
17769
virtual ufc::finite_element* create_sub_element(unsigned int i) const
17771
return new hyperelasticity_1_finite_element_2_1();
17776
/// This class defines the interface for a finite element.
17778
class hyperelasticity_1_finite_element_2_2: public ufc::finite_element
17783
hyperelasticity_1_finite_element_2_2() : ufc::finite_element()
17789
virtual ~hyperelasticity_1_finite_element_2_2()
17794
/// Return a string identifying the finite element
17795
virtual const char* signature() const
17797
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
17800
/// Return the cell shape
17801
virtual ufc::shape cell_shape() const
17803
return ufc::tetrahedron;
17806
/// Return the dimension of the finite element function space
17807
virtual unsigned int space_dimension() const
17812
/// Return the rank of the value space
17813
virtual unsigned int value_rank() const
17818
/// Return the dimension of the value space for axis i
17819
virtual unsigned int value_dimension(unsigned int i) const
17824
/// Evaluate basis function i at given point in cell
17825
virtual void evaluate_basis(unsigned int i,
17827
const double* coordinates,
17828
const ufc::cell& c) const
17830
// Extract vertex coordinates
17831
const double * const * element_coordinates = c.coordinates;
17833
// Compute Jacobian of affine map from reference cell
17834
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
17835
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
17836
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
17837
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
17838
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
17839
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
17840
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
17841
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
17842
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
17844
// Compute sub determinants
17845
const double d00 = J_11*J_22 - J_12*J_21;
17846
const double d01 = J_12*J_20 - J_10*J_22;
17847
const double d02 = J_10*J_21 - J_11*J_20;
17849
const double d10 = J_02*J_21 - J_01*J_22;
17850
const double d11 = J_00*J_22 - J_02*J_20;
17851
const double d12 = J_01*J_20 - J_00*J_21;
17853
const double d20 = J_01*J_12 - J_02*J_11;
17854
const double d21 = J_02*J_10 - J_00*J_12;
17855
const double d22 = J_00*J_11 - J_01*J_10;
17857
// Compute determinant of Jacobian
17858
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
17860
// Compute inverse of Jacobian
17862
// Compute constants
17863
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
17864
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
17865
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
17867
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
17868
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
17869
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
17871
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
17872
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
17873
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
17875
// Get coordinates and map to the UFC reference element
17876
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
17877
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
17878
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
17880
// Map coordinates to the reference cube
17881
if (std::abs(y + z - 1.0) < 1e-08)
17884
x = -2.0 * x/(y + z - 1.0) - 1.0;
17885
if (std::abs(z - 1.0) < 1e-08)
17888
y = 2.0 * y/(1.0 - z) - 1.0;
17894
// Map degree of freedom to element degree of freedom
17895
const unsigned int dof = i;
17897
// Generate scalings
17898
const double scalings_y_0 = 1;
17899
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
17900
const double scalings_z_0 = 1;
17901
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
17903
// Compute psitilde_a
17904
const double psitilde_a_0 = 1;
17905
const double psitilde_a_1 = x;
17907
// Compute psitilde_bs
17908
const double psitilde_bs_0_0 = 1;
17909
const double psitilde_bs_0_1 = 1.5*y + 0.5;
17910
const double psitilde_bs_1_0 = 1;
17912
// Compute psitilde_cs
17913
const double psitilde_cs_00_0 = 1;
17914
const double psitilde_cs_00_1 = 2*z + 1;
17915
const double psitilde_cs_01_0 = 1;
17916
const double psitilde_cs_10_0 = 1;
17918
// Compute basisvalues
17919
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
17920
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
17921
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
17922
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
17924
// Table(s) of coefficients
17925
static const double coefficients0[4][4] = \
17926
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
17927
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
17928
{0.288675135, 0, 0.210818511, -0.0745355992},
17929
{0.288675135, 0, 0, 0.223606798}};
17931
// Extract relevant coefficients
17932
const double coeff0_0 = coefficients0[dof][0];
17933
const double coeff0_1 = coefficients0[dof][1];
17934
const double coeff0_2 = coefficients0[dof][2];
17935
const double coeff0_3 = coefficients0[dof][3];
17937
// Compute value(s)
17938
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
17941
/// Evaluate all basis functions at given point in cell
17942
virtual void evaluate_basis_all(double* values,
17943
const double* coordinates,
17944
const ufc::cell& c) const
17946
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
17949
/// Evaluate order n derivatives of basis function i at given point in cell
17950
virtual void evaluate_basis_derivatives(unsigned int i,
17953
const double* coordinates,
17954
const ufc::cell& c) const
17956
// Extract vertex coordinates
17957
const double * const * element_coordinates = c.coordinates;
17959
// Compute Jacobian of affine map from reference cell
17960
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
17961
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
17962
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
17963
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
17964
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
17965
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
17966
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
17967
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
17968
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
17970
// Compute sub determinants
17971
const double d00 = J_11*J_22 - J_12*J_21;
17972
const double d01 = J_12*J_20 - J_10*J_22;
17973
const double d02 = J_10*J_21 - J_11*J_20;
17975
const double d10 = J_02*J_21 - J_01*J_22;
17976
const double d11 = J_00*J_22 - J_02*J_20;
17977
const double d12 = J_01*J_20 - J_00*J_21;
17979
const double d20 = J_01*J_12 - J_02*J_11;
17980
const double d21 = J_02*J_10 - J_00*J_12;
17981
const double d22 = J_00*J_11 - J_01*J_10;
17983
// Compute determinant of Jacobian
17984
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
17986
// Compute inverse of Jacobian
17988
// Compute constants
17989
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
17990
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
17991
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
17993
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
17994
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
17995
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
17997
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
17998
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
17999
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
18001
// Get coordinates and map to the UFC reference element
18002
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
18003
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
18004
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
18006
// Map coordinates to the reference cube
18007
if (std::abs(y + z - 1.0) < 1e-08)
18010
x = -2.0 * x/(y + z - 1.0) - 1.0;
18011
if (std::abs(z - 1.0) < 1e-08)
18014
y = 2.0 * y/(1.0 - z) - 1.0;
18017
// Compute number of derivatives
18018
unsigned int num_derivatives = 1;
18020
for (unsigned int j = 0; j < n; j++)
18021
num_derivatives *= 3;
18024
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
18025
unsigned int **combinations = new unsigned int *[num_derivatives];
18027
for (unsigned int j = 0; j < num_derivatives; j++)
18029
combinations[j] = new unsigned int [n];
18030
for (unsigned int k = 0; k < n; k++)
18031
combinations[j][k] = 0;
18034
// Generate combinations of derivatives
18035
for (unsigned int row = 1; row < num_derivatives; row++)
18037
for (unsigned int num = 0; num < row; num++)
18039
for (unsigned int col = n-1; col+1 > 0; col--)
18041
if (combinations[row][col] + 1 > 2)
18042
combinations[row][col] = 0;
18045
combinations[row][col] += 1;
18052
// Compute inverse of Jacobian
18053
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
18055
// Declare transformation matrix
18056
// Declare pointer to two dimensional array and initialise
18057
double **transform = new double *[num_derivatives];
18059
for (unsigned int j = 0; j < num_derivatives; j++)
18061
transform[j] = new double [num_derivatives];
18062
for (unsigned int k = 0; k < num_derivatives; k++)
18063
transform[j][k] = 1;
18066
// Construct transformation matrix
18067
for (unsigned int row = 0; row < num_derivatives; row++)
18069
for (unsigned int col = 0; col < num_derivatives; col++)
18071
for (unsigned int k = 0; k < n; k++)
18072
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
18077
for (unsigned int j = 0; j < 1*num_derivatives; j++)
18080
// Map degree of freedom to element degree of freedom
18081
const unsigned int dof = i;
18083
// Generate scalings
18084
const double scalings_y_0 = 1;
18085
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
18086
const double scalings_z_0 = 1;
18087
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
18089
// Compute psitilde_a
18090
const double psitilde_a_0 = 1;
18091
const double psitilde_a_1 = x;
18093
// Compute psitilde_bs
18094
const double psitilde_bs_0_0 = 1;
18095
const double psitilde_bs_0_1 = 1.5*y + 0.5;
18096
const double psitilde_bs_1_0 = 1;
18098
// Compute psitilde_cs
18099
const double psitilde_cs_00_0 = 1;
18100
const double psitilde_cs_00_1 = 2*z + 1;
18101
const double psitilde_cs_01_0 = 1;
18102
const double psitilde_cs_10_0 = 1;
18104
// Compute basisvalues
18105
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
18106
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
18107
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
18108
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
18110
// Table(s) of coefficients
18111
static const double coefficients0[4][4] = \
18112
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
18113
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
18114
{0.288675135, 0, 0.210818511, -0.0745355992},
18115
{0.288675135, 0, 0, 0.223606798}};
18117
// Interesting (new) part
18118
// Tables of derivatives of the polynomial base (transpose)
18119
static const double dmats0[4][4] = \
18121
{6.32455532, 0, 0, 0},
18125
static const double dmats1[4][4] = \
18127
{3.16227766, 0, 0, 0},
18128
{5.47722558, 0, 0, 0},
18131
static const double dmats2[4][4] = \
18133
{3.16227766, 0, 0, 0},
18134
{1.82574186, 0, 0, 0},
18135
{5.16397779, 0, 0, 0}};
18137
// Compute reference derivatives
18138
// Declare pointer to array of derivatives on FIAT element
18139
double *derivatives = new double [num_derivatives];
18141
// Declare coefficients
18142
double coeff0_0 = 0;
18143
double coeff0_1 = 0;
18144
double coeff0_2 = 0;
18145
double coeff0_3 = 0;
18147
// Declare new coefficients
18148
double new_coeff0_0 = 0;
18149
double new_coeff0_1 = 0;
18150
double new_coeff0_2 = 0;
18151
double new_coeff0_3 = 0;
18153
// Loop possible derivatives
18154
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
18156
// Get values from coefficients array
18157
new_coeff0_0 = coefficients0[dof][0];
18158
new_coeff0_1 = coefficients0[dof][1];
18159
new_coeff0_2 = coefficients0[dof][2];
18160
new_coeff0_3 = coefficients0[dof][3];
18162
// Loop derivative order
18163
for (unsigned int j = 0; j < n; j++)
18165
// Update old coefficients
18166
coeff0_0 = new_coeff0_0;
18167
coeff0_1 = new_coeff0_1;
18168
coeff0_2 = new_coeff0_2;
18169
coeff0_3 = new_coeff0_3;
18171
if(combinations[deriv_num][j] == 0)
18173
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
18174
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
18175
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
18176
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
18178
if(combinations[deriv_num][j] == 1)
18180
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
18181
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
18182
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
18183
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
18185
if(combinations[deriv_num][j] == 2)
18187
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
18188
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
18189
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
18190
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
18194
// Compute derivatives on reference element as dot product of coefficients and basisvalues
18195
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
18198
// Transform derivatives back to physical element
18199
for (unsigned int row = 0; row < num_derivatives; row++)
18201
for (unsigned int col = 0; col < num_derivatives; col++)
18203
values[row] += transform[row][col]*derivatives[col];
18206
// Delete pointer to array of derivatives on FIAT element
18207
delete [] derivatives;
18209
// Delete pointer to array of combinations of derivatives and transform
18210
for (unsigned int row = 0; row < num_derivatives; row++)
18212
delete [] combinations[row];
18213
delete [] transform[row];
18216
delete [] combinations;
18217
delete [] transform;
18220
/// Evaluate order n derivatives of all basis functions at given point in cell
18221
virtual void evaluate_basis_derivatives_all(unsigned int n,
18223
const double* coordinates,
18224
const ufc::cell& c) const
18226
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
18229
/// Evaluate linear functional for dof i on the function f
18230
virtual double evaluate_dof(unsigned int i,
18231
const ufc::function& f,
18232
const ufc::cell& c) const
18234
// The reference points, direction and weights:
18235
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
18236
static const double W[4][1] = {{1}, {1}, {1}, {1}};
18237
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
18239
const double * const * x = c.coordinates;
18240
double result = 0.0;
18241
// Iterate over the points:
18242
// Evaluate basis functions for affine mapping
18243
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
18244
const double w1 = X[i][0][0];
18245
const double w2 = X[i][0][1];
18246
const double w3 = X[i][0][2];
18248
// Compute affine mapping y = F(X)
18250
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
18251
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
18252
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
18254
// Evaluate function at physical points
18256
f.evaluate(values, y, c);
18258
// Map function values using appropriate mapping
18259
// Affine map: Do nothing
18261
// Note that we do not map the weights (yet).
18263
// Take directional components
18264
for(int k = 0; k < 1; k++)
18265
result += values[k]*D[i][0][k];
18266
// Multiply by weights
18272
/// Evaluate linear functionals for all dofs on the function f
18273
virtual void evaluate_dofs(double* values,
18274
const ufc::function& f,
18275
const ufc::cell& c) const
18277
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
18280
/// Interpolate vertex values from dof values
18281
virtual void interpolate_vertex_values(double* vertex_values,
18282
const double* dof_values,
18283
const ufc::cell& c) const
18285
// Evaluate at vertices and use affine mapping
18286
vertex_values[0] = dof_values[0];
18287
vertex_values[1] = dof_values[1];
18288
vertex_values[2] = dof_values[2];
18289
vertex_values[3] = dof_values[3];
18292
/// Return the number of sub elements (for a mixed element)
18293
virtual unsigned int num_sub_elements() const
18298
/// Create a new finite element for sub element i (for a mixed element)
18299
virtual ufc::finite_element* create_sub_element(unsigned int i) const
18301
return new hyperelasticity_1_finite_element_2_2();
18306
/// This class defines the interface for a finite element.
18308
class hyperelasticity_1_finite_element_2: public ufc::finite_element
18313
hyperelasticity_1_finite_element_2() : ufc::finite_element()
18319
virtual ~hyperelasticity_1_finite_element_2()
18324
/// Return a string identifying the finite element
18325
virtual const char* signature() const
18327
return "VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
18330
/// Return the cell shape
18331
virtual ufc::shape cell_shape() const
18333
return ufc::tetrahedron;
18336
/// Return the dimension of the finite element function space
18337
virtual unsigned int space_dimension() const
18342
/// Return the rank of the value space
18343
virtual unsigned int value_rank() const
18348
/// Return the dimension of the value space for axis i
18349
virtual unsigned int value_dimension(unsigned int i) const
18354
/// Evaluate basis function i at given point in cell
18355
virtual void evaluate_basis(unsigned int i,
18357
const double* coordinates,
18358
const ufc::cell& c) const
18360
// Extract vertex coordinates
18361
const double * const * element_coordinates = c.coordinates;
18363
// Compute Jacobian of affine map from reference cell
18364
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
18365
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
18366
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
18367
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
18368
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
18369
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
18370
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
18371
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
18372
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
18374
// Compute sub determinants
18375
const double d00 = J_11*J_22 - J_12*J_21;
18376
const double d01 = J_12*J_20 - J_10*J_22;
18377
const double d02 = J_10*J_21 - J_11*J_20;
18379
const double d10 = J_02*J_21 - J_01*J_22;
18380
const double d11 = J_00*J_22 - J_02*J_20;
18381
const double d12 = J_01*J_20 - J_00*J_21;
18383
const double d20 = J_01*J_12 - J_02*J_11;
18384
const double d21 = J_02*J_10 - J_00*J_12;
18385
const double d22 = J_00*J_11 - J_01*J_10;
18387
// Compute determinant of Jacobian
18388
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
18390
// Compute inverse of Jacobian
18392
// Compute constants
18393
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
18394
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
18395
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
18397
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
18398
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
18399
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
18401
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
18402
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
18403
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
18405
// Get coordinates and map to the UFC reference element
18406
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
18407
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
18408
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
18410
// Map coordinates to the reference cube
18411
if (std::abs(y + z - 1.0) < 1e-08)
18414
x = -2.0 * x/(y + z - 1.0) - 1.0;
18415
if (std::abs(z - 1.0) < 1e-08)
18418
y = 2.0 * y/(1.0 - z) - 1.0;
18426
if (0 <= i && i <= 3)
18428
// Map degree of freedom to element degree of freedom
18429
const unsigned int dof = i;
18431
// Generate scalings
18432
const double scalings_y_0 = 1;
18433
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
18434
const double scalings_z_0 = 1;
18435
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
18437
// Compute psitilde_a
18438
const double psitilde_a_0 = 1;
18439
const double psitilde_a_1 = x;
18441
// Compute psitilde_bs
18442
const double psitilde_bs_0_0 = 1;
18443
const double psitilde_bs_0_1 = 1.5*y + 0.5;
18444
const double psitilde_bs_1_0 = 1;
18446
// Compute psitilde_cs
18447
const double psitilde_cs_00_0 = 1;
18448
const double psitilde_cs_00_1 = 2*z + 1;
18449
const double psitilde_cs_01_0 = 1;
18450
const double psitilde_cs_10_0 = 1;
18452
// Compute basisvalues
18453
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
18454
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
18455
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
18456
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
18458
// Table(s) of coefficients
18459
static const double coefficients0[4][4] = \
18460
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
18461
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
18462
{0.288675135, 0, 0.210818511, -0.0745355992},
18463
{0.288675135, 0, 0, 0.223606798}};
18465
// Extract relevant coefficients
18466
const double coeff0_0 = coefficients0[dof][0];
18467
const double coeff0_1 = coefficients0[dof][1];
18468
const double coeff0_2 = coefficients0[dof][2];
18469
const double coeff0_3 = coefficients0[dof][3];
18471
// Compute value(s)
18472
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
18475
if (4 <= i && i <= 7)
18477
// Map degree of freedom to element degree of freedom
18478
const unsigned int dof = i - 4;
18480
// Generate scalings
18481
const double scalings_y_0 = 1;
18482
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
18483
const double scalings_z_0 = 1;
18484
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
18486
// Compute psitilde_a
18487
const double psitilde_a_0 = 1;
18488
const double psitilde_a_1 = x;
18490
// Compute psitilde_bs
18491
const double psitilde_bs_0_0 = 1;
18492
const double psitilde_bs_0_1 = 1.5*y + 0.5;
18493
const double psitilde_bs_1_0 = 1;
18495
// Compute psitilde_cs
18496
const double psitilde_cs_00_0 = 1;
18497
const double psitilde_cs_00_1 = 2*z + 1;
18498
const double psitilde_cs_01_0 = 1;
18499
const double psitilde_cs_10_0 = 1;
18501
// Compute basisvalues
18502
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
18503
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
18504
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
18505
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
18507
// Table(s) of coefficients
18508
static const double coefficients0[4][4] = \
18509
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
18510
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
18511
{0.288675135, 0, 0.210818511, -0.0745355992},
18512
{0.288675135, 0, 0, 0.223606798}};
18514
// Extract relevant coefficients
18515
const double coeff0_0 = coefficients0[dof][0];
18516
const double coeff0_1 = coefficients0[dof][1];
18517
const double coeff0_2 = coefficients0[dof][2];
18518
const double coeff0_3 = coefficients0[dof][3];
18520
// Compute value(s)
18521
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
18524
if (8 <= i && i <= 11)
18526
// Map degree of freedom to element degree of freedom
18527
const unsigned int dof = i - 8;
18529
// Generate scalings
18530
const double scalings_y_0 = 1;
18531
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
18532
const double scalings_z_0 = 1;
18533
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
18535
// Compute psitilde_a
18536
const double psitilde_a_0 = 1;
18537
const double psitilde_a_1 = x;
18539
// Compute psitilde_bs
18540
const double psitilde_bs_0_0 = 1;
18541
const double psitilde_bs_0_1 = 1.5*y + 0.5;
18542
const double psitilde_bs_1_0 = 1;
18544
// Compute psitilde_cs
18545
const double psitilde_cs_00_0 = 1;
18546
const double psitilde_cs_00_1 = 2*z + 1;
18547
const double psitilde_cs_01_0 = 1;
18548
const double psitilde_cs_10_0 = 1;
18550
// Compute basisvalues
18551
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
18552
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
18553
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
18554
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
18556
// Table(s) of coefficients
18557
static const double coefficients0[4][4] = \
18558
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
18559
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
18560
{0.288675135, 0, 0.210818511, -0.0745355992},
18561
{0.288675135, 0, 0, 0.223606798}};
18563
// Extract relevant coefficients
18564
const double coeff0_0 = coefficients0[dof][0];
18565
const double coeff0_1 = coefficients0[dof][1];
18566
const double coeff0_2 = coefficients0[dof][2];
18567
const double coeff0_3 = coefficients0[dof][3];
18569
// Compute value(s)
18570
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
18575
/// Evaluate all basis functions at given point in cell
18576
virtual void evaluate_basis_all(double* values,
18577
const double* coordinates,
18578
const ufc::cell& c) const
18580
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
18583
/// Evaluate order n derivatives of basis function i at given point in cell
18584
virtual void evaluate_basis_derivatives(unsigned int i,
18587
const double* coordinates,
18588
const ufc::cell& c) const
18590
// Extract vertex coordinates
18591
const double * const * element_coordinates = c.coordinates;
18593
// Compute Jacobian of affine map from reference cell
18594
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
18595
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
18596
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
18597
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
18598
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
18599
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
18600
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
18601
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
18602
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
18604
// Compute sub determinants
18605
const double d00 = J_11*J_22 - J_12*J_21;
18606
const double d01 = J_12*J_20 - J_10*J_22;
18607
const double d02 = J_10*J_21 - J_11*J_20;
18609
const double d10 = J_02*J_21 - J_01*J_22;
18610
const double d11 = J_00*J_22 - J_02*J_20;
18611
const double d12 = J_01*J_20 - J_00*J_21;
18613
const double d20 = J_01*J_12 - J_02*J_11;
18614
const double d21 = J_02*J_10 - J_00*J_12;
18615
const double d22 = J_00*J_11 - J_01*J_10;
18617
// Compute determinant of Jacobian
18618
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
18620
// Compute inverse of Jacobian
18622
// Compute constants
18623
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
18624
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
18625
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
18627
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
18628
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
18629
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
18631
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
18632
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
18633
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
18635
// Get coordinates and map to the UFC reference element
18636
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
18637
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
18638
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
18640
// Map coordinates to the reference cube
18641
if (std::abs(y + z - 1.0) < 1e-08)
18644
x = -2.0 * x/(y + z - 1.0) - 1.0;
18645
if (std::abs(z - 1.0) < 1e-08)
18648
y = 2.0 * y/(1.0 - z) - 1.0;
18651
// Compute number of derivatives
18652
unsigned int num_derivatives = 1;
18654
for (unsigned int j = 0; j < n; j++)
18655
num_derivatives *= 3;
18658
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
18659
unsigned int **combinations = new unsigned int *[num_derivatives];
18661
for (unsigned int j = 0; j < num_derivatives; j++)
18663
combinations[j] = new unsigned int [n];
18664
for (unsigned int k = 0; k < n; k++)
18665
combinations[j][k] = 0;
18668
// Generate combinations of derivatives
18669
for (unsigned int row = 1; row < num_derivatives; row++)
18671
for (unsigned int num = 0; num < row; num++)
18673
for (unsigned int col = n-1; col+1 > 0; col--)
18675
if (combinations[row][col] + 1 > 2)
18676
combinations[row][col] = 0;
18679
combinations[row][col] += 1;
18686
// Compute inverse of Jacobian
18687
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
18689
// Declare transformation matrix
18690
// Declare pointer to two dimensional array and initialise
18691
double **transform = new double *[num_derivatives];
18693
for (unsigned int j = 0; j < num_derivatives; j++)
18695
transform[j] = new double [num_derivatives];
18696
for (unsigned int k = 0; k < num_derivatives; k++)
18697
transform[j][k] = 1;
18700
// Construct transformation matrix
18701
for (unsigned int row = 0; row < num_derivatives; row++)
18703
for (unsigned int col = 0; col < num_derivatives; col++)
18705
for (unsigned int k = 0; k < n; k++)
18706
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
18711
for (unsigned int j = 0; j < 3*num_derivatives; j++)
18714
if (0 <= i && i <= 3)
18716
// Map degree of freedom to element degree of freedom
18717
const unsigned int dof = i;
18719
// Generate scalings
18720
const double scalings_y_0 = 1;
18721
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
18722
const double scalings_z_0 = 1;
18723
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
18725
// Compute psitilde_a
18726
const double psitilde_a_0 = 1;
18727
const double psitilde_a_1 = x;
18729
// Compute psitilde_bs
18730
const double psitilde_bs_0_0 = 1;
18731
const double psitilde_bs_0_1 = 1.5*y + 0.5;
18732
const double psitilde_bs_1_0 = 1;
18734
// Compute psitilde_cs
18735
const double psitilde_cs_00_0 = 1;
18736
const double psitilde_cs_00_1 = 2*z + 1;
18737
const double psitilde_cs_01_0 = 1;
18738
const double psitilde_cs_10_0 = 1;
18740
// Compute basisvalues
18741
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
18742
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
18743
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
18744
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
18746
// Table(s) of coefficients
18747
static const double coefficients0[4][4] = \
18748
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
18749
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
18750
{0.288675135, 0, 0.210818511, -0.0745355992},
18751
{0.288675135, 0, 0, 0.223606798}};
18753
// Interesting (new) part
18754
// Tables of derivatives of the polynomial base (transpose)
18755
static const double dmats0[4][4] = \
18757
{6.32455532, 0, 0, 0},
18761
static const double dmats1[4][4] = \
18763
{3.16227766, 0, 0, 0},
18764
{5.47722558, 0, 0, 0},
18767
static const double dmats2[4][4] = \
18769
{3.16227766, 0, 0, 0},
18770
{1.82574186, 0, 0, 0},
18771
{5.16397779, 0, 0, 0}};
18773
// Compute reference derivatives
18774
// Declare pointer to array of derivatives on FIAT element
18775
double *derivatives = new double [num_derivatives];
18777
// Declare coefficients
18778
double coeff0_0 = 0;
18779
double coeff0_1 = 0;
18780
double coeff0_2 = 0;
18781
double coeff0_3 = 0;
18783
// Declare new coefficients
18784
double new_coeff0_0 = 0;
18785
double new_coeff0_1 = 0;
18786
double new_coeff0_2 = 0;
18787
double new_coeff0_3 = 0;
18789
// Loop possible derivatives
18790
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
18792
// Get values from coefficients array
18793
new_coeff0_0 = coefficients0[dof][0];
18794
new_coeff0_1 = coefficients0[dof][1];
18795
new_coeff0_2 = coefficients0[dof][2];
18796
new_coeff0_3 = coefficients0[dof][3];
18798
// Loop derivative order
18799
for (unsigned int j = 0; j < n; j++)
18801
// Update old coefficients
18802
coeff0_0 = new_coeff0_0;
18803
coeff0_1 = new_coeff0_1;
18804
coeff0_2 = new_coeff0_2;
18805
coeff0_3 = new_coeff0_3;
18807
if(combinations[deriv_num][j] == 0)
18809
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
18810
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
18811
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
18812
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
18814
if(combinations[deriv_num][j] == 1)
18816
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
18817
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
18818
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
18819
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
18821
if(combinations[deriv_num][j] == 2)
18823
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
18824
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
18825
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
18826
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
18830
// Compute derivatives on reference element as dot product of coefficients and basisvalues
18831
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
18834
// Transform derivatives back to physical element
18835
for (unsigned int row = 0; row < num_derivatives; row++)
18837
for (unsigned int col = 0; col < num_derivatives; col++)
18839
values[row] += transform[row][col]*derivatives[col];
18842
// Delete pointer to array of derivatives on FIAT element
18843
delete [] derivatives;
18845
// Delete pointer to array of combinations of derivatives and transform
18846
for (unsigned int row = 0; row < num_derivatives; row++)
18848
delete [] combinations[row];
18849
delete [] transform[row];
18852
delete [] combinations;
18853
delete [] transform;
18856
if (4 <= i && i <= 7)
18858
// Map degree of freedom to element degree of freedom
18859
const unsigned int dof = i - 4;
18861
// Generate scalings
18862
const double scalings_y_0 = 1;
18863
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
18864
const double scalings_z_0 = 1;
18865
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
18867
// Compute psitilde_a
18868
const double psitilde_a_0 = 1;
18869
const double psitilde_a_1 = x;
18871
// Compute psitilde_bs
18872
const double psitilde_bs_0_0 = 1;
18873
const double psitilde_bs_0_1 = 1.5*y + 0.5;
18874
const double psitilde_bs_1_0 = 1;
18876
// Compute psitilde_cs
18877
const double psitilde_cs_00_0 = 1;
18878
const double psitilde_cs_00_1 = 2*z + 1;
18879
const double psitilde_cs_01_0 = 1;
18880
const double psitilde_cs_10_0 = 1;
18882
// Compute basisvalues
18883
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
18884
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
18885
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
18886
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
18888
// Table(s) of coefficients
18889
static const double coefficients0[4][4] = \
18890
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
18891
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
18892
{0.288675135, 0, 0.210818511, -0.0745355992},
18893
{0.288675135, 0, 0, 0.223606798}};
18895
// Interesting (new) part
18896
// Tables of derivatives of the polynomial base (transpose)
18897
static const double dmats0[4][4] = \
18899
{6.32455532, 0, 0, 0},
18903
static const double dmats1[4][4] = \
18905
{3.16227766, 0, 0, 0},
18906
{5.47722558, 0, 0, 0},
18909
static const double dmats2[4][4] = \
18911
{3.16227766, 0, 0, 0},
18912
{1.82574186, 0, 0, 0},
18913
{5.16397779, 0, 0, 0}};
18915
// Compute reference derivatives
18916
// Declare pointer to array of derivatives on FIAT element
18917
double *derivatives = new double [num_derivatives];
18919
// Declare coefficients
18920
double coeff0_0 = 0;
18921
double coeff0_1 = 0;
18922
double coeff0_2 = 0;
18923
double coeff0_3 = 0;
18925
// Declare new coefficients
18926
double new_coeff0_0 = 0;
18927
double new_coeff0_1 = 0;
18928
double new_coeff0_2 = 0;
18929
double new_coeff0_3 = 0;
18931
// Loop possible derivatives
18932
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
18934
// Get values from coefficients array
18935
new_coeff0_0 = coefficients0[dof][0];
18936
new_coeff0_1 = coefficients0[dof][1];
18937
new_coeff0_2 = coefficients0[dof][2];
18938
new_coeff0_3 = coefficients0[dof][3];
18940
// Loop derivative order
18941
for (unsigned int j = 0; j < n; j++)
18943
// Update old coefficients
18944
coeff0_0 = new_coeff0_0;
18945
coeff0_1 = new_coeff0_1;
18946
coeff0_2 = new_coeff0_2;
18947
coeff0_3 = new_coeff0_3;
18949
if(combinations[deriv_num][j] == 0)
18951
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
18952
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
18953
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
18954
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
18956
if(combinations[deriv_num][j] == 1)
18958
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
18959
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
18960
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
18961
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
18963
if(combinations[deriv_num][j] == 2)
18965
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
18966
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
18967
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
18968
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
18972
// Compute derivatives on reference element as dot product of coefficients and basisvalues
18973
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
18976
// Transform derivatives back to physical element
18977
for (unsigned int row = 0; row < num_derivatives; row++)
18979
for (unsigned int col = 0; col < num_derivatives; col++)
18981
values[num_derivatives + row] += transform[row][col]*derivatives[col];
18984
// Delete pointer to array of derivatives on FIAT element
18985
delete [] derivatives;
18987
// Delete pointer to array of combinations of derivatives and transform
18988
for (unsigned int row = 0; row < num_derivatives; row++)
18990
delete [] combinations[row];
18991
delete [] transform[row];
18994
delete [] combinations;
18995
delete [] transform;
18998
if (8 <= i && i <= 11)
19000
// Map degree of freedom to element degree of freedom
19001
const unsigned int dof = i - 8;
19003
// Generate scalings
19004
const double scalings_y_0 = 1;
19005
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
19006
const double scalings_z_0 = 1;
19007
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
19009
// Compute psitilde_a
19010
const double psitilde_a_0 = 1;
19011
const double psitilde_a_1 = x;
19013
// Compute psitilde_bs
19014
const double psitilde_bs_0_0 = 1;
19015
const double psitilde_bs_0_1 = 1.5*y + 0.5;
19016
const double psitilde_bs_1_0 = 1;
19018
// Compute psitilde_cs
19019
const double psitilde_cs_00_0 = 1;
19020
const double psitilde_cs_00_1 = 2*z + 1;
19021
const double psitilde_cs_01_0 = 1;
19022
const double psitilde_cs_10_0 = 1;
19024
// Compute basisvalues
19025
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
19026
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
19027
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
19028
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
19030
// Table(s) of coefficients
19031
static const double coefficients0[4][4] = \
19032
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
19033
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
19034
{0.288675135, 0, 0.210818511, -0.0745355992},
19035
{0.288675135, 0, 0, 0.223606798}};
19037
// Interesting (new) part
19038
// Tables of derivatives of the polynomial base (transpose)
19039
static const double dmats0[4][4] = \
19041
{6.32455532, 0, 0, 0},
19045
static const double dmats1[4][4] = \
19047
{3.16227766, 0, 0, 0},
19048
{5.47722558, 0, 0, 0},
19051
static const double dmats2[4][4] = \
19053
{3.16227766, 0, 0, 0},
19054
{1.82574186, 0, 0, 0},
19055
{5.16397779, 0, 0, 0}};
19057
// Compute reference derivatives
19058
// Declare pointer to array of derivatives on FIAT element
19059
double *derivatives = new double [num_derivatives];
19061
// Declare coefficients
19062
double coeff0_0 = 0;
19063
double coeff0_1 = 0;
19064
double coeff0_2 = 0;
19065
double coeff0_3 = 0;
19067
// Declare new coefficients
19068
double new_coeff0_0 = 0;
19069
double new_coeff0_1 = 0;
19070
double new_coeff0_2 = 0;
19071
double new_coeff0_3 = 0;
19073
// Loop possible derivatives
19074
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
19076
// Get values from coefficients array
19077
new_coeff0_0 = coefficients0[dof][0];
19078
new_coeff0_1 = coefficients0[dof][1];
19079
new_coeff0_2 = coefficients0[dof][2];
19080
new_coeff0_3 = coefficients0[dof][3];
19082
// Loop derivative order
19083
for (unsigned int j = 0; j < n; j++)
19085
// Update old coefficients
19086
coeff0_0 = new_coeff0_0;
19087
coeff0_1 = new_coeff0_1;
19088
coeff0_2 = new_coeff0_2;
19089
coeff0_3 = new_coeff0_3;
19091
if(combinations[deriv_num][j] == 0)
19093
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
19094
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
19095
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
19096
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
19098
if(combinations[deriv_num][j] == 1)
19100
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
19101
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
19102
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
19103
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
19105
if(combinations[deriv_num][j] == 2)
19107
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
19108
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
19109
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
19110
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
19114
// Compute derivatives on reference element as dot product of coefficients and basisvalues
19115
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
19118
// Transform derivatives back to physical element
19119
for (unsigned int row = 0; row < num_derivatives; row++)
19121
for (unsigned int col = 0; col < num_derivatives; col++)
19123
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
19126
// Delete pointer to array of derivatives on FIAT element
19127
delete [] derivatives;
19129
// Delete pointer to array of combinations of derivatives and transform
19130
for (unsigned int row = 0; row < num_derivatives; row++)
19132
delete [] combinations[row];
19133
delete [] transform[row];
19136
delete [] combinations;
19137
delete [] transform;
19142
/// Evaluate order n derivatives of all basis functions at given point in cell
19143
virtual void evaluate_basis_derivatives_all(unsigned int n,
19145
const double* coordinates,
19146
const ufc::cell& c) const
19148
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
19151
/// Evaluate linear functional for dof i on the function f
19152
virtual double evaluate_dof(unsigned int i,
19153
const ufc::function& f,
19154
const ufc::cell& c) const
19156
// The reference points, direction and weights:
19157
static const double X[12][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
19158
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
19159
static const double D[12][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
19161
const double * const * x = c.coordinates;
19162
double result = 0.0;
19163
// Iterate over the points:
19164
// Evaluate basis functions for affine mapping
19165
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
19166
const double w1 = X[i][0][0];
19167
const double w2 = X[i][0][1];
19168
const double w3 = X[i][0][2];
19170
// Compute affine mapping y = F(X)
19172
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
19173
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
19174
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
19176
// Evaluate function at physical points
19178
f.evaluate(values, y, c);
19180
// Map function values using appropriate mapping
19181
// Affine map: Do nothing
19183
// Note that we do not map the weights (yet).
19185
// Take directional components
19186
for(int k = 0; k < 3; k++)
19187
result += values[k]*D[i][0][k];
19188
// Multiply by weights
19194
/// Evaluate linear functionals for all dofs on the function f
19195
virtual void evaluate_dofs(double* values,
19196
const ufc::function& f,
19197
const ufc::cell& c) const
19199
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
19202
/// Interpolate vertex values from dof values
19203
virtual void interpolate_vertex_values(double* vertex_values,
19204
const double* dof_values,
19205
const ufc::cell& c) const
19207
// Evaluate at vertices and use affine mapping
19208
vertex_values[0] = dof_values[0];
19209
vertex_values[3] = dof_values[1];
19210
vertex_values[6] = dof_values[2];
19211
vertex_values[9] = dof_values[3];
19212
// Evaluate at vertices and use affine mapping
19213
vertex_values[1] = dof_values[4];
19214
vertex_values[4] = dof_values[5];
19215
vertex_values[7] = dof_values[6];
19216
vertex_values[10] = dof_values[7];
19217
// Evaluate at vertices and use affine mapping
19218
vertex_values[2] = dof_values[8];
19219
vertex_values[5] = dof_values[9];
19220
vertex_values[8] = dof_values[10];
19221
vertex_values[11] = dof_values[11];
19224
/// Return the number of sub elements (for a mixed element)
19225
virtual unsigned int num_sub_elements() const
19230
/// Create a new finite element for sub element i (for a mixed element)
19231
virtual ufc::finite_element* create_sub_element(unsigned int i) const
19236
return new hyperelasticity_1_finite_element_2_0();
19239
return new hyperelasticity_1_finite_element_2_1();
19242
return new hyperelasticity_1_finite_element_2_2();
19250
/// This class defines the interface for a finite element.
19252
class hyperelasticity_1_finite_element_3_0: public ufc::finite_element
19257
hyperelasticity_1_finite_element_3_0() : ufc::finite_element()
19263
virtual ~hyperelasticity_1_finite_element_3_0()
19268
/// Return a string identifying the finite element
19269
virtual const char* signature() const
19271
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
19274
/// Return the cell shape
19275
virtual ufc::shape cell_shape() const
19277
return ufc::tetrahedron;
19280
/// Return the dimension of the finite element function space
19281
virtual unsigned int space_dimension() const
19286
/// Return the rank of the value space
19287
virtual unsigned int value_rank() const
19292
/// Return the dimension of the value space for axis i
19293
virtual unsigned int value_dimension(unsigned int i) const
19298
/// Evaluate basis function i at given point in cell
19299
virtual void evaluate_basis(unsigned int i,
19301
const double* coordinates,
19302
const ufc::cell& c) const
19304
// Extract vertex coordinates
19305
const double * const * element_coordinates = c.coordinates;
19307
// Compute Jacobian of affine map from reference cell
19308
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
19309
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
19310
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
19311
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
19312
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
19313
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
19314
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
19315
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
19316
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
19318
// Compute sub determinants
19319
const double d00 = J_11*J_22 - J_12*J_21;
19320
const double d01 = J_12*J_20 - J_10*J_22;
19321
const double d02 = J_10*J_21 - J_11*J_20;
19323
const double d10 = J_02*J_21 - J_01*J_22;
19324
const double d11 = J_00*J_22 - J_02*J_20;
19325
const double d12 = J_01*J_20 - J_00*J_21;
19327
const double d20 = J_01*J_12 - J_02*J_11;
19328
const double d21 = J_02*J_10 - J_00*J_12;
19329
const double d22 = J_00*J_11 - J_01*J_10;
19331
// Compute determinant of Jacobian
19332
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
19334
// Compute inverse of Jacobian
19336
// Compute constants
19337
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
19338
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
19339
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
19341
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
19342
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
19343
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
19345
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
19346
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
19347
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
19349
// Get coordinates and map to the UFC reference element
19350
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
19351
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
19352
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
19354
// Map coordinates to the reference cube
19355
if (std::abs(y + z - 1.0) < 1e-08)
19358
x = -2.0 * x/(y + z - 1.0) - 1.0;
19359
if (std::abs(z - 1.0) < 1e-08)
19362
y = 2.0 * y/(1.0 - z) - 1.0;
19368
// Map degree of freedom to element degree of freedom
19369
const unsigned int dof = i;
19371
// Generate scalings
19372
const double scalings_y_0 = 1;
19373
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
19374
const double scalings_z_0 = 1;
19375
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
19377
// Compute psitilde_a
19378
const double psitilde_a_0 = 1;
19379
const double psitilde_a_1 = x;
19381
// Compute psitilde_bs
19382
const double psitilde_bs_0_0 = 1;
19383
const double psitilde_bs_0_1 = 1.5*y + 0.5;
19384
const double psitilde_bs_1_0 = 1;
19386
// Compute psitilde_cs
19387
const double psitilde_cs_00_0 = 1;
19388
const double psitilde_cs_00_1 = 2*z + 1;
19389
const double psitilde_cs_01_0 = 1;
19390
const double psitilde_cs_10_0 = 1;
19392
// Compute basisvalues
19393
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
19394
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
19395
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
19396
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
19398
// Table(s) of coefficients
19399
static const double coefficients0[4][4] = \
19400
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
19401
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
19402
{0.288675135, 0, 0.210818511, -0.0745355992},
19403
{0.288675135, 0, 0, 0.223606798}};
19405
// Extract relevant coefficients
19406
const double coeff0_0 = coefficients0[dof][0];
19407
const double coeff0_1 = coefficients0[dof][1];
19408
const double coeff0_2 = coefficients0[dof][2];
19409
const double coeff0_3 = coefficients0[dof][3];
19411
// Compute value(s)
19412
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
19415
/// Evaluate all basis functions at given point in cell
19416
virtual void evaluate_basis_all(double* values,
19417
const double* coordinates,
19418
const ufc::cell& c) const
19420
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
19423
/// Evaluate order n derivatives of basis function i at given point in cell
19424
virtual void evaluate_basis_derivatives(unsigned int i,
19427
const double* coordinates,
19428
const ufc::cell& c) const
19430
// Extract vertex coordinates
19431
const double * const * element_coordinates = c.coordinates;
19433
// Compute Jacobian of affine map from reference cell
19434
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
19435
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
19436
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
19437
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
19438
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
19439
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
19440
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
19441
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
19442
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
19444
// Compute sub determinants
19445
const double d00 = J_11*J_22 - J_12*J_21;
19446
const double d01 = J_12*J_20 - J_10*J_22;
19447
const double d02 = J_10*J_21 - J_11*J_20;
19449
const double d10 = J_02*J_21 - J_01*J_22;
19450
const double d11 = J_00*J_22 - J_02*J_20;
19451
const double d12 = J_01*J_20 - J_00*J_21;
19453
const double d20 = J_01*J_12 - J_02*J_11;
19454
const double d21 = J_02*J_10 - J_00*J_12;
19455
const double d22 = J_00*J_11 - J_01*J_10;
19457
// Compute determinant of Jacobian
19458
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
19460
// Compute inverse of Jacobian
19462
// Compute constants
19463
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
19464
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
19465
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
19467
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
19468
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
19469
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
19471
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
19472
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
19473
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
19475
// Get coordinates and map to the UFC reference element
19476
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
19477
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
19478
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
19480
// Map coordinates to the reference cube
19481
if (std::abs(y + z - 1.0) < 1e-08)
19484
x = -2.0 * x/(y + z - 1.0) - 1.0;
19485
if (std::abs(z - 1.0) < 1e-08)
19488
y = 2.0 * y/(1.0 - z) - 1.0;
19491
// Compute number of derivatives
19492
unsigned int num_derivatives = 1;
19494
for (unsigned int j = 0; j < n; j++)
19495
num_derivatives *= 3;
19498
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
19499
unsigned int **combinations = new unsigned int *[num_derivatives];
19501
for (unsigned int j = 0; j < num_derivatives; j++)
19503
combinations[j] = new unsigned int [n];
19504
for (unsigned int k = 0; k < n; k++)
19505
combinations[j][k] = 0;
19508
// Generate combinations of derivatives
19509
for (unsigned int row = 1; row < num_derivatives; row++)
19511
for (unsigned int num = 0; num < row; num++)
19513
for (unsigned int col = n-1; col+1 > 0; col--)
19515
if (combinations[row][col] + 1 > 2)
19516
combinations[row][col] = 0;
19519
combinations[row][col] += 1;
19526
// Compute inverse of Jacobian
19527
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
19529
// Declare transformation matrix
19530
// Declare pointer to two dimensional array and initialise
19531
double **transform = new double *[num_derivatives];
19533
for (unsigned int j = 0; j < num_derivatives; j++)
19535
transform[j] = new double [num_derivatives];
19536
for (unsigned int k = 0; k < num_derivatives; k++)
19537
transform[j][k] = 1;
19540
// Construct transformation matrix
19541
for (unsigned int row = 0; row < num_derivatives; row++)
19543
for (unsigned int col = 0; col < num_derivatives; col++)
19545
for (unsigned int k = 0; k < n; k++)
19546
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
19551
for (unsigned int j = 0; j < 1*num_derivatives; j++)
19554
// Map degree of freedom to element degree of freedom
19555
const unsigned int dof = i;
19557
// Generate scalings
19558
const double scalings_y_0 = 1;
19559
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
19560
const double scalings_z_0 = 1;
19561
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
19563
// Compute psitilde_a
19564
const double psitilde_a_0 = 1;
19565
const double psitilde_a_1 = x;
19567
// Compute psitilde_bs
19568
const double psitilde_bs_0_0 = 1;
19569
const double psitilde_bs_0_1 = 1.5*y + 0.5;
19570
const double psitilde_bs_1_0 = 1;
19572
// Compute psitilde_cs
19573
const double psitilde_cs_00_0 = 1;
19574
const double psitilde_cs_00_1 = 2*z + 1;
19575
const double psitilde_cs_01_0 = 1;
19576
const double psitilde_cs_10_0 = 1;
19578
// Compute basisvalues
19579
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
19580
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
19581
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
19582
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
19584
// Table(s) of coefficients
19585
static const double coefficients0[4][4] = \
19586
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
19587
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
19588
{0.288675135, 0, 0.210818511, -0.0745355992},
19589
{0.288675135, 0, 0, 0.223606798}};
19591
// Interesting (new) part
19592
// Tables of derivatives of the polynomial base (transpose)
19593
static const double dmats0[4][4] = \
19595
{6.32455532, 0, 0, 0},
19599
static const double dmats1[4][4] = \
19601
{3.16227766, 0, 0, 0},
19602
{5.47722558, 0, 0, 0},
19605
static const double dmats2[4][4] = \
19607
{3.16227766, 0, 0, 0},
19608
{1.82574186, 0, 0, 0},
19609
{5.16397779, 0, 0, 0}};
19611
// Compute reference derivatives
19612
// Declare pointer to array of derivatives on FIAT element
19613
double *derivatives = new double [num_derivatives];
19615
// Declare coefficients
19616
double coeff0_0 = 0;
19617
double coeff0_1 = 0;
19618
double coeff0_2 = 0;
19619
double coeff0_3 = 0;
19621
// Declare new coefficients
19622
double new_coeff0_0 = 0;
19623
double new_coeff0_1 = 0;
19624
double new_coeff0_2 = 0;
19625
double new_coeff0_3 = 0;
19627
// Loop possible derivatives
19628
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
19630
// Get values from coefficients array
19631
new_coeff0_0 = coefficients0[dof][0];
19632
new_coeff0_1 = coefficients0[dof][1];
19633
new_coeff0_2 = coefficients0[dof][2];
19634
new_coeff0_3 = coefficients0[dof][3];
19636
// Loop derivative order
19637
for (unsigned int j = 0; j < n; j++)
19639
// Update old coefficients
19640
coeff0_0 = new_coeff0_0;
19641
coeff0_1 = new_coeff0_1;
19642
coeff0_2 = new_coeff0_2;
19643
coeff0_3 = new_coeff0_3;
19645
if(combinations[deriv_num][j] == 0)
19647
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
19648
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
19649
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
19650
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
19652
if(combinations[deriv_num][j] == 1)
19654
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
19655
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
19656
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
19657
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
19659
if(combinations[deriv_num][j] == 2)
19661
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
19662
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
19663
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
19664
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
19668
// Compute derivatives on reference element as dot product of coefficients and basisvalues
19669
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
19672
// Transform derivatives back to physical element
19673
for (unsigned int row = 0; row < num_derivatives; row++)
19675
for (unsigned int col = 0; col < num_derivatives; col++)
19677
values[row] += transform[row][col]*derivatives[col];
19680
// Delete pointer to array of derivatives on FIAT element
19681
delete [] derivatives;
19683
// Delete pointer to array of combinations of derivatives and transform
19684
for (unsigned int row = 0; row < num_derivatives; row++)
19686
delete [] combinations[row];
19687
delete [] transform[row];
19690
delete [] combinations;
19691
delete [] transform;
19694
/// Evaluate order n derivatives of all basis functions at given point in cell
19695
virtual void evaluate_basis_derivatives_all(unsigned int n,
19697
const double* coordinates,
19698
const ufc::cell& c) const
19700
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
19703
/// Evaluate linear functional for dof i on the function f
19704
virtual double evaluate_dof(unsigned int i,
19705
const ufc::function& f,
19706
const ufc::cell& c) const
19708
// The reference points, direction and weights:
19709
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
19710
static const double W[4][1] = {{1}, {1}, {1}, {1}};
19711
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
19713
const double * const * x = c.coordinates;
19714
double result = 0.0;
19715
// Iterate over the points:
19716
// Evaluate basis functions for affine mapping
19717
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
19718
const double w1 = X[i][0][0];
19719
const double w2 = X[i][0][1];
19720
const double w3 = X[i][0][2];
19722
// Compute affine mapping y = F(X)
19724
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
19725
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
19726
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
19728
// Evaluate function at physical points
19730
f.evaluate(values, y, c);
19732
// Map function values using appropriate mapping
19733
// Affine map: Do nothing
19735
// Note that we do not map the weights (yet).
19737
// Take directional components
19738
for(int k = 0; k < 1; k++)
19739
result += values[k]*D[i][0][k];
19740
// Multiply by weights
19746
/// Evaluate linear functionals for all dofs on the function f
19747
virtual void evaluate_dofs(double* values,
19748
const ufc::function& f,
19749
const ufc::cell& c) const
19751
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
19754
/// Interpolate vertex values from dof values
19755
virtual void interpolate_vertex_values(double* vertex_values,
19756
const double* dof_values,
19757
const ufc::cell& c) const
19759
// Evaluate at vertices and use affine mapping
19760
vertex_values[0] = dof_values[0];
19761
vertex_values[1] = dof_values[1];
19762
vertex_values[2] = dof_values[2];
19763
vertex_values[3] = dof_values[3];
19766
/// Return the number of sub elements (for a mixed element)
19767
virtual unsigned int num_sub_elements() const
19772
/// Create a new finite element for sub element i (for a mixed element)
19773
virtual ufc::finite_element* create_sub_element(unsigned int i) const
19775
return new hyperelasticity_1_finite_element_3_0();
19780
/// This class defines the interface for a finite element.
19782
class hyperelasticity_1_finite_element_3_1: public ufc::finite_element
19787
hyperelasticity_1_finite_element_3_1() : ufc::finite_element()
19793
virtual ~hyperelasticity_1_finite_element_3_1()
19798
/// Return a string identifying the finite element
19799
virtual const char* signature() const
19801
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
19804
/// Return the cell shape
19805
virtual ufc::shape cell_shape() const
19807
return ufc::tetrahedron;
19810
/// Return the dimension of the finite element function space
19811
virtual unsigned int space_dimension() const
19816
/// Return the rank of the value space
19817
virtual unsigned int value_rank() const
19822
/// Return the dimension of the value space for axis i
19823
virtual unsigned int value_dimension(unsigned int i) const
19828
/// Evaluate basis function i at given point in cell
19829
virtual void evaluate_basis(unsigned int i,
19831
const double* coordinates,
19832
const ufc::cell& c) const
19834
// Extract vertex coordinates
19835
const double * const * element_coordinates = c.coordinates;
19837
// Compute Jacobian of affine map from reference cell
19838
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
19839
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
19840
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
19841
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
19842
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
19843
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
19844
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
19845
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
19846
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
19848
// Compute sub determinants
19849
const double d00 = J_11*J_22 - J_12*J_21;
19850
const double d01 = J_12*J_20 - J_10*J_22;
19851
const double d02 = J_10*J_21 - J_11*J_20;
19853
const double d10 = J_02*J_21 - J_01*J_22;
19854
const double d11 = J_00*J_22 - J_02*J_20;
19855
const double d12 = J_01*J_20 - J_00*J_21;
19857
const double d20 = J_01*J_12 - J_02*J_11;
19858
const double d21 = J_02*J_10 - J_00*J_12;
19859
const double d22 = J_00*J_11 - J_01*J_10;
19861
// Compute determinant of Jacobian
19862
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
19864
// Compute inverse of Jacobian
19866
// Compute constants
19867
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
19868
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
19869
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
19871
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
19872
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
19873
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
19875
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
19876
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
19877
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
19879
// Get coordinates and map to the UFC reference element
19880
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
19881
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
19882
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
19884
// Map coordinates to the reference cube
19885
if (std::abs(y + z - 1.0) < 1e-08)
19888
x = -2.0 * x/(y + z - 1.0) - 1.0;
19889
if (std::abs(z - 1.0) < 1e-08)
19892
y = 2.0 * y/(1.0 - z) - 1.0;
19898
// Map degree of freedom to element degree of freedom
19899
const unsigned int dof = i;
19901
// Generate scalings
19902
const double scalings_y_0 = 1;
19903
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
19904
const double scalings_z_0 = 1;
19905
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
19907
// Compute psitilde_a
19908
const double psitilde_a_0 = 1;
19909
const double psitilde_a_1 = x;
19911
// Compute psitilde_bs
19912
const double psitilde_bs_0_0 = 1;
19913
const double psitilde_bs_0_1 = 1.5*y + 0.5;
19914
const double psitilde_bs_1_0 = 1;
19916
// Compute psitilde_cs
19917
const double psitilde_cs_00_0 = 1;
19918
const double psitilde_cs_00_1 = 2*z + 1;
19919
const double psitilde_cs_01_0 = 1;
19920
const double psitilde_cs_10_0 = 1;
19922
// Compute basisvalues
19923
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
19924
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
19925
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
19926
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
19928
// Table(s) of coefficients
19929
static const double coefficients0[4][4] = \
19930
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
19931
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
19932
{0.288675135, 0, 0.210818511, -0.0745355992},
19933
{0.288675135, 0, 0, 0.223606798}};
19935
// Extract relevant coefficients
19936
const double coeff0_0 = coefficients0[dof][0];
19937
const double coeff0_1 = coefficients0[dof][1];
19938
const double coeff0_2 = coefficients0[dof][2];
19939
const double coeff0_3 = coefficients0[dof][3];
19941
// Compute value(s)
19942
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
19945
/// Evaluate all basis functions at given point in cell
19946
virtual void evaluate_basis_all(double* values,
19947
const double* coordinates,
19948
const ufc::cell& c) const
19950
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
19953
/// Evaluate order n derivatives of basis function i at given point in cell
19954
virtual void evaluate_basis_derivatives(unsigned int i,
19957
const double* coordinates,
19958
const ufc::cell& c) const
19960
// Extract vertex coordinates
19961
const double * const * element_coordinates = c.coordinates;
19963
// Compute Jacobian of affine map from reference cell
19964
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
19965
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
19966
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
19967
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
19968
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
19969
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
19970
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
19971
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
19972
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
19974
// Compute sub determinants
19975
const double d00 = J_11*J_22 - J_12*J_21;
19976
const double d01 = J_12*J_20 - J_10*J_22;
19977
const double d02 = J_10*J_21 - J_11*J_20;
19979
const double d10 = J_02*J_21 - J_01*J_22;
19980
const double d11 = J_00*J_22 - J_02*J_20;
19981
const double d12 = J_01*J_20 - J_00*J_21;
19983
const double d20 = J_01*J_12 - J_02*J_11;
19984
const double d21 = J_02*J_10 - J_00*J_12;
19985
const double d22 = J_00*J_11 - J_01*J_10;
19987
// Compute determinant of Jacobian
19988
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
19990
// Compute inverse of Jacobian
19992
// Compute constants
19993
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
19994
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
19995
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
19997
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
19998
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
19999
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
20001
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
20002
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
20003
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
20005
// Get coordinates and map to the UFC reference element
20006
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
20007
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
20008
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
20010
// Map coordinates to the reference cube
20011
if (std::abs(y + z - 1.0) < 1e-08)
20014
x = -2.0 * x/(y + z - 1.0) - 1.0;
20015
if (std::abs(z - 1.0) < 1e-08)
20018
y = 2.0 * y/(1.0 - z) - 1.0;
20021
// Compute number of derivatives
20022
unsigned int num_derivatives = 1;
20024
for (unsigned int j = 0; j < n; j++)
20025
num_derivatives *= 3;
20028
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
20029
unsigned int **combinations = new unsigned int *[num_derivatives];
20031
for (unsigned int j = 0; j < num_derivatives; j++)
20033
combinations[j] = new unsigned int [n];
20034
for (unsigned int k = 0; k < n; k++)
20035
combinations[j][k] = 0;
20038
// Generate combinations of derivatives
20039
for (unsigned int row = 1; row < num_derivatives; row++)
20041
for (unsigned int num = 0; num < row; num++)
20043
for (unsigned int col = n-1; col+1 > 0; col--)
20045
if (combinations[row][col] + 1 > 2)
20046
combinations[row][col] = 0;
20049
combinations[row][col] += 1;
20056
// Compute inverse of Jacobian
20057
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
20059
// Declare transformation matrix
20060
// Declare pointer to two dimensional array and initialise
20061
double **transform = new double *[num_derivatives];
20063
for (unsigned int j = 0; j < num_derivatives; j++)
20065
transform[j] = new double [num_derivatives];
20066
for (unsigned int k = 0; k < num_derivatives; k++)
20067
transform[j][k] = 1;
20070
// Construct transformation matrix
20071
for (unsigned int row = 0; row < num_derivatives; row++)
20073
for (unsigned int col = 0; col < num_derivatives; col++)
20075
for (unsigned int k = 0; k < n; k++)
20076
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
20081
for (unsigned int j = 0; j < 1*num_derivatives; j++)
20084
// Map degree of freedom to element degree of freedom
20085
const unsigned int dof = i;
20087
// Generate scalings
20088
const double scalings_y_0 = 1;
20089
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
20090
const double scalings_z_0 = 1;
20091
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
20093
// Compute psitilde_a
20094
const double psitilde_a_0 = 1;
20095
const double psitilde_a_1 = x;
20097
// Compute psitilde_bs
20098
const double psitilde_bs_0_0 = 1;
20099
const double psitilde_bs_0_1 = 1.5*y + 0.5;
20100
const double psitilde_bs_1_0 = 1;
20102
// Compute psitilde_cs
20103
const double psitilde_cs_00_0 = 1;
20104
const double psitilde_cs_00_1 = 2*z + 1;
20105
const double psitilde_cs_01_0 = 1;
20106
const double psitilde_cs_10_0 = 1;
20108
// Compute basisvalues
20109
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
20110
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
20111
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
20112
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
20114
// Table(s) of coefficients
20115
static const double coefficients0[4][4] = \
20116
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
20117
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
20118
{0.288675135, 0, 0.210818511, -0.0745355992},
20119
{0.288675135, 0, 0, 0.223606798}};
20121
// Interesting (new) part
20122
// Tables of derivatives of the polynomial base (transpose)
20123
static const double dmats0[4][4] = \
20125
{6.32455532, 0, 0, 0},
20129
static const double dmats1[4][4] = \
20131
{3.16227766, 0, 0, 0},
20132
{5.47722558, 0, 0, 0},
20135
static const double dmats2[4][4] = \
20137
{3.16227766, 0, 0, 0},
20138
{1.82574186, 0, 0, 0},
20139
{5.16397779, 0, 0, 0}};
20141
// Compute reference derivatives
20142
// Declare pointer to array of derivatives on FIAT element
20143
double *derivatives = new double [num_derivatives];
20145
// Declare coefficients
20146
double coeff0_0 = 0;
20147
double coeff0_1 = 0;
20148
double coeff0_2 = 0;
20149
double coeff0_3 = 0;
20151
// Declare new coefficients
20152
double new_coeff0_0 = 0;
20153
double new_coeff0_1 = 0;
20154
double new_coeff0_2 = 0;
20155
double new_coeff0_3 = 0;
20157
// Loop possible derivatives
20158
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
20160
// Get values from coefficients array
20161
new_coeff0_0 = coefficients0[dof][0];
20162
new_coeff0_1 = coefficients0[dof][1];
20163
new_coeff0_2 = coefficients0[dof][2];
20164
new_coeff0_3 = coefficients0[dof][3];
20166
// Loop derivative order
20167
for (unsigned int j = 0; j < n; j++)
20169
// Update old coefficients
20170
coeff0_0 = new_coeff0_0;
20171
coeff0_1 = new_coeff0_1;
20172
coeff0_2 = new_coeff0_2;
20173
coeff0_3 = new_coeff0_3;
20175
if(combinations[deriv_num][j] == 0)
20177
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
20178
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
20179
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
20180
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
20182
if(combinations[deriv_num][j] == 1)
20184
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
20185
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
20186
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
20187
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
20189
if(combinations[deriv_num][j] == 2)
20191
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
20192
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
20193
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
20194
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
20198
// Compute derivatives on reference element as dot product of coefficients and basisvalues
20199
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
20202
// Transform derivatives back to physical element
20203
for (unsigned int row = 0; row < num_derivatives; row++)
20205
for (unsigned int col = 0; col < num_derivatives; col++)
20207
values[row] += transform[row][col]*derivatives[col];
20210
// Delete pointer to array of derivatives on FIAT element
20211
delete [] derivatives;
20213
// Delete pointer to array of combinations of derivatives and transform
20214
for (unsigned int row = 0; row < num_derivatives; row++)
20216
delete [] combinations[row];
20217
delete [] transform[row];
20220
delete [] combinations;
20221
delete [] transform;
20224
/// Evaluate order n derivatives of all basis functions at given point in cell
20225
virtual void evaluate_basis_derivatives_all(unsigned int n,
20227
const double* coordinates,
20228
const ufc::cell& c) const
20230
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
20233
/// Evaluate linear functional for dof i on the function f
20234
virtual double evaluate_dof(unsigned int i,
20235
const ufc::function& f,
20236
const ufc::cell& c) const
20238
// The reference points, direction and weights:
20239
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
20240
static const double W[4][1] = {{1}, {1}, {1}, {1}};
20241
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
20243
const double * const * x = c.coordinates;
20244
double result = 0.0;
20245
// Iterate over the points:
20246
// Evaluate basis functions for affine mapping
20247
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
20248
const double w1 = X[i][0][0];
20249
const double w2 = X[i][0][1];
20250
const double w3 = X[i][0][2];
20252
// Compute affine mapping y = F(X)
20254
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
20255
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
20256
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
20258
// Evaluate function at physical points
20260
f.evaluate(values, y, c);
20262
// Map function values using appropriate mapping
20263
// Affine map: Do nothing
20265
// Note that we do not map the weights (yet).
20267
// Take directional components
20268
for(int k = 0; k < 1; k++)
20269
result += values[k]*D[i][0][k];
20270
// Multiply by weights
20276
/// Evaluate linear functionals for all dofs on the function f
20277
virtual void evaluate_dofs(double* values,
20278
const ufc::function& f,
20279
const ufc::cell& c) const
20281
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
20284
/// Interpolate vertex values from dof values
20285
virtual void interpolate_vertex_values(double* vertex_values,
20286
const double* dof_values,
20287
const ufc::cell& c) const
20289
// Evaluate at vertices and use affine mapping
20290
vertex_values[0] = dof_values[0];
20291
vertex_values[1] = dof_values[1];
20292
vertex_values[2] = dof_values[2];
20293
vertex_values[3] = dof_values[3];
20296
/// Return the number of sub elements (for a mixed element)
20297
virtual unsigned int num_sub_elements() const
20302
/// Create a new finite element for sub element i (for a mixed element)
20303
virtual ufc::finite_element* create_sub_element(unsigned int i) const
20305
return new hyperelasticity_1_finite_element_3_1();
20310
/// This class defines the interface for a finite element.
20312
class hyperelasticity_1_finite_element_3_2: public ufc::finite_element
20317
hyperelasticity_1_finite_element_3_2() : ufc::finite_element()
20323
virtual ~hyperelasticity_1_finite_element_3_2()
20328
/// Return a string identifying the finite element
20329
virtual const char* signature() const
20331
return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
20334
/// Return the cell shape
20335
virtual ufc::shape cell_shape() const
20337
return ufc::tetrahedron;
20340
/// Return the dimension of the finite element function space
20341
virtual unsigned int space_dimension() const
20346
/// Return the rank of the value space
20347
virtual unsigned int value_rank() const
20352
/// Return the dimension of the value space for axis i
20353
virtual unsigned int value_dimension(unsigned int i) const
20358
/// Evaluate basis function i at given point in cell
20359
virtual void evaluate_basis(unsigned int i,
20361
const double* coordinates,
20362
const ufc::cell& c) const
20364
// Extract vertex coordinates
20365
const double * const * element_coordinates = c.coordinates;
20367
// Compute Jacobian of affine map from reference cell
20368
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
20369
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
20370
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
20371
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
20372
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
20373
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
20374
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
20375
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
20376
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
20378
// Compute sub determinants
20379
const double d00 = J_11*J_22 - J_12*J_21;
20380
const double d01 = J_12*J_20 - J_10*J_22;
20381
const double d02 = J_10*J_21 - J_11*J_20;
20383
const double d10 = J_02*J_21 - J_01*J_22;
20384
const double d11 = J_00*J_22 - J_02*J_20;
20385
const double d12 = J_01*J_20 - J_00*J_21;
20387
const double d20 = J_01*J_12 - J_02*J_11;
20388
const double d21 = J_02*J_10 - J_00*J_12;
20389
const double d22 = J_00*J_11 - J_01*J_10;
20391
// Compute determinant of Jacobian
20392
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
20394
// Compute inverse of Jacobian
20396
// Compute constants
20397
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
20398
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
20399
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
20401
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
20402
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
20403
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
20405
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
20406
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
20407
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
20409
// Get coordinates and map to the UFC reference element
20410
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
20411
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
20412
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
20414
// Map coordinates to the reference cube
20415
if (std::abs(y + z - 1.0) < 1e-08)
20418
x = -2.0 * x/(y + z - 1.0) - 1.0;
20419
if (std::abs(z - 1.0) < 1e-08)
20422
y = 2.0 * y/(1.0 - z) - 1.0;
20428
// Map degree of freedom to element degree of freedom
20429
const unsigned int dof = i;
20431
// Generate scalings
20432
const double scalings_y_0 = 1;
20433
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
20434
const double scalings_z_0 = 1;
20435
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
20437
// Compute psitilde_a
20438
const double psitilde_a_0 = 1;
20439
const double psitilde_a_1 = x;
20441
// Compute psitilde_bs
20442
const double psitilde_bs_0_0 = 1;
20443
const double psitilde_bs_0_1 = 1.5*y + 0.5;
20444
const double psitilde_bs_1_0 = 1;
20446
// Compute psitilde_cs
20447
const double psitilde_cs_00_0 = 1;
20448
const double psitilde_cs_00_1 = 2*z + 1;
20449
const double psitilde_cs_01_0 = 1;
20450
const double psitilde_cs_10_0 = 1;
20452
// Compute basisvalues
20453
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
20454
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
20455
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
20456
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
20458
// Table(s) of coefficients
20459
static const double coefficients0[4][4] = \
20460
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
20461
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
20462
{0.288675135, 0, 0.210818511, -0.0745355992},
20463
{0.288675135, 0, 0, 0.223606798}};
20465
// Extract relevant coefficients
20466
const double coeff0_0 = coefficients0[dof][0];
20467
const double coeff0_1 = coefficients0[dof][1];
20468
const double coeff0_2 = coefficients0[dof][2];
20469
const double coeff0_3 = coefficients0[dof][3];
20471
// Compute value(s)
20472
*values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
20475
/// Evaluate all basis functions at given point in cell
20476
virtual void evaluate_basis_all(double* values,
20477
const double* coordinates,
20478
const ufc::cell& c) const
20480
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
20483
/// Evaluate order n derivatives of basis function i at given point in cell
20484
virtual void evaluate_basis_derivatives(unsigned int i,
20487
const double* coordinates,
20488
const ufc::cell& c) const
20490
// Extract vertex coordinates
20491
const double * const * element_coordinates = c.coordinates;
20493
// Compute Jacobian of affine map from reference cell
20494
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
20495
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
20496
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
20497
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
20498
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
20499
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
20500
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
20501
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
20502
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
20504
// Compute sub determinants
20505
const double d00 = J_11*J_22 - J_12*J_21;
20506
const double d01 = J_12*J_20 - J_10*J_22;
20507
const double d02 = J_10*J_21 - J_11*J_20;
20509
const double d10 = J_02*J_21 - J_01*J_22;
20510
const double d11 = J_00*J_22 - J_02*J_20;
20511
const double d12 = J_01*J_20 - J_00*J_21;
20513
const double d20 = J_01*J_12 - J_02*J_11;
20514
const double d21 = J_02*J_10 - J_00*J_12;
20515
const double d22 = J_00*J_11 - J_01*J_10;
20517
// Compute determinant of Jacobian
20518
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
20520
// Compute inverse of Jacobian
20522
// Compute constants
20523
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
20524
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
20525
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
20527
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
20528
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
20529
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
20531
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
20532
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
20533
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
20535
// Get coordinates and map to the UFC reference element
20536
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
20537
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
20538
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
20540
// Map coordinates to the reference cube
20541
if (std::abs(y + z - 1.0) < 1e-08)
20544
x = -2.0 * x/(y + z - 1.0) - 1.0;
20545
if (std::abs(z - 1.0) < 1e-08)
20548
y = 2.0 * y/(1.0 - z) - 1.0;
20551
// Compute number of derivatives
20552
unsigned int num_derivatives = 1;
20554
for (unsigned int j = 0; j < n; j++)
20555
num_derivatives *= 3;
20558
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
20559
unsigned int **combinations = new unsigned int *[num_derivatives];
20561
for (unsigned int j = 0; j < num_derivatives; j++)
20563
combinations[j] = new unsigned int [n];
20564
for (unsigned int k = 0; k < n; k++)
20565
combinations[j][k] = 0;
20568
// Generate combinations of derivatives
20569
for (unsigned int row = 1; row < num_derivatives; row++)
20571
for (unsigned int num = 0; num < row; num++)
20573
for (unsigned int col = n-1; col+1 > 0; col--)
20575
if (combinations[row][col] + 1 > 2)
20576
combinations[row][col] = 0;
20579
combinations[row][col] += 1;
20586
// Compute inverse of Jacobian
20587
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
20589
// Declare transformation matrix
20590
// Declare pointer to two dimensional array and initialise
20591
double **transform = new double *[num_derivatives];
20593
for (unsigned int j = 0; j < num_derivatives; j++)
20595
transform[j] = new double [num_derivatives];
20596
for (unsigned int k = 0; k < num_derivatives; k++)
20597
transform[j][k] = 1;
20600
// Construct transformation matrix
20601
for (unsigned int row = 0; row < num_derivatives; row++)
20603
for (unsigned int col = 0; col < num_derivatives; col++)
20605
for (unsigned int k = 0; k < n; k++)
20606
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
20611
for (unsigned int j = 0; j < 1*num_derivatives; j++)
20614
// Map degree of freedom to element degree of freedom
20615
const unsigned int dof = i;
20617
// Generate scalings
20618
const double scalings_y_0 = 1;
20619
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
20620
const double scalings_z_0 = 1;
20621
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
20623
// Compute psitilde_a
20624
const double psitilde_a_0 = 1;
20625
const double psitilde_a_1 = x;
20627
// Compute psitilde_bs
20628
const double psitilde_bs_0_0 = 1;
20629
const double psitilde_bs_0_1 = 1.5*y + 0.5;
20630
const double psitilde_bs_1_0 = 1;
20632
// Compute psitilde_cs
20633
const double psitilde_cs_00_0 = 1;
20634
const double psitilde_cs_00_1 = 2*z + 1;
20635
const double psitilde_cs_01_0 = 1;
20636
const double psitilde_cs_10_0 = 1;
20638
// Compute basisvalues
20639
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
20640
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
20641
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
20642
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
20644
// Table(s) of coefficients
20645
static const double coefficients0[4][4] = \
20646
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
20647
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
20648
{0.288675135, 0, 0.210818511, -0.0745355992},
20649
{0.288675135, 0, 0, 0.223606798}};
20651
// Interesting (new) part
20652
// Tables of derivatives of the polynomial base (transpose)
20653
static const double dmats0[4][4] = \
20655
{6.32455532, 0, 0, 0},
20659
static const double dmats1[4][4] = \
20661
{3.16227766, 0, 0, 0},
20662
{5.47722558, 0, 0, 0},
20665
static const double dmats2[4][4] = \
20667
{3.16227766, 0, 0, 0},
20668
{1.82574186, 0, 0, 0},
20669
{5.16397779, 0, 0, 0}};
20671
// Compute reference derivatives
20672
// Declare pointer to array of derivatives on FIAT element
20673
double *derivatives = new double [num_derivatives];
20675
// Declare coefficients
20676
double coeff0_0 = 0;
20677
double coeff0_1 = 0;
20678
double coeff0_2 = 0;
20679
double coeff0_3 = 0;
20681
// Declare new coefficients
20682
double new_coeff0_0 = 0;
20683
double new_coeff0_1 = 0;
20684
double new_coeff0_2 = 0;
20685
double new_coeff0_3 = 0;
20687
// Loop possible derivatives
20688
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
20690
// Get values from coefficients array
20691
new_coeff0_0 = coefficients0[dof][0];
20692
new_coeff0_1 = coefficients0[dof][1];
20693
new_coeff0_2 = coefficients0[dof][2];
20694
new_coeff0_3 = coefficients0[dof][3];
20696
// Loop derivative order
20697
for (unsigned int j = 0; j < n; j++)
20699
// Update old coefficients
20700
coeff0_0 = new_coeff0_0;
20701
coeff0_1 = new_coeff0_1;
20702
coeff0_2 = new_coeff0_2;
20703
coeff0_3 = new_coeff0_3;
20705
if(combinations[deriv_num][j] == 0)
20707
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
20708
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
20709
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
20710
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
20712
if(combinations[deriv_num][j] == 1)
20714
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
20715
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
20716
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
20717
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
20719
if(combinations[deriv_num][j] == 2)
20721
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
20722
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
20723
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
20724
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
20728
// Compute derivatives on reference element as dot product of coefficients and basisvalues
20729
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
20732
// Transform derivatives back to physical element
20733
for (unsigned int row = 0; row < num_derivatives; row++)
20735
for (unsigned int col = 0; col < num_derivatives; col++)
20737
values[row] += transform[row][col]*derivatives[col];
20740
// Delete pointer to array of derivatives on FIAT element
20741
delete [] derivatives;
20743
// Delete pointer to array of combinations of derivatives and transform
20744
for (unsigned int row = 0; row < num_derivatives; row++)
20746
delete [] combinations[row];
20747
delete [] transform[row];
20750
delete [] combinations;
20751
delete [] transform;
20754
/// Evaluate order n derivatives of all basis functions at given point in cell
20755
virtual void evaluate_basis_derivatives_all(unsigned int n,
20757
const double* coordinates,
20758
const ufc::cell& c) const
20760
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
20763
/// Evaluate linear functional for dof i on the function f
20764
virtual double evaluate_dof(unsigned int i,
20765
const ufc::function& f,
20766
const ufc::cell& c) const
20768
// The reference points, direction and weights:
20769
static const double X[4][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
20770
static const double W[4][1] = {{1}, {1}, {1}, {1}};
20771
static const double D[4][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}};
20773
const double * const * x = c.coordinates;
20774
double result = 0.0;
20775
// Iterate over the points:
20776
// Evaluate basis functions for affine mapping
20777
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
20778
const double w1 = X[i][0][0];
20779
const double w2 = X[i][0][1];
20780
const double w3 = X[i][0][2];
20782
// Compute affine mapping y = F(X)
20784
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
20785
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
20786
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
20788
// Evaluate function at physical points
20790
f.evaluate(values, y, c);
20792
// Map function values using appropriate mapping
20793
// Affine map: Do nothing
20795
// Note that we do not map the weights (yet).
20797
// Take directional components
20798
for(int k = 0; k < 1; k++)
20799
result += values[k]*D[i][0][k];
20800
// Multiply by weights
20806
/// Evaluate linear functionals for all dofs on the function f
20807
virtual void evaluate_dofs(double* values,
20808
const ufc::function& f,
20809
const ufc::cell& c) const
20811
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
20814
/// Interpolate vertex values from dof values
20815
virtual void interpolate_vertex_values(double* vertex_values,
20816
const double* dof_values,
20817
const ufc::cell& c) const
20819
// Evaluate at vertices and use affine mapping
20820
vertex_values[0] = dof_values[0];
20821
vertex_values[1] = dof_values[1];
20822
vertex_values[2] = dof_values[2];
20823
vertex_values[3] = dof_values[3];
20826
/// Return the number of sub elements (for a mixed element)
20827
virtual unsigned int num_sub_elements() const
20832
/// Create a new finite element for sub element i (for a mixed element)
20833
virtual ufc::finite_element* create_sub_element(unsigned int i) const
20835
return new hyperelasticity_1_finite_element_3_2();
20840
/// This class defines the interface for a finite element.
20842
class hyperelasticity_1_finite_element_3: public ufc::finite_element
20847
hyperelasticity_1_finite_element_3() : ufc::finite_element()
20853
virtual ~hyperelasticity_1_finite_element_3()
20858
/// Return a string identifying the finite element
20859
virtual const char* signature() const
20861
return "VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
20864
/// Return the cell shape
20865
virtual ufc::shape cell_shape() const
20867
return ufc::tetrahedron;
20870
/// Return the dimension of the finite element function space
20871
virtual unsigned int space_dimension() const
20876
/// Return the rank of the value space
20877
virtual unsigned int value_rank() const
20882
/// Return the dimension of the value space for axis i
20883
virtual unsigned int value_dimension(unsigned int i) const
20888
/// Evaluate basis function i at given point in cell
20889
virtual void evaluate_basis(unsigned int i,
20891
const double* coordinates,
20892
const ufc::cell& c) const
20894
// Extract vertex coordinates
20895
const double * const * element_coordinates = c.coordinates;
20897
// Compute Jacobian of affine map from reference cell
20898
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
20899
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
20900
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
20901
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
20902
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
20903
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
20904
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
20905
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
20906
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
20908
// Compute sub determinants
20909
const double d00 = J_11*J_22 - J_12*J_21;
20910
const double d01 = J_12*J_20 - J_10*J_22;
20911
const double d02 = J_10*J_21 - J_11*J_20;
20913
const double d10 = J_02*J_21 - J_01*J_22;
20914
const double d11 = J_00*J_22 - J_02*J_20;
20915
const double d12 = J_01*J_20 - J_00*J_21;
20917
const double d20 = J_01*J_12 - J_02*J_11;
20918
const double d21 = J_02*J_10 - J_00*J_12;
20919
const double d22 = J_00*J_11 - J_01*J_10;
20921
// Compute determinant of Jacobian
20922
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
20924
// Compute inverse of Jacobian
20926
// Compute constants
20927
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
20928
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
20929
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
20931
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
20932
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
20933
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
20935
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
20936
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
20937
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
20939
// Get coordinates and map to the UFC reference element
20940
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
20941
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
20942
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
20944
// Map coordinates to the reference cube
20945
if (std::abs(y + z - 1.0) < 1e-08)
20948
x = -2.0 * x/(y + z - 1.0) - 1.0;
20949
if (std::abs(z - 1.0) < 1e-08)
20952
y = 2.0 * y/(1.0 - z) - 1.0;
20960
if (0 <= i && i <= 3)
20962
// Map degree of freedom to element degree of freedom
20963
const unsigned int dof = i;
20965
// Generate scalings
20966
const double scalings_y_0 = 1;
20967
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
20968
const double scalings_z_0 = 1;
20969
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
20971
// Compute psitilde_a
20972
const double psitilde_a_0 = 1;
20973
const double psitilde_a_1 = x;
20975
// Compute psitilde_bs
20976
const double psitilde_bs_0_0 = 1;
20977
const double psitilde_bs_0_1 = 1.5*y + 0.5;
20978
const double psitilde_bs_1_0 = 1;
20980
// Compute psitilde_cs
20981
const double psitilde_cs_00_0 = 1;
20982
const double psitilde_cs_00_1 = 2*z + 1;
20983
const double psitilde_cs_01_0 = 1;
20984
const double psitilde_cs_10_0 = 1;
20986
// Compute basisvalues
20987
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
20988
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
20989
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
20990
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
20992
// Table(s) of coefficients
20993
static const double coefficients0[4][4] = \
20994
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
20995
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
20996
{0.288675135, 0, 0.210818511, -0.0745355992},
20997
{0.288675135, 0, 0, 0.223606798}};
20999
// Extract relevant coefficients
21000
const double coeff0_0 = coefficients0[dof][0];
21001
const double coeff0_1 = coefficients0[dof][1];
21002
const double coeff0_2 = coefficients0[dof][2];
21003
const double coeff0_3 = coefficients0[dof][3];
21005
// Compute value(s)
21006
values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
21009
if (4 <= i && i <= 7)
21011
// Map degree of freedom to element degree of freedom
21012
const unsigned int dof = i - 4;
21014
// Generate scalings
21015
const double scalings_y_0 = 1;
21016
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
21017
const double scalings_z_0 = 1;
21018
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
21020
// Compute psitilde_a
21021
const double psitilde_a_0 = 1;
21022
const double psitilde_a_1 = x;
21024
// Compute psitilde_bs
21025
const double psitilde_bs_0_0 = 1;
21026
const double psitilde_bs_0_1 = 1.5*y + 0.5;
21027
const double psitilde_bs_1_0 = 1;
21029
// Compute psitilde_cs
21030
const double psitilde_cs_00_0 = 1;
21031
const double psitilde_cs_00_1 = 2*z + 1;
21032
const double psitilde_cs_01_0 = 1;
21033
const double psitilde_cs_10_0 = 1;
21035
// Compute basisvalues
21036
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
21037
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
21038
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
21039
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
21041
// Table(s) of coefficients
21042
static const double coefficients0[4][4] = \
21043
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
21044
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
21045
{0.288675135, 0, 0.210818511, -0.0745355992},
21046
{0.288675135, 0, 0, 0.223606798}};
21048
// Extract relevant coefficients
21049
const double coeff0_0 = coefficients0[dof][0];
21050
const double coeff0_1 = coefficients0[dof][1];
21051
const double coeff0_2 = coefficients0[dof][2];
21052
const double coeff0_3 = coefficients0[dof][3];
21054
// Compute value(s)
21055
values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
21058
if (8 <= i && i <= 11)
21060
// Map degree of freedom to element degree of freedom
21061
const unsigned int dof = i - 8;
21063
// Generate scalings
21064
const double scalings_y_0 = 1;
21065
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
21066
const double scalings_z_0 = 1;
21067
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
21069
// Compute psitilde_a
21070
const double psitilde_a_0 = 1;
21071
const double psitilde_a_1 = x;
21073
// Compute psitilde_bs
21074
const double psitilde_bs_0_0 = 1;
21075
const double psitilde_bs_0_1 = 1.5*y + 0.5;
21076
const double psitilde_bs_1_0 = 1;
21078
// Compute psitilde_cs
21079
const double psitilde_cs_00_0 = 1;
21080
const double psitilde_cs_00_1 = 2*z + 1;
21081
const double psitilde_cs_01_0 = 1;
21082
const double psitilde_cs_10_0 = 1;
21084
// Compute basisvalues
21085
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
21086
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
21087
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
21088
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
21090
// Table(s) of coefficients
21091
static const double coefficients0[4][4] = \
21092
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
21093
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
21094
{0.288675135, 0, 0.210818511, -0.0745355992},
21095
{0.288675135, 0, 0, 0.223606798}};
21097
// Extract relevant coefficients
21098
const double coeff0_0 = coefficients0[dof][0];
21099
const double coeff0_1 = coefficients0[dof][1];
21100
const double coeff0_2 = coefficients0[dof][2];
21101
const double coeff0_3 = coefficients0[dof][3];
21103
// Compute value(s)
21104
values[2] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3;
21109
/// Evaluate all basis functions at given point in cell
21110
virtual void evaluate_basis_all(double* values,
21111
const double* coordinates,
21112
const ufc::cell& c) const
21114
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
21117
/// Evaluate order n derivatives of basis function i at given point in cell
21118
virtual void evaluate_basis_derivatives(unsigned int i,
21121
const double* coordinates,
21122
const ufc::cell& c) const
21124
// Extract vertex coordinates
21125
const double * const * element_coordinates = c.coordinates;
21127
// Compute Jacobian of affine map from reference cell
21128
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
21129
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
21130
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
21131
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
21132
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
21133
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
21134
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
21135
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
21136
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
21138
// Compute sub determinants
21139
const double d00 = J_11*J_22 - J_12*J_21;
21140
const double d01 = J_12*J_20 - J_10*J_22;
21141
const double d02 = J_10*J_21 - J_11*J_20;
21143
const double d10 = J_02*J_21 - J_01*J_22;
21144
const double d11 = J_00*J_22 - J_02*J_20;
21145
const double d12 = J_01*J_20 - J_00*J_21;
21147
const double d20 = J_01*J_12 - J_02*J_11;
21148
const double d21 = J_02*J_10 - J_00*J_12;
21149
const double d22 = J_00*J_11 - J_01*J_10;
21151
// Compute determinant of Jacobian
21152
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
21154
// Compute inverse of Jacobian
21156
// Compute constants
21157
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
21158
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
21159
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
21161
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
21162
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
21163
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
21165
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
21166
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
21167
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
21169
// Get coordinates and map to the UFC reference element
21170
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
21171
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
21172
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
21174
// Map coordinates to the reference cube
21175
if (std::abs(y + z - 1.0) < 1e-08)
21178
x = -2.0 * x/(y + z - 1.0) - 1.0;
21179
if (std::abs(z - 1.0) < 1e-08)
21182
y = 2.0 * y/(1.0 - z) - 1.0;
21185
// Compute number of derivatives
21186
unsigned int num_derivatives = 1;
21188
for (unsigned int j = 0; j < n; j++)
21189
num_derivatives *= 3;
21192
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
21193
unsigned int **combinations = new unsigned int *[num_derivatives];
21195
for (unsigned int j = 0; j < num_derivatives; j++)
21197
combinations[j] = new unsigned int [n];
21198
for (unsigned int k = 0; k < n; k++)
21199
combinations[j][k] = 0;
21202
// Generate combinations of derivatives
21203
for (unsigned int row = 1; row < num_derivatives; row++)
21205
for (unsigned int num = 0; num < row; num++)
21207
for (unsigned int col = n-1; col+1 > 0; col--)
21209
if (combinations[row][col] + 1 > 2)
21210
combinations[row][col] = 0;
21213
combinations[row][col] += 1;
21220
// Compute inverse of Jacobian
21221
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
21223
// Declare transformation matrix
21224
// Declare pointer to two dimensional array and initialise
21225
double **transform = new double *[num_derivatives];
21227
for (unsigned int j = 0; j < num_derivatives; j++)
21229
transform[j] = new double [num_derivatives];
21230
for (unsigned int k = 0; k < num_derivatives; k++)
21231
transform[j][k] = 1;
21234
// Construct transformation matrix
21235
for (unsigned int row = 0; row < num_derivatives; row++)
21237
for (unsigned int col = 0; col < num_derivatives; col++)
21239
for (unsigned int k = 0; k < n; k++)
21240
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
21245
for (unsigned int j = 0; j < 3*num_derivatives; j++)
21248
if (0 <= i && i <= 3)
21250
// Map degree of freedom to element degree of freedom
21251
const unsigned int dof = i;
21253
// Generate scalings
21254
const double scalings_y_0 = 1;
21255
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
21256
const double scalings_z_0 = 1;
21257
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
21259
// Compute psitilde_a
21260
const double psitilde_a_0 = 1;
21261
const double psitilde_a_1 = x;
21263
// Compute psitilde_bs
21264
const double psitilde_bs_0_0 = 1;
21265
const double psitilde_bs_0_1 = 1.5*y + 0.5;
21266
const double psitilde_bs_1_0 = 1;
21268
// Compute psitilde_cs
21269
const double psitilde_cs_00_0 = 1;
21270
const double psitilde_cs_00_1 = 2*z + 1;
21271
const double psitilde_cs_01_0 = 1;
21272
const double psitilde_cs_10_0 = 1;
21274
// Compute basisvalues
21275
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
21276
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
21277
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
21278
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
21280
// Table(s) of coefficients
21281
static const double coefficients0[4][4] = \
21282
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
21283
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
21284
{0.288675135, 0, 0.210818511, -0.0745355992},
21285
{0.288675135, 0, 0, 0.223606798}};
21287
// Interesting (new) part
21288
// Tables of derivatives of the polynomial base (transpose)
21289
static const double dmats0[4][4] = \
21291
{6.32455532, 0, 0, 0},
21295
static const double dmats1[4][4] = \
21297
{3.16227766, 0, 0, 0},
21298
{5.47722558, 0, 0, 0},
21301
static const double dmats2[4][4] = \
21303
{3.16227766, 0, 0, 0},
21304
{1.82574186, 0, 0, 0},
21305
{5.16397779, 0, 0, 0}};
21307
// Compute reference derivatives
21308
// Declare pointer to array of derivatives on FIAT element
21309
double *derivatives = new double [num_derivatives];
21311
// Declare coefficients
21312
double coeff0_0 = 0;
21313
double coeff0_1 = 0;
21314
double coeff0_2 = 0;
21315
double coeff0_3 = 0;
21317
// Declare new coefficients
21318
double new_coeff0_0 = 0;
21319
double new_coeff0_1 = 0;
21320
double new_coeff0_2 = 0;
21321
double new_coeff0_3 = 0;
21323
// Loop possible derivatives
21324
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
21326
// Get values from coefficients array
21327
new_coeff0_0 = coefficients0[dof][0];
21328
new_coeff0_1 = coefficients0[dof][1];
21329
new_coeff0_2 = coefficients0[dof][2];
21330
new_coeff0_3 = coefficients0[dof][3];
21332
// Loop derivative order
21333
for (unsigned int j = 0; j < n; j++)
21335
// Update old coefficients
21336
coeff0_0 = new_coeff0_0;
21337
coeff0_1 = new_coeff0_1;
21338
coeff0_2 = new_coeff0_2;
21339
coeff0_3 = new_coeff0_3;
21341
if(combinations[deriv_num][j] == 0)
21343
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
21344
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
21345
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
21346
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
21348
if(combinations[deriv_num][j] == 1)
21350
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
21351
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
21352
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
21353
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
21355
if(combinations[deriv_num][j] == 2)
21357
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
21358
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
21359
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
21360
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
21364
// Compute derivatives on reference element as dot product of coefficients and basisvalues
21365
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
21368
// Transform derivatives back to physical element
21369
for (unsigned int row = 0; row < num_derivatives; row++)
21371
for (unsigned int col = 0; col < num_derivatives; col++)
21373
values[row] += transform[row][col]*derivatives[col];
21376
// Delete pointer to array of derivatives on FIAT element
21377
delete [] derivatives;
21379
// Delete pointer to array of combinations of derivatives and transform
21380
for (unsigned int row = 0; row < num_derivatives; row++)
21382
delete [] combinations[row];
21383
delete [] transform[row];
21386
delete [] combinations;
21387
delete [] transform;
21390
if (4 <= i && i <= 7)
21392
// Map degree of freedom to element degree of freedom
21393
const unsigned int dof = i - 4;
21395
// Generate scalings
21396
const double scalings_y_0 = 1;
21397
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
21398
const double scalings_z_0 = 1;
21399
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
21401
// Compute psitilde_a
21402
const double psitilde_a_0 = 1;
21403
const double psitilde_a_1 = x;
21405
// Compute psitilde_bs
21406
const double psitilde_bs_0_0 = 1;
21407
const double psitilde_bs_0_1 = 1.5*y + 0.5;
21408
const double psitilde_bs_1_0 = 1;
21410
// Compute psitilde_cs
21411
const double psitilde_cs_00_0 = 1;
21412
const double psitilde_cs_00_1 = 2*z + 1;
21413
const double psitilde_cs_01_0 = 1;
21414
const double psitilde_cs_10_0 = 1;
21416
// Compute basisvalues
21417
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
21418
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
21419
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
21420
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
21422
// Table(s) of coefficients
21423
static const double coefficients0[4][4] = \
21424
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
21425
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
21426
{0.288675135, 0, 0.210818511, -0.0745355992},
21427
{0.288675135, 0, 0, 0.223606798}};
21429
// Interesting (new) part
21430
// Tables of derivatives of the polynomial base (transpose)
21431
static const double dmats0[4][4] = \
21433
{6.32455532, 0, 0, 0},
21437
static const double dmats1[4][4] = \
21439
{3.16227766, 0, 0, 0},
21440
{5.47722558, 0, 0, 0},
21443
static const double dmats2[4][4] = \
21445
{3.16227766, 0, 0, 0},
21446
{1.82574186, 0, 0, 0},
21447
{5.16397779, 0, 0, 0}};
21449
// Compute reference derivatives
21450
// Declare pointer to array of derivatives on FIAT element
21451
double *derivatives = new double [num_derivatives];
21453
// Declare coefficients
21454
double coeff0_0 = 0;
21455
double coeff0_1 = 0;
21456
double coeff0_2 = 0;
21457
double coeff0_3 = 0;
21459
// Declare new coefficients
21460
double new_coeff0_0 = 0;
21461
double new_coeff0_1 = 0;
21462
double new_coeff0_2 = 0;
21463
double new_coeff0_3 = 0;
21465
// Loop possible derivatives
21466
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
21468
// Get values from coefficients array
21469
new_coeff0_0 = coefficients0[dof][0];
21470
new_coeff0_1 = coefficients0[dof][1];
21471
new_coeff0_2 = coefficients0[dof][2];
21472
new_coeff0_3 = coefficients0[dof][3];
21474
// Loop derivative order
21475
for (unsigned int j = 0; j < n; j++)
21477
// Update old coefficients
21478
coeff0_0 = new_coeff0_0;
21479
coeff0_1 = new_coeff0_1;
21480
coeff0_2 = new_coeff0_2;
21481
coeff0_3 = new_coeff0_3;
21483
if(combinations[deriv_num][j] == 0)
21485
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
21486
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
21487
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
21488
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
21490
if(combinations[deriv_num][j] == 1)
21492
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
21493
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
21494
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
21495
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
21497
if(combinations[deriv_num][j] == 2)
21499
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
21500
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
21501
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
21502
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
21506
// Compute derivatives on reference element as dot product of coefficients and basisvalues
21507
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
21510
// Transform derivatives back to physical element
21511
for (unsigned int row = 0; row < num_derivatives; row++)
21513
for (unsigned int col = 0; col < num_derivatives; col++)
21515
values[num_derivatives + row] += transform[row][col]*derivatives[col];
21518
// Delete pointer to array of derivatives on FIAT element
21519
delete [] derivatives;
21521
// Delete pointer to array of combinations of derivatives and transform
21522
for (unsigned int row = 0; row < num_derivatives; row++)
21524
delete [] combinations[row];
21525
delete [] transform[row];
21528
delete [] combinations;
21529
delete [] transform;
21532
if (8 <= i && i <= 11)
21534
// Map degree of freedom to element degree of freedom
21535
const unsigned int dof = i - 8;
21537
// Generate scalings
21538
const double scalings_y_0 = 1;
21539
const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
21540
const double scalings_z_0 = 1;
21541
const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
21543
// Compute psitilde_a
21544
const double psitilde_a_0 = 1;
21545
const double psitilde_a_1 = x;
21547
// Compute psitilde_bs
21548
const double psitilde_bs_0_0 = 1;
21549
const double psitilde_bs_0_1 = 1.5*y + 0.5;
21550
const double psitilde_bs_1_0 = 1;
21552
// Compute psitilde_cs
21553
const double psitilde_cs_00_0 = 1;
21554
const double psitilde_cs_00_1 = 2*z + 1;
21555
const double psitilde_cs_01_0 = 1;
21556
const double psitilde_cs_10_0 = 1;
21558
// Compute basisvalues
21559
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
21560
const double basisvalue1 = 2.73861279*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
21561
const double basisvalue2 = 1.58113883*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
21562
const double basisvalue3 = 1.11803399*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
21564
// Table(s) of coefficients
21565
static const double coefficients0[4][4] = \
21566
{{0.288675135, -0.182574186, -0.105409255, -0.0745355992},
21567
{0.288675135, 0.182574186, -0.105409255, -0.0745355992},
21568
{0.288675135, 0, 0.210818511, -0.0745355992},
21569
{0.288675135, 0, 0, 0.223606798}};
21571
// Interesting (new) part
21572
// Tables of derivatives of the polynomial base (transpose)
21573
static const double dmats0[4][4] = \
21575
{6.32455532, 0, 0, 0},
21579
static const double dmats1[4][4] = \
21581
{3.16227766, 0, 0, 0},
21582
{5.47722558, 0, 0, 0},
21585
static const double dmats2[4][4] = \
21587
{3.16227766, 0, 0, 0},
21588
{1.82574186, 0, 0, 0},
21589
{5.16397779, 0, 0, 0}};
21591
// Compute reference derivatives
21592
// Declare pointer to array of derivatives on FIAT element
21593
double *derivatives = new double [num_derivatives];
21595
// Declare coefficients
21596
double coeff0_0 = 0;
21597
double coeff0_1 = 0;
21598
double coeff0_2 = 0;
21599
double coeff0_3 = 0;
21601
// Declare new coefficients
21602
double new_coeff0_0 = 0;
21603
double new_coeff0_1 = 0;
21604
double new_coeff0_2 = 0;
21605
double new_coeff0_3 = 0;
21607
// Loop possible derivatives
21608
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
21610
// Get values from coefficients array
21611
new_coeff0_0 = coefficients0[dof][0];
21612
new_coeff0_1 = coefficients0[dof][1];
21613
new_coeff0_2 = coefficients0[dof][2];
21614
new_coeff0_3 = coefficients0[dof][3];
21616
// Loop derivative order
21617
for (unsigned int j = 0; j < n; j++)
21619
// Update old coefficients
21620
coeff0_0 = new_coeff0_0;
21621
coeff0_1 = new_coeff0_1;
21622
coeff0_2 = new_coeff0_2;
21623
coeff0_3 = new_coeff0_3;
21625
if(combinations[deriv_num][j] == 0)
21627
new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0];
21628
new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1];
21629
new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2];
21630
new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3];
21632
if(combinations[deriv_num][j] == 1)
21634
new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0];
21635
new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1];
21636
new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2];
21637
new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3];
21639
if(combinations[deriv_num][j] == 2)
21641
new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0];
21642
new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1];
21643
new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2];
21644
new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3];
21648
// Compute derivatives on reference element as dot product of coefficients and basisvalues
21649
derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3;
21652
// Transform derivatives back to physical element
21653
for (unsigned int row = 0; row < num_derivatives; row++)
21655
for (unsigned int col = 0; col < num_derivatives; col++)
21657
values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
21660
// Delete pointer to array of derivatives on FIAT element
21661
delete [] derivatives;
21663
// Delete pointer to array of combinations of derivatives and transform
21664
for (unsigned int row = 0; row < num_derivatives; row++)
21666
delete [] combinations[row];
21667
delete [] transform[row];
21670
delete [] combinations;
21671
delete [] transform;
21676
/// Evaluate order n derivatives of all basis functions at given point in cell
21677
virtual void evaluate_basis_derivatives_all(unsigned int n,
21679
const double* coordinates,
21680
const ufc::cell& c) const
21682
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
21685
/// Evaluate linear functional for dof i on the function f
21686
virtual double evaluate_dof(unsigned int i,
21687
const ufc::function& f,
21688
const ufc::cell& c) const
21690
// The reference points, direction and weights:
21691
static const double X[12][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}};
21692
static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
21693
static const double D[12][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
21695
const double * const * x = c.coordinates;
21696
double result = 0.0;
21697
// Iterate over the points:
21698
// Evaluate basis functions for affine mapping
21699
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
21700
const double w1 = X[i][0][0];
21701
const double w2 = X[i][0][1];
21702
const double w3 = X[i][0][2];
21704
// Compute affine mapping y = F(X)
21706
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
21707
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
21708
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
21710
// Evaluate function at physical points
21712
f.evaluate(values, y, c);
21714
// Map function values using appropriate mapping
21715
// Affine map: Do nothing
21717
// Note that we do not map the weights (yet).
21719
// Take directional components
21720
for(int k = 0; k < 3; k++)
21721
result += values[k]*D[i][0][k];
21722
// Multiply by weights
21728
/// Evaluate linear functionals for all dofs on the function f
21729
virtual void evaluate_dofs(double* values,
21730
const ufc::function& f,
21731
const ufc::cell& c) const
21733
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
21736
/// Interpolate vertex values from dof values
21737
virtual void interpolate_vertex_values(double* vertex_values,
21738
const double* dof_values,
21739
const ufc::cell& c) const
21741
// Evaluate at vertices and use affine mapping
21742
vertex_values[0] = dof_values[0];
21743
vertex_values[3] = dof_values[1];
21744
vertex_values[6] = dof_values[2];
21745
vertex_values[9] = dof_values[3];
21746
// Evaluate at vertices and use affine mapping
21747
vertex_values[1] = dof_values[4];
21748
vertex_values[4] = dof_values[5];
21749
vertex_values[7] = dof_values[6];
21750
vertex_values[10] = dof_values[7];
21751
// Evaluate at vertices and use affine mapping
21752
vertex_values[2] = dof_values[8];
21753
vertex_values[5] = dof_values[9];
21754
vertex_values[8] = dof_values[10];
21755
vertex_values[11] = dof_values[11];
21758
/// Return the number of sub elements (for a mixed element)
21759
virtual unsigned int num_sub_elements() const
21764
/// Create a new finite element for sub element i (for a mixed element)
21765
virtual ufc::finite_element* create_sub_element(unsigned int i) const
21770
return new hyperelasticity_1_finite_element_3_0();
21773
return new hyperelasticity_1_finite_element_3_1();
21776
return new hyperelasticity_1_finite_element_3_2();
21784
/// This class defines the interface for a finite element.
21786
class hyperelasticity_1_finite_element_4: public ufc::finite_element
21791
hyperelasticity_1_finite_element_4() : ufc::finite_element()
21797
virtual ~hyperelasticity_1_finite_element_4()
21802
/// Return a string identifying the finite element
21803
virtual const char* signature() const
21805
return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
21808
/// Return the cell shape
21809
virtual ufc::shape cell_shape() const
21811
return ufc::tetrahedron;
21814
/// Return the dimension of the finite element function space
21815
virtual unsigned int space_dimension() const
21820
/// Return the rank of the value space
21821
virtual unsigned int value_rank() const
21826
/// Return the dimension of the value space for axis i
21827
virtual unsigned int value_dimension(unsigned int i) const
21832
/// Evaluate basis function i at given point in cell
21833
virtual void evaluate_basis(unsigned int i,
21835
const double* coordinates,
21836
const ufc::cell& c) const
21838
// Extract vertex coordinates
21839
const double * const * element_coordinates = c.coordinates;
21841
// Compute Jacobian of affine map from reference cell
21842
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
21843
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
21844
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
21845
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
21846
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
21847
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
21848
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
21849
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
21850
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
21852
// Compute sub determinants
21853
const double d00 = J_11*J_22 - J_12*J_21;
21854
const double d01 = J_12*J_20 - J_10*J_22;
21855
const double d02 = J_10*J_21 - J_11*J_20;
21857
const double d10 = J_02*J_21 - J_01*J_22;
21858
const double d11 = J_00*J_22 - J_02*J_20;
21859
const double d12 = J_01*J_20 - J_00*J_21;
21861
const double d20 = J_01*J_12 - J_02*J_11;
21862
const double d21 = J_02*J_10 - J_00*J_12;
21863
const double d22 = J_00*J_11 - J_01*J_10;
21865
// Compute determinant of Jacobian
21866
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
21868
// Compute inverse of Jacobian
21870
// Compute constants
21871
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
21872
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
21873
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
21875
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
21876
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
21877
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
21879
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
21880
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
21881
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
21883
// Get coordinates and map to the UFC reference element
21884
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
21885
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
21886
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
21888
// Map coordinates to the reference cube
21889
if (std::abs(y + z - 1.0) < 1e-08)
21892
x = -2.0 * x/(y + z - 1.0) - 1.0;
21893
if (std::abs(z - 1.0) < 1e-08)
21896
y = 2.0 * y/(1.0 - z) - 1.0;
21902
// Map degree of freedom to element degree of freedom
21903
const unsigned int dof = i;
21905
// Generate scalings
21906
const double scalings_y_0 = 1;
21907
const double scalings_z_0 = 1;
21909
// Compute psitilde_a
21910
const double psitilde_a_0 = 1;
21912
// Compute psitilde_bs
21913
const double psitilde_bs_0_0 = 1;
21915
// Compute psitilde_cs
21916
const double psitilde_cs_00_0 = 1;
21918
// Compute basisvalues
21919
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
21921
// Table(s) of coefficients
21922
static const double coefficients0[1][1] = \
21925
// Extract relevant coefficients
21926
const double coeff0_0 = coefficients0[dof][0];
21928
// Compute value(s)
21929
*values = coeff0_0*basisvalue0;
21932
/// Evaluate all basis functions at given point in cell
21933
virtual void evaluate_basis_all(double* values,
21934
const double* coordinates,
21935
const ufc::cell& c) const
21937
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
21940
/// Evaluate order n derivatives of basis function i at given point in cell
21941
virtual void evaluate_basis_derivatives(unsigned int i,
21944
const double* coordinates,
21945
const ufc::cell& c) const
21947
// Extract vertex coordinates
21948
const double * const * element_coordinates = c.coordinates;
21950
// Compute Jacobian of affine map from reference cell
21951
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
21952
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
21953
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
21954
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
21955
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
21956
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
21957
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
21958
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
21959
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
21961
// Compute sub determinants
21962
const double d00 = J_11*J_22 - J_12*J_21;
21963
const double d01 = J_12*J_20 - J_10*J_22;
21964
const double d02 = J_10*J_21 - J_11*J_20;
21966
const double d10 = J_02*J_21 - J_01*J_22;
21967
const double d11 = J_00*J_22 - J_02*J_20;
21968
const double d12 = J_01*J_20 - J_00*J_21;
21970
const double d20 = J_01*J_12 - J_02*J_11;
21971
const double d21 = J_02*J_10 - J_00*J_12;
21972
const double d22 = J_00*J_11 - J_01*J_10;
21974
// Compute determinant of Jacobian
21975
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
21977
// Compute inverse of Jacobian
21979
// Compute constants
21980
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
21981
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
21982
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
21984
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
21985
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
21986
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
21988
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
21989
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
21990
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
21992
// Get coordinates and map to the UFC reference element
21993
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
21994
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
21995
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
21997
// Map coordinates to the reference cube
21998
if (std::abs(y + z - 1.0) < 1e-08)
22001
x = -2.0 * x/(y + z - 1.0) - 1.0;
22002
if (std::abs(z - 1.0) < 1e-08)
22005
y = 2.0 * y/(1.0 - z) - 1.0;
22008
// Compute number of derivatives
22009
unsigned int num_derivatives = 1;
22011
for (unsigned int j = 0; j < n; j++)
22012
num_derivatives *= 3;
22015
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
22016
unsigned int **combinations = new unsigned int *[num_derivatives];
22018
for (unsigned int j = 0; j < num_derivatives; j++)
22020
combinations[j] = new unsigned int [n];
22021
for (unsigned int k = 0; k < n; k++)
22022
combinations[j][k] = 0;
22025
// Generate combinations of derivatives
22026
for (unsigned int row = 1; row < num_derivatives; row++)
22028
for (unsigned int num = 0; num < row; num++)
22030
for (unsigned int col = n-1; col+1 > 0; col--)
22032
if (combinations[row][col] + 1 > 2)
22033
combinations[row][col] = 0;
22036
combinations[row][col] += 1;
22043
// Compute inverse of Jacobian
22044
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
22046
// Declare transformation matrix
22047
// Declare pointer to two dimensional array and initialise
22048
double **transform = new double *[num_derivatives];
22050
for (unsigned int j = 0; j < num_derivatives; j++)
22052
transform[j] = new double [num_derivatives];
22053
for (unsigned int k = 0; k < num_derivatives; k++)
22054
transform[j][k] = 1;
22057
// Construct transformation matrix
22058
for (unsigned int row = 0; row < num_derivatives; row++)
22060
for (unsigned int col = 0; col < num_derivatives; col++)
22062
for (unsigned int k = 0; k < n; k++)
22063
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
22068
for (unsigned int j = 0; j < 1*num_derivatives; j++)
22071
// Map degree of freedom to element degree of freedom
22072
const unsigned int dof = i;
22074
// Generate scalings
22075
const double scalings_y_0 = 1;
22076
const double scalings_z_0 = 1;
22078
// Compute psitilde_a
22079
const double psitilde_a_0 = 1;
22081
// Compute psitilde_bs
22082
const double psitilde_bs_0_0 = 1;
22084
// Compute psitilde_cs
22085
const double psitilde_cs_00_0 = 1;
22087
// Compute basisvalues
22088
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
22090
// Table(s) of coefficients
22091
static const double coefficients0[1][1] = \
22094
// Interesting (new) part
22095
// Tables of derivatives of the polynomial base (transpose)
22096
static const double dmats0[1][1] = \
22099
static const double dmats1[1][1] = \
22102
static const double dmats2[1][1] = \
22105
// Compute reference derivatives
22106
// Declare pointer to array of derivatives on FIAT element
22107
double *derivatives = new double [num_derivatives];
22109
// Declare coefficients
22110
double coeff0_0 = 0;
22112
// Declare new coefficients
22113
double new_coeff0_0 = 0;
22115
// Loop possible derivatives
22116
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
22118
// Get values from coefficients array
22119
new_coeff0_0 = coefficients0[dof][0];
22121
// Loop derivative order
22122
for (unsigned int j = 0; j < n; j++)
22124
// Update old coefficients
22125
coeff0_0 = new_coeff0_0;
22127
if(combinations[deriv_num][j] == 0)
22129
new_coeff0_0 = coeff0_0*dmats0[0][0];
22131
if(combinations[deriv_num][j] == 1)
22133
new_coeff0_0 = coeff0_0*dmats1[0][0];
22135
if(combinations[deriv_num][j] == 2)
22137
new_coeff0_0 = coeff0_0*dmats2[0][0];
22141
// Compute derivatives on reference element as dot product of coefficients and basisvalues
22142
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
22145
// Transform derivatives back to physical element
22146
for (unsigned int row = 0; row < num_derivatives; row++)
22148
for (unsigned int col = 0; col < num_derivatives; col++)
22150
values[row] += transform[row][col]*derivatives[col];
22153
// Delete pointer to array of derivatives on FIAT element
22154
delete [] derivatives;
22156
// Delete pointer to array of combinations of derivatives and transform
22157
for (unsigned int row = 0; row < num_derivatives; row++)
22159
delete [] combinations[row];
22160
delete [] transform[row];
22163
delete [] combinations;
22164
delete [] transform;
22167
/// Evaluate order n derivatives of all basis functions at given point in cell
22168
virtual void evaluate_basis_derivatives_all(unsigned int n,
22170
const double* coordinates,
22171
const ufc::cell& c) const
22173
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
22176
/// Evaluate linear functional for dof i on the function f
22177
virtual double evaluate_dof(unsigned int i,
22178
const ufc::function& f,
22179
const ufc::cell& c) const
22181
// The reference points, direction and weights:
22182
static const double X[1][1][3] = {{{0.25, 0.25, 0.25}}};
22183
static const double W[1][1] = {{1}};
22184
static const double D[1][1][1] = {{{1}}};
22186
const double * const * x = c.coordinates;
22187
double result = 0.0;
22188
// Iterate over the points:
22189
// Evaluate basis functions for affine mapping
22190
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
22191
const double w1 = X[i][0][0];
22192
const double w2 = X[i][0][1];
22193
const double w3 = X[i][0][2];
22195
// Compute affine mapping y = F(X)
22197
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
22198
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
22199
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
22201
// Evaluate function at physical points
22203
f.evaluate(values, y, c);
22205
// Map function values using appropriate mapping
22206
// Affine map: Do nothing
22208
// Note that we do not map the weights (yet).
22210
// Take directional components
22211
for(int k = 0; k < 1; k++)
22212
result += values[k]*D[i][0][k];
22213
// Multiply by weights
22219
/// Evaluate linear functionals for all dofs on the function f
22220
virtual void evaluate_dofs(double* values,
22221
const ufc::function& f,
22222
const ufc::cell& c) const
22224
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
22227
/// Interpolate vertex values from dof values
22228
virtual void interpolate_vertex_values(double* vertex_values,
22229
const double* dof_values,
22230
const ufc::cell& c) const
22232
// Evaluate at vertices and use affine mapping
22233
vertex_values[0] = dof_values[0];
22234
vertex_values[1] = dof_values[0];
22235
vertex_values[2] = dof_values[0];
22236
vertex_values[3] = dof_values[0];
22239
/// Return the number of sub elements (for a mixed element)
22240
virtual unsigned int num_sub_elements() const
22245
/// Create a new finite element for sub element i (for a mixed element)
22246
virtual ufc::finite_element* create_sub_element(unsigned int i) const
22248
return new hyperelasticity_1_finite_element_4();
22253
/// This class defines the interface for a finite element.
22255
class hyperelasticity_1_finite_element_5: public ufc::finite_element
22260
hyperelasticity_1_finite_element_5() : ufc::finite_element()
22266
virtual ~hyperelasticity_1_finite_element_5()
22271
/// Return a string identifying the finite element
22272
virtual const char* signature() const
22274
return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
22277
/// Return the cell shape
22278
virtual ufc::shape cell_shape() const
22280
return ufc::tetrahedron;
22283
/// Return the dimension of the finite element function space
22284
virtual unsigned int space_dimension() const
22289
/// Return the rank of the value space
22290
virtual unsigned int value_rank() const
22295
/// Return the dimension of the value space for axis i
22296
virtual unsigned int value_dimension(unsigned int i) const
22301
/// Evaluate basis function i at given point in cell
22302
virtual void evaluate_basis(unsigned int i,
22304
const double* coordinates,
22305
const ufc::cell& c) const
22307
// Extract vertex coordinates
22308
const double * const * element_coordinates = c.coordinates;
22310
// Compute Jacobian of affine map from reference cell
22311
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
22312
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
22313
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
22314
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
22315
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
22316
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
22317
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
22318
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
22319
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
22321
// Compute sub determinants
22322
const double d00 = J_11*J_22 - J_12*J_21;
22323
const double d01 = J_12*J_20 - J_10*J_22;
22324
const double d02 = J_10*J_21 - J_11*J_20;
22326
const double d10 = J_02*J_21 - J_01*J_22;
22327
const double d11 = J_00*J_22 - J_02*J_20;
22328
const double d12 = J_01*J_20 - J_00*J_21;
22330
const double d20 = J_01*J_12 - J_02*J_11;
22331
const double d21 = J_02*J_10 - J_00*J_12;
22332
const double d22 = J_00*J_11 - J_01*J_10;
22334
// Compute determinant of Jacobian
22335
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
22337
// Compute inverse of Jacobian
22339
// Compute constants
22340
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
22341
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
22342
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
22344
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
22345
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
22346
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
22348
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
22349
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
22350
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
22352
// Get coordinates and map to the UFC reference element
22353
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
22354
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
22355
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
22357
// Map coordinates to the reference cube
22358
if (std::abs(y + z - 1.0) < 1e-08)
22361
x = -2.0 * x/(y + z - 1.0) - 1.0;
22362
if (std::abs(z - 1.0) < 1e-08)
22365
y = 2.0 * y/(1.0 - z) - 1.0;
22371
// Map degree of freedom to element degree of freedom
22372
const unsigned int dof = i;
22374
// Generate scalings
22375
const double scalings_y_0 = 1;
22376
const double scalings_z_0 = 1;
22378
// Compute psitilde_a
22379
const double psitilde_a_0 = 1;
22381
// Compute psitilde_bs
22382
const double psitilde_bs_0_0 = 1;
22384
// Compute psitilde_cs
22385
const double psitilde_cs_00_0 = 1;
22387
// Compute basisvalues
22388
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
22390
// Table(s) of coefficients
22391
static const double coefficients0[1][1] = \
22394
// Extract relevant coefficients
22395
const double coeff0_0 = coefficients0[dof][0];
22397
// Compute value(s)
22398
*values = coeff0_0*basisvalue0;
22401
/// Evaluate all basis functions at given point in cell
22402
virtual void evaluate_basis_all(double* values,
22403
const double* coordinates,
22404
const ufc::cell& c) const
22406
throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
22409
/// Evaluate order n derivatives of basis function i at given point in cell
22410
virtual void evaluate_basis_derivatives(unsigned int i,
22413
const double* coordinates,
22414
const ufc::cell& c) const
22416
// Extract vertex coordinates
22417
const double * const * element_coordinates = c.coordinates;
22419
// Compute Jacobian of affine map from reference cell
22420
const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
22421
const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
22422
const double J_02 = element_coordinates[3][0] - element_coordinates[0][0];
22423
const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
22424
const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
22425
const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
22426
const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
22427
const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
22428
const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
22430
// Compute sub determinants
22431
const double d00 = J_11*J_22 - J_12*J_21;
22432
const double d01 = J_12*J_20 - J_10*J_22;
22433
const double d02 = J_10*J_21 - J_11*J_20;
22435
const double d10 = J_02*J_21 - J_01*J_22;
22436
const double d11 = J_00*J_22 - J_02*J_20;
22437
const double d12 = J_01*J_20 - J_00*J_21;
22439
const double d20 = J_01*J_12 - J_02*J_11;
22440
const double d21 = J_02*J_10 - J_00*J_12;
22441
const double d22 = J_00*J_11 - J_01*J_10;
22443
// Compute determinant of Jacobian
22444
double detJ = J_00*d00 + J_10*d10 + J_20*d20;
22446
// Compute inverse of Jacobian
22448
// Compute constants
22449
const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
22450
+ d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
22451
+ d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
22453
const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
22454
+ d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
22455
+ d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
22457
const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
22458
+ d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
22459
+ d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
22461
// Get coordinates and map to the UFC reference element
22462
double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
22463
double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
22464
double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
22466
// Map coordinates to the reference cube
22467
if (std::abs(y + z - 1.0) < 1e-08)
22470
x = -2.0 * x/(y + z - 1.0) - 1.0;
22471
if (std::abs(z - 1.0) < 1e-08)
22474
y = 2.0 * y/(1.0 - z) - 1.0;
22477
// Compute number of derivatives
22478
unsigned int num_derivatives = 1;
22480
for (unsigned int j = 0; j < n; j++)
22481
num_derivatives *= 3;
22484
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
22485
unsigned int **combinations = new unsigned int *[num_derivatives];
22487
for (unsigned int j = 0; j < num_derivatives; j++)
22489
combinations[j] = new unsigned int [n];
22490
for (unsigned int k = 0; k < n; k++)
22491
combinations[j][k] = 0;
22494
// Generate combinations of derivatives
22495
for (unsigned int row = 1; row < num_derivatives; row++)
22497
for (unsigned int num = 0; num < row; num++)
22499
for (unsigned int col = n-1; col+1 > 0; col--)
22501
if (combinations[row][col] + 1 > 2)
22502
combinations[row][col] = 0;
22505
combinations[row][col] += 1;
22512
// Compute inverse of Jacobian
22513
const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / detJ}};
22515
// Declare transformation matrix
22516
// Declare pointer to two dimensional array and initialise
22517
double **transform = new double *[num_derivatives];
22519
for (unsigned int j = 0; j < num_derivatives; j++)
22521
transform[j] = new double [num_derivatives];
22522
for (unsigned int k = 0; k < num_derivatives; k++)
22523
transform[j][k] = 1;
22526
// Construct transformation matrix
22527
for (unsigned int row = 0; row < num_derivatives; row++)
22529
for (unsigned int col = 0; col < num_derivatives; col++)
22531
for (unsigned int k = 0; k < n; k++)
22532
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
22537
for (unsigned int j = 0; j < 1*num_derivatives; j++)
22540
// Map degree of freedom to element degree of freedom
22541
const unsigned int dof = i;
22543
// Generate scalings
22544
const double scalings_y_0 = 1;
22545
const double scalings_z_0 = 1;
22547
// Compute psitilde_a
22548
const double psitilde_a_0 = 1;
22550
// Compute psitilde_bs
22551
const double psitilde_bs_0_0 = 1;
22553
// Compute psitilde_cs
22554
const double psitilde_cs_00_0 = 1;
22556
// Compute basisvalues
22557
const double basisvalue0 = 0.866025404*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
22559
// Table(s) of coefficients
22560
static const double coefficients0[1][1] = \
22563
// Interesting (new) part
22564
// Tables of derivatives of the polynomial base (transpose)
22565
static const double dmats0[1][1] = \
22568
static const double dmats1[1][1] = \
22571
static const double dmats2[1][1] = \
22574
// Compute reference derivatives
22575
// Declare pointer to array of derivatives on FIAT element
22576
double *derivatives = new double [num_derivatives];
22578
// Declare coefficients
22579
double coeff0_0 = 0;
22581
// Declare new coefficients
22582
double new_coeff0_0 = 0;
22584
// Loop possible derivatives
22585
for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
22587
// Get values from coefficients array
22588
new_coeff0_0 = coefficients0[dof][0];
22590
// Loop derivative order
22591
for (unsigned int j = 0; j < n; j++)
22593
// Update old coefficients
22594
coeff0_0 = new_coeff0_0;
22596
if(combinations[deriv_num][j] == 0)
22598
new_coeff0_0 = coeff0_0*dmats0[0][0];
22600
if(combinations[deriv_num][j] == 1)
22602
new_coeff0_0 = coeff0_0*dmats1[0][0];
22604
if(combinations[deriv_num][j] == 2)
22606
new_coeff0_0 = coeff0_0*dmats2[0][0];
22610
// Compute derivatives on reference element as dot product of coefficients and basisvalues
22611
derivatives[deriv_num] = new_coeff0_0*basisvalue0;
22614
// Transform derivatives back to physical element
22615
for (unsigned int row = 0; row < num_derivatives; row++)
22617
for (unsigned int col = 0; col < num_derivatives; col++)
22619
values[row] += transform[row][col]*derivatives[col];
22622
// Delete pointer to array of derivatives on FIAT element
22623
delete [] derivatives;
22625
// Delete pointer to array of combinations of derivatives and transform
22626
for (unsigned int row = 0; row < num_derivatives; row++)
22628
delete [] combinations[row];
22629
delete [] transform[row];
22632
delete [] combinations;
22633
delete [] transform;
22636
/// Evaluate order n derivatives of all basis functions at given point in cell
22637
virtual void evaluate_basis_derivatives_all(unsigned int n,
22639
const double* coordinates,
22640
const ufc::cell& c) const
22642
throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
22645
/// Evaluate linear functional for dof i on the function f
22646
virtual double evaluate_dof(unsigned int i,
22647
const ufc::function& f,
22648
const ufc::cell& c) const
22650
// The reference points, direction and weights:
22651
static const double X[1][1][3] = {{{0.25, 0.25, 0.25}}};
22652
static const double W[1][1] = {{1}};
22653
static const double D[1][1][1] = {{{1}}};
22655
const double * const * x = c.coordinates;
22656
double result = 0.0;
22657
// Iterate over the points:
22658
// Evaluate basis functions for affine mapping
22659
const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
22660
const double w1 = X[i][0][0];
22661
const double w2 = X[i][0][1];
22662
const double w3 = X[i][0][2];
22664
// Compute affine mapping y = F(X)
22666
y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
22667
y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
22668
y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
22670
// Evaluate function at physical points
22672
f.evaluate(values, y, c);
22674
// Map function values using appropriate mapping
22675
// Affine map: Do nothing
22677
// Note that we do not map the weights (yet).
22679
// Take directional components
22680
for(int k = 0; k < 1; k++)
22681
result += values[k]*D[i][0][k];
22682
// Multiply by weights
22688
/// Evaluate linear functionals for all dofs on the function f
22689
virtual void evaluate_dofs(double* values,
22690
const ufc::function& f,
22691
const ufc::cell& c) const
22693
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
22696
/// Interpolate vertex values from dof values
22697
virtual void interpolate_vertex_values(double* vertex_values,
22698
const double* dof_values,
22699
const ufc::cell& c) const
22701
// Evaluate at vertices and use affine mapping
22702
vertex_values[0] = dof_values[0];
22703
vertex_values[1] = dof_values[0];
22704
vertex_values[2] = dof_values[0];
22705
vertex_values[3] = dof_values[0];
22708
/// Return the number of sub elements (for a mixed element)
22709
virtual unsigned int num_sub_elements() const
22714
/// Create a new finite element for sub element i (for a mixed element)
22715
virtual ufc::finite_element* create_sub_element(unsigned int i) const
22717
return new hyperelasticity_1_finite_element_5();
22722
/// This class defines the interface for a local-to-global mapping of
22723
/// degrees of freedom (dofs).
22725
class hyperelasticity_1_dof_map_0_0: public ufc::dof_map
22729
unsigned int __global_dimension;
22734
hyperelasticity_1_dof_map_0_0() : ufc::dof_map()
22736
__global_dimension = 0;
22740
virtual ~hyperelasticity_1_dof_map_0_0()
22745
/// Return a string identifying the dof map
22746
virtual const char* signature() const
22748
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
22751
/// Return true iff mesh entities of topological dimension d are needed
22752
virtual bool needs_mesh_entities(unsigned int d) const
22772
/// Initialize dof map for mesh (return true iff init_cell() is needed)
22773
virtual bool init_mesh(const ufc::mesh& m)
22775
__global_dimension = m.num_entities[0];
22779
/// Initialize dof map for given cell
22780
virtual void init_cell(const ufc::mesh& m,
22781
const ufc::cell& c)
22786
/// Finish initialization of dof map for cells
22787
virtual void init_cell_finalize()
22792
/// Return the dimension of the global finite element function space
22793
virtual unsigned int global_dimension() const
22795
return __global_dimension;
22798
/// Return the dimension of the local finite element function space for a cell
22799
virtual unsigned int local_dimension(const ufc::cell& c) const
22804
/// Return the maximum dimension of the local finite element function space
22805
virtual unsigned int max_local_dimension() const
22810
// Return the geometric dimension of the coordinates this dof map provides
22811
virtual unsigned int geometric_dimension() const
22816
/// Return the number of dofs on each cell facet
22817
virtual unsigned int num_facet_dofs() const
22822
/// Return the number of dofs associated with each cell entity of dimension d
22823
virtual unsigned int num_entity_dofs(unsigned int d) const
22825
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
22828
/// Tabulate the local-to-global mapping of dofs on a cell
22829
virtual void tabulate_dofs(unsigned int* dofs,
22830
const ufc::mesh& m,
22831
const ufc::cell& c) const
22833
dofs[0] = c.entity_indices[0][0];
22834
dofs[1] = c.entity_indices[0][1];
22835
dofs[2] = c.entity_indices[0][2];
22836
dofs[3] = c.entity_indices[0][3];
22839
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
22840
virtual void tabulate_facet_dofs(unsigned int* dofs,
22841
unsigned int facet) const
22868
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
22869
virtual void tabulate_entity_dofs(unsigned int* dofs,
22870
unsigned int d, unsigned int i) const
22872
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
22875
/// Tabulate the coordinates of all dofs on a cell
22876
virtual void tabulate_coordinates(double** coordinates,
22877
const ufc::cell& c) const
22879
const double * const * x = c.coordinates;
22880
coordinates[0][0] = x[0][0];
22881
coordinates[0][1] = x[0][1];
22882
coordinates[0][2] = x[0][2];
22883
coordinates[1][0] = x[1][0];
22884
coordinates[1][1] = x[1][1];
22885
coordinates[1][2] = x[1][2];
22886
coordinates[2][0] = x[2][0];
22887
coordinates[2][1] = x[2][1];
22888
coordinates[2][2] = x[2][2];
22889
coordinates[3][0] = x[3][0];
22890
coordinates[3][1] = x[3][1];
22891
coordinates[3][2] = x[3][2];
22894
/// Return the number of sub dof maps (for a mixed element)
22895
virtual unsigned int num_sub_dof_maps() const
22900
/// Create a new dof_map for sub dof map i (for a mixed element)
22901
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
22903
return new hyperelasticity_1_dof_map_0_0();
22908
/// This class defines the interface for a local-to-global mapping of
22909
/// degrees of freedom (dofs).
22911
class hyperelasticity_1_dof_map_0_1: public ufc::dof_map
22915
unsigned int __global_dimension;
22920
hyperelasticity_1_dof_map_0_1() : ufc::dof_map()
22922
__global_dimension = 0;
22926
virtual ~hyperelasticity_1_dof_map_0_1()
22931
/// Return a string identifying the dof map
22932
virtual const char* signature() const
22934
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
22937
/// Return true iff mesh entities of topological dimension d are needed
22938
virtual bool needs_mesh_entities(unsigned int d) const
22958
/// Initialize dof map for mesh (return true iff init_cell() is needed)
22959
virtual bool init_mesh(const ufc::mesh& m)
22961
__global_dimension = m.num_entities[0];
22965
/// Initialize dof map for given cell
22966
virtual void init_cell(const ufc::mesh& m,
22967
const ufc::cell& c)
22972
/// Finish initialization of dof map for cells
22973
virtual void init_cell_finalize()
22978
/// Return the dimension of the global finite element function space
22979
virtual unsigned int global_dimension() const
22981
return __global_dimension;
22984
/// Return the dimension of the local finite element function space for a cell
22985
virtual unsigned int local_dimension(const ufc::cell& c) const
22990
/// Return the maximum dimension of the local finite element function space
22991
virtual unsigned int max_local_dimension() const
22996
// Return the geometric dimension of the coordinates this dof map provides
22997
virtual unsigned int geometric_dimension() const
23002
/// Return the number of dofs on each cell facet
23003
virtual unsigned int num_facet_dofs() const
23008
/// Return the number of dofs associated with each cell entity of dimension d
23009
virtual unsigned int num_entity_dofs(unsigned int d) const
23011
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23014
/// Tabulate the local-to-global mapping of dofs on a cell
23015
virtual void tabulate_dofs(unsigned int* dofs,
23016
const ufc::mesh& m,
23017
const ufc::cell& c) const
23019
dofs[0] = c.entity_indices[0][0];
23020
dofs[1] = c.entity_indices[0][1];
23021
dofs[2] = c.entity_indices[0][2];
23022
dofs[3] = c.entity_indices[0][3];
23025
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
23026
virtual void tabulate_facet_dofs(unsigned int* dofs,
23027
unsigned int facet) const
23054
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
23055
virtual void tabulate_entity_dofs(unsigned int* dofs,
23056
unsigned int d, unsigned int i) const
23058
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23061
/// Tabulate the coordinates of all dofs on a cell
23062
virtual void tabulate_coordinates(double** coordinates,
23063
const ufc::cell& c) const
23065
const double * const * x = c.coordinates;
23066
coordinates[0][0] = x[0][0];
23067
coordinates[0][1] = x[0][1];
23068
coordinates[0][2] = x[0][2];
23069
coordinates[1][0] = x[1][0];
23070
coordinates[1][1] = x[1][1];
23071
coordinates[1][2] = x[1][2];
23072
coordinates[2][0] = x[2][0];
23073
coordinates[2][1] = x[2][1];
23074
coordinates[2][2] = x[2][2];
23075
coordinates[3][0] = x[3][0];
23076
coordinates[3][1] = x[3][1];
23077
coordinates[3][2] = x[3][2];
23080
/// Return the number of sub dof maps (for a mixed element)
23081
virtual unsigned int num_sub_dof_maps() const
23086
/// Create a new dof_map for sub dof map i (for a mixed element)
23087
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
23089
return new hyperelasticity_1_dof_map_0_1();
23094
/// This class defines the interface for a local-to-global mapping of
23095
/// degrees of freedom (dofs).
23097
class hyperelasticity_1_dof_map_0_2: public ufc::dof_map
23101
unsigned int __global_dimension;
23106
hyperelasticity_1_dof_map_0_2() : ufc::dof_map()
23108
__global_dimension = 0;
23112
virtual ~hyperelasticity_1_dof_map_0_2()
23117
/// Return a string identifying the dof map
23118
virtual const char* signature() const
23120
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
23123
/// Return true iff mesh entities of topological dimension d are needed
23124
virtual bool needs_mesh_entities(unsigned int d) const
23144
/// Initialize dof map for mesh (return true iff init_cell() is needed)
23145
virtual bool init_mesh(const ufc::mesh& m)
23147
__global_dimension = m.num_entities[0];
23151
/// Initialize dof map for given cell
23152
virtual void init_cell(const ufc::mesh& m,
23153
const ufc::cell& c)
23158
/// Finish initialization of dof map for cells
23159
virtual void init_cell_finalize()
23164
/// Return the dimension of the global finite element function space
23165
virtual unsigned int global_dimension() const
23167
return __global_dimension;
23170
/// Return the dimension of the local finite element function space for a cell
23171
virtual unsigned int local_dimension(const ufc::cell& c) const
23176
/// Return the maximum dimension of the local finite element function space
23177
virtual unsigned int max_local_dimension() const
23182
// Return the geometric dimension of the coordinates this dof map provides
23183
virtual unsigned int geometric_dimension() const
23188
/// Return the number of dofs on each cell facet
23189
virtual unsigned int num_facet_dofs() const
23194
/// Return the number of dofs associated with each cell entity of dimension d
23195
virtual unsigned int num_entity_dofs(unsigned int d) const
23197
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23200
/// Tabulate the local-to-global mapping of dofs on a cell
23201
virtual void tabulate_dofs(unsigned int* dofs,
23202
const ufc::mesh& m,
23203
const ufc::cell& c) const
23205
dofs[0] = c.entity_indices[0][0];
23206
dofs[1] = c.entity_indices[0][1];
23207
dofs[2] = c.entity_indices[0][2];
23208
dofs[3] = c.entity_indices[0][3];
23211
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
23212
virtual void tabulate_facet_dofs(unsigned int* dofs,
23213
unsigned int facet) const
23240
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
23241
virtual void tabulate_entity_dofs(unsigned int* dofs,
23242
unsigned int d, unsigned int i) const
23244
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23247
/// Tabulate the coordinates of all dofs on a cell
23248
virtual void tabulate_coordinates(double** coordinates,
23249
const ufc::cell& c) const
23251
const double * const * x = c.coordinates;
23252
coordinates[0][0] = x[0][0];
23253
coordinates[0][1] = x[0][1];
23254
coordinates[0][2] = x[0][2];
23255
coordinates[1][0] = x[1][0];
23256
coordinates[1][1] = x[1][1];
23257
coordinates[1][2] = x[1][2];
23258
coordinates[2][0] = x[2][0];
23259
coordinates[2][1] = x[2][1];
23260
coordinates[2][2] = x[2][2];
23261
coordinates[3][0] = x[3][0];
23262
coordinates[3][1] = x[3][1];
23263
coordinates[3][2] = x[3][2];
23266
/// Return the number of sub dof maps (for a mixed element)
23267
virtual unsigned int num_sub_dof_maps() const
23272
/// Create a new dof_map for sub dof map i (for a mixed element)
23273
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
23275
return new hyperelasticity_1_dof_map_0_2();
23280
/// This class defines the interface for a local-to-global mapping of
23281
/// degrees of freedom (dofs).
23283
class hyperelasticity_1_dof_map_0: public ufc::dof_map
23287
unsigned int __global_dimension;
23292
hyperelasticity_1_dof_map_0() : ufc::dof_map()
23294
__global_dimension = 0;
23298
virtual ~hyperelasticity_1_dof_map_0()
23303
/// Return a string identifying the dof map
23304
virtual const char* signature() const
23306
return "FFC dof map for VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
23309
/// Return true iff mesh entities of topological dimension d are needed
23310
virtual bool needs_mesh_entities(unsigned int d) const
23330
/// Initialize dof map for mesh (return true iff init_cell() is needed)
23331
virtual bool init_mesh(const ufc::mesh& m)
23333
__global_dimension = 3*m.num_entities[0];
23337
/// Initialize dof map for given cell
23338
virtual void init_cell(const ufc::mesh& m,
23339
const ufc::cell& c)
23344
/// Finish initialization of dof map for cells
23345
virtual void init_cell_finalize()
23350
/// Return the dimension of the global finite element function space
23351
virtual unsigned int global_dimension() const
23353
return __global_dimension;
23356
/// Return the dimension of the local finite element function space for a cell
23357
virtual unsigned int local_dimension(const ufc::cell& c) const
23362
/// Return the maximum dimension of the local finite element function space
23363
virtual unsigned int max_local_dimension() const
23368
// Return the geometric dimension of the coordinates this dof map provides
23369
virtual unsigned int geometric_dimension() const
23374
/// Return the number of dofs on each cell facet
23375
virtual unsigned int num_facet_dofs() const
23380
/// Return the number of dofs associated with each cell entity of dimension d
23381
virtual unsigned int num_entity_dofs(unsigned int d) const
23383
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23386
/// Tabulate the local-to-global mapping of dofs on a cell
23387
virtual void tabulate_dofs(unsigned int* dofs,
23388
const ufc::mesh& m,
23389
const ufc::cell& c) const
23391
dofs[0] = c.entity_indices[0][0];
23392
dofs[1] = c.entity_indices[0][1];
23393
dofs[2] = c.entity_indices[0][2];
23394
dofs[3] = c.entity_indices[0][3];
23395
unsigned int offset = m.num_entities[0];
23396
dofs[4] = offset + c.entity_indices[0][0];
23397
dofs[5] = offset + c.entity_indices[0][1];
23398
dofs[6] = offset + c.entity_indices[0][2];
23399
dofs[7] = offset + c.entity_indices[0][3];
23400
offset = offset + m.num_entities[0];
23401
dofs[8] = offset + c.entity_indices[0][0];
23402
dofs[9] = offset + c.entity_indices[0][1];
23403
dofs[10] = offset + c.entity_indices[0][2];
23404
dofs[11] = offset + c.entity_indices[0][3];
23407
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
23408
virtual void tabulate_facet_dofs(unsigned int* dofs,
23409
unsigned int facet) const
23460
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
23461
virtual void tabulate_entity_dofs(unsigned int* dofs,
23462
unsigned int d, unsigned int i) const
23464
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23467
/// Tabulate the coordinates of all dofs on a cell
23468
virtual void tabulate_coordinates(double** coordinates,
23469
const ufc::cell& c) const
23471
const double * const * x = c.coordinates;
23472
coordinates[0][0] = x[0][0];
23473
coordinates[0][1] = x[0][1];
23474
coordinates[0][2] = x[0][2];
23475
coordinates[1][0] = x[1][0];
23476
coordinates[1][1] = x[1][1];
23477
coordinates[1][2] = x[1][2];
23478
coordinates[2][0] = x[2][0];
23479
coordinates[2][1] = x[2][1];
23480
coordinates[2][2] = x[2][2];
23481
coordinates[3][0] = x[3][0];
23482
coordinates[3][1] = x[3][1];
23483
coordinates[3][2] = x[3][2];
23484
coordinates[4][0] = x[0][0];
23485
coordinates[4][1] = x[0][1];
23486
coordinates[4][2] = x[0][2];
23487
coordinates[5][0] = x[1][0];
23488
coordinates[5][1] = x[1][1];
23489
coordinates[5][2] = x[1][2];
23490
coordinates[6][0] = x[2][0];
23491
coordinates[6][1] = x[2][1];
23492
coordinates[6][2] = x[2][2];
23493
coordinates[7][0] = x[3][0];
23494
coordinates[7][1] = x[3][1];
23495
coordinates[7][2] = x[3][2];
23496
coordinates[8][0] = x[0][0];
23497
coordinates[8][1] = x[0][1];
23498
coordinates[8][2] = x[0][2];
23499
coordinates[9][0] = x[1][0];
23500
coordinates[9][1] = x[1][1];
23501
coordinates[9][2] = x[1][2];
23502
coordinates[10][0] = x[2][0];
23503
coordinates[10][1] = x[2][1];
23504
coordinates[10][2] = x[2][2];
23505
coordinates[11][0] = x[3][0];
23506
coordinates[11][1] = x[3][1];
23507
coordinates[11][2] = x[3][2];
23510
/// Return the number of sub dof maps (for a mixed element)
23511
virtual unsigned int num_sub_dof_maps() const
23516
/// Create a new dof_map for sub dof map i (for a mixed element)
23517
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
23522
return new hyperelasticity_1_dof_map_0_0();
23525
return new hyperelasticity_1_dof_map_0_1();
23528
return new hyperelasticity_1_dof_map_0_2();
23536
/// This class defines the interface for a local-to-global mapping of
23537
/// degrees of freedom (dofs).
23539
class hyperelasticity_1_dof_map_1_0: public ufc::dof_map
23543
unsigned int __global_dimension;
23548
hyperelasticity_1_dof_map_1_0() : ufc::dof_map()
23550
__global_dimension = 0;
23554
virtual ~hyperelasticity_1_dof_map_1_0()
23559
/// Return a string identifying the dof map
23560
virtual const char* signature() const
23562
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
23565
/// Return true iff mesh entities of topological dimension d are needed
23566
virtual bool needs_mesh_entities(unsigned int d) const
23586
/// Initialize dof map for mesh (return true iff init_cell() is needed)
23587
virtual bool init_mesh(const ufc::mesh& m)
23589
__global_dimension = m.num_entities[0];
23593
/// Initialize dof map for given cell
23594
virtual void init_cell(const ufc::mesh& m,
23595
const ufc::cell& c)
23600
/// Finish initialization of dof map for cells
23601
virtual void init_cell_finalize()
23606
/// Return the dimension of the global finite element function space
23607
virtual unsigned int global_dimension() const
23609
return __global_dimension;
23612
/// Return the dimension of the local finite element function space for a cell
23613
virtual unsigned int local_dimension(const ufc::cell& c) const
23618
/// Return the maximum dimension of the local finite element function space
23619
virtual unsigned int max_local_dimension() const
23624
// Return the geometric dimension of the coordinates this dof map provides
23625
virtual unsigned int geometric_dimension() const
23630
/// Return the number of dofs on each cell facet
23631
virtual unsigned int num_facet_dofs() const
23636
/// Return the number of dofs associated with each cell entity of dimension d
23637
virtual unsigned int num_entity_dofs(unsigned int d) const
23639
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23642
/// Tabulate the local-to-global mapping of dofs on a cell
23643
virtual void tabulate_dofs(unsigned int* dofs,
23644
const ufc::mesh& m,
23645
const ufc::cell& c) const
23647
dofs[0] = c.entity_indices[0][0];
23648
dofs[1] = c.entity_indices[0][1];
23649
dofs[2] = c.entity_indices[0][2];
23650
dofs[3] = c.entity_indices[0][3];
23653
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
23654
virtual void tabulate_facet_dofs(unsigned int* dofs,
23655
unsigned int facet) const
23682
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
23683
virtual void tabulate_entity_dofs(unsigned int* dofs,
23684
unsigned int d, unsigned int i) const
23686
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23689
/// Tabulate the coordinates of all dofs on a cell
23690
virtual void tabulate_coordinates(double** coordinates,
23691
const ufc::cell& c) const
23693
const double * const * x = c.coordinates;
23694
coordinates[0][0] = x[0][0];
23695
coordinates[0][1] = x[0][1];
23696
coordinates[0][2] = x[0][2];
23697
coordinates[1][0] = x[1][0];
23698
coordinates[1][1] = x[1][1];
23699
coordinates[1][2] = x[1][2];
23700
coordinates[2][0] = x[2][0];
23701
coordinates[2][1] = x[2][1];
23702
coordinates[2][2] = x[2][2];
23703
coordinates[3][0] = x[3][0];
23704
coordinates[3][1] = x[3][1];
23705
coordinates[3][2] = x[3][2];
23708
/// Return the number of sub dof maps (for a mixed element)
23709
virtual unsigned int num_sub_dof_maps() const
23714
/// Create a new dof_map for sub dof map i (for a mixed element)
23715
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
23717
return new hyperelasticity_1_dof_map_1_0();
23722
/// This class defines the interface for a local-to-global mapping of
23723
/// degrees of freedom (dofs).
23725
class hyperelasticity_1_dof_map_1_1: public ufc::dof_map
23729
unsigned int __global_dimension;
23734
hyperelasticity_1_dof_map_1_1() : ufc::dof_map()
23736
__global_dimension = 0;
23740
virtual ~hyperelasticity_1_dof_map_1_1()
23745
/// Return a string identifying the dof map
23746
virtual const char* signature() const
23748
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
23751
/// Return true iff mesh entities of topological dimension d are needed
23752
virtual bool needs_mesh_entities(unsigned int d) const
23772
/// Initialize dof map for mesh (return true iff init_cell() is needed)
23773
virtual bool init_mesh(const ufc::mesh& m)
23775
__global_dimension = m.num_entities[0];
23779
/// Initialize dof map for given cell
23780
virtual void init_cell(const ufc::mesh& m,
23781
const ufc::cell& c)
23786
/// Finish initialization of dof map for cells
23787
virtual void init_cell_finalize()
23792
/// Return the dimension of the global finite element function space
23793
virtual unsigned int global_dimension() const
23795
return __global_dimension;
23798
/// Return the dimension of the local finite element function space for a cell
23799
virtual unsigned int local_dimension(const ufc::cell& c) const
23804
/// Return the maximum dimension of the local finite element function space
23805
virtual unsigned int max_local_dimension() const
23810
// Return the geometric dimension of the coordinates this dof map provides
23811
virtual unsigned int geometric_dimension() const
23816
/// Return the number of dofs on each cell facet
23817
virtual unsigned int num_facet_dofs() const
23822
/// Return the number of dofs associated with each cell entity of dimension d
23823
virtual unsigned int num_entity_dofs(unsigned int d) const
23825
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23828
/// Tabulate the local-to-global mapping of dofs on a cell
23829
virtual void tabulate_dofs(unsigned int* dofs,
23830
const ufc::mesh& m,
23831
const ufc::cell& c) const
23833
dofs[0] = c.entity_indices[0][0];
23834
dofs[1] = c.entity_indices[0][1];
23835
dofs[2] = c.entity_indices[0][2];
23836
dofs[3] = c.entity_indices[0][3];
23839
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
23840
virtual void tabulate_facet_dofs(unsigned int* dofs,
23841
unsigned int facet) const
23868
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
23869
virtual void tabulate_entity_dofs(unsigned int* dofs,
23870
unsigned int d, unsigned int i) const
23872
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
23875
/// Tabulate the coordinates of all dofs on a cell
23876
virtual void tabulate_coordinates(double** coordinates,
23877
const ufc::cell& c) const
23879
const double * const * x = c.coordinates;
23880
coordinates[0][0] = x[0][0];
23881
coordinates[0][1] = x[0][1];
23882
coordinates[0][2] = x[0][2];
23883
coordinates[1][0] = x[1][0];
23884
coordinates[1][1] = x[1][1];
23885
coordinates[1][2] = x[1][2];
23886
coordinates[2][0] = x[2][0];
23887
coordinates[2][1] = x[2][1];
23888
coordinates[2][2] = x[2][2];
23889
coordinates[3][0] = x[3][0];
23890
coordinates[3][1] = x[3][1];
23891
coordinates[3][2] = x[3][2];
23894
/// Return the number of sub dof maps (for a mixed element)
23895
virtual unsigned int num_sub_dof_maps() const
23900
/// Create a new dof_map for sub dof map i (for a mixed element)
23901
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
23903
return new hyperelasticity_1_dof_map_1_1();
23908
/// This class defines the interface for a local-to-global mapping of
23909
/// degrees of freedom (dofs).
23911
class hyperelasticity_1_dof_map_1_2: public ufc::dof_map
23915
unsigned int __global_dimension;
23920
hyperelasticity_1_dof_map_1_2() : ufc::dof_map()
23922
__global_dimension = 0;
23926
virtual ~hyperelasticity_1_dof_map_1_2()
23931
/// Return a string identifying the dof map
23932
virtual const char* signature() const
23934
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
23937
/// Return true iff mesh entities of topological dimension d are needed
23938
virtual bool needs_mesh_entities(unsigned int d) const
23958
/// Initialize dof map for mesh (return true iff init_cell() is needed)
23959
virtual bool init_mesh(const ufc::mesh& m)
23961
__global_dimension = m.num_entities[0];
23965
/// Initialize dof map for given cell
23966
virtual void init_cell(const ufc::mesh& m,
23967
const ufc::cell& c)
23972
/// Finish initialization of dof map for cells
23973
virtual void init_cell_finalize()
23978
/// Return the dimension of the global finite element function space
23979
virtual unsigned int global_dimension() const
23981
return __global_dimension;
23984
/// Return the dimension of the local finite element function space for a cell
23985
virtual unsigned int local_dimension(const ufc::cell& c) const
23990
/// Return the maximum dimension of the local finite element function space
23991
virtual unsigned int max_local_dimension() const
23996
// Return the geometric dimension of the coordinates this dof map provides
23997
virtual unsigned int geometric_dimension() const
24002
/// Return the number of dofs on each cell facet
24003
virtual unsigned int num_facet_dofs() const
24008
/// Return the number of dofs associated with each cell entity of dimension d
24009
virtual unsigned int num_entity_dofs(unsigned int d) const
24011
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24014
/// Tabulate the local-to-global mapping of dofs on a cell
24015
virtual void tabulate_dofs(unsigned int* dofs,
24016
const ufc::mesh& m,
24017
const ufc::cell& c) const
24019
dofs[0] = c.entity_indices[0][0];
24020
dofs[1] = c.entity_indices[0][1];
24021
dofs[2] = c.entity_indices[0][2];
24022
dofs[3] = c.entity_indices[0][3];
24025
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
24026
virtual void tabulate_facet_dofs(unsigned int* dofs,
24027
unsigned int facet) const
24054
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
24055
virtual void tabulate_entity_dofs(unsigned int* dofs,
24056
unsigned int d, unsigned int i) const
24058
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24061
/// Tabulate the coordinates of all dofs on a cell
24062
virtual void tabulate_coordinates(double** coordinates,
24063
const ufc::cell& c) const
24065
const double * const * x = c.coordinates;
24066
coordinates[0][0] = x[0][0];
24067
coordinates[0][1] = x[0][1];
24068
coordinates[0][2] = x[0][2];
24069
coordinates[1][0] = x[1][0];
24070
coordinates[1][1] = x[1][1];
24071
coordinates[1][2] = x[1][2];
24072
coordinates[2][0] = x[2][0];
24073
coordinates[2][1] = x[2][1];
24074
coordinates[2][2] = x[2][2];
24075
coordinates[3][0] = x[3][0];
24076
coordinates[3][1] = x[3][1];
24077
coordinates[3][2] = x[3][2];
24080
/// Return the number of sub dof maps (for a mixed element)
24081
virtual unsigned int num_sub_dof_maps() const
24086
/// Create a new dof_map for sub dof map i (for a mixed element)
24087
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
24089
return new hyperelasticity_1_dof_map_1_2();
24094
/// This class defines the interface for a local-to-global mapping of
24095
/// degrees of freedom (dofs).
24097
class hyperelasticity_1_dof_map_1: public ufc::dof_map
24101
unsigned int __global_dimension;
24106
hyperelasticity_1_dof_map_1() : ufc::dof_map()
24108
__global_dimension = 0;
24112
virtual ~hyperelasticity_1_dof_map_1()
24117
/// Return a string identifying the dof map
24118
virtual const char* signature() const
24120
return "FFC dof map for VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
24123
/// Return true iff mesh entities of topological dimension d are needed
24124
virtual bool needs_mesh_entities(unsigned int d) const
24144
/// Initialize dof map for mesh (return true iff init_cell() is needed)
24145
virtual bool init_mesh(const ufc::mesh& m)
24147
__global_dimension = 3*m.num_entities[0];
24151
/// Initialize dof map for given cell
24152
virtual void init_cell(const ufc::mesh& m,
24153
const ufc::cell& c)
24158
/// Finish initialization of dof map for cells
24159
virtual void init_cell_finalize()
24164
/// Return the dimension of the global finite element function space
24165
virtual unsigned int global_dimension() const
24167
return __global_dimension;
24170
/// Return the dimension of the local finite element function space for a cell
24171
virtual unsigned int local_dimension(const ufc::cell& c) const
24176
/// Return the maximum dimension of the local finite element function space
24177
virtual unsigned int max_local_dimension() const
24182
// Return the geometric dimension of the coordinates this dof map provides
24183
virtual unsigned int geometric_dimension() const
24188
/// Return the number of dofs on each cell facet
24189
virtual unsigned int num_facet_dofs() const
24194
/// Return the number of dofs associated with each cell entity of dimension d
24195
virtual unsigned int num_entity_dofs(unsigned int d) const
24197
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24200
/// Tabulate the local-to-global mapping of dofs on a cell
24201
virtual void tabulate_dofs(unsigned int* dofs,
24202
const ufc::mesh& m,
24203
const ufc::cell& c) const
24205
dofs[0] = c.entity_indices[0][0];
24206
dofs[1] = c.entity_indices[0][1];
24207
dofs[2] = c.entity_indices[0][2];
24208
dofs[3] = c.entity_indices[0][3];
24209
unsigned int offset = m.num_entities[0];
24210
dofs[4] = offset + c.entity_indices[0][0];
24211
dofs[5] = offset + c.entity_indices[0][1];
24212
dofs[6] = offset + c.entity_indices[0][2];
24213
dofs[7] = offset + c.entity_indices[0][3];
24214
offset = offset + m.num_entities[0];
24215
dofs[8] = offset + c.entity_indices[0][0];
24216
dofs[9] = offset + c.entity_indices[0][1];
24217
dofs[10] = offset + c.entity_indices[0][2];
24218
dofs[11] = offset + c.entity_indices[0][3];
24221
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
24222
virtual void tabulate_facet_dofs(unsigned int* dofs,
24223
unsigned int facet) const
24274
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
24275
virtual void tabulate_entity_dofs(unsigned int* dofs,
24276
unsigned int d, unsigned int i) const
24278
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24281
/// Tabulate the coordinates of all dofs on a cell
24282
virtual void tabulate_coordinates(double** coordinates,
24283
const ufc::cell& c) const
24285
const double * const * x = c.coordinates;
24286
coordinates[0][0] = x[0][0];
24287
coordinates[0][1] = x[0][1];
24288
coordinates[0][2] = x[0][2];
24289
coordinates[1][0] = x[1][0];
24290
coordinates[1][1] = x[1][1];
24291
coordinates[1][2] = x[1][2];
24292
coordinates[2][0] = x[2][0];
24293
coordinates[2][1] = x[2][1];
24294
coordinates[2][2] = x[2][2];
24295
coordinates[3][0] = x[3][0];
24296
coordinates[3][1] = x[3][1];
24297
coordinates[3][2] = x[3][2];
24298
coordinates[4][0] = x[0][0];
24299
coordinates[4][1] = x[0][1];
24300
coordinates[4][2] = x[0][2];
24301
coordinates[5][0] = x[1][0];
24302
coordinates[5][1] = x[1][1];
24303
coordinates[5][2] = x[1][2];
24304
coordinates[6][0] = x[2][0];
24305
coordinates[6][1] = x[2][1];
24306
coordinates[6][2] = x[2][2];
24307
coordinates[7][0] = x[3][0];
24308
coordinates[7][1] = x[3][1];
24309
coordinates[7][2] = x[3][2];
24310
coordinates[8][0] = x[0][0];
24311
coordinates[8][1] = x[0][1];
24312
coordinates[8][2] = x[0][2];
24313
coordinates[9][0] = x[1][0];
24314
coordinates[9][1] = x[1][1];
24315
coordinates[9][2] = x[1][2];
24316
coordinates[10][0] = x[2][0];
24317
coordinates[10][1] = x[2][1];
24318
coordinates[10][2] = x[2][2];
24319
coordinates[11][0] = x[3][0];
24320
coordinates[11][1] = x[3][1];
24321
coordinates[11][2] = x[3][2];
24324
/// Return the number of sub dof maps (for a mixed element)
24325
virtual unsigned int num_sub_dof_maps() const
24330
/// Create a new dof_map for sub dof map i (for a mixed element)
24331
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
24336
return new hyperelasticity_1_dof_map_1_0();
24339
return new hyperelasticity_1_dof_map_1_1();
24342
return new hyperelasticity_1_dof_map_1_2();
24350
/// This class defines the interface for a local-to-global mapping of
24351
/// degrees of freedom (dofs).
24353
class hyperelasticity_1_dof_map_2_0: public ufc::dof_map
24357
unsigned int __global_dimension;
24362
hyperelasticity_1_dof_map_2_0() : ufc::dof_map()
24364
__global_dimension = 0;
24368
virtual ~hyperelasticity_1_dof_map_2_0()
24373
/// Return a string identifying the dof map
24374
virtual const char* signature() const
24376
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
24379
/// Return true iff mesh entities of topological dimension d are needed
24380
virtual bool needs_mesh_entities(unsigned int d) const
24400
/// Initialize dof map for mesh (return true iff init_cell() is needed)
24401
virtual bool init_mesh(const ufc::mesh& m)
24403
__global_dimension = m.num_entities[0];
24407
/// Initialize dof map for given cell
24408
virtual void init_cell(const ufc::mesh& m,
24409
const ufc::cell& c)
24414
/// Finish initialization of dof map for cells
24415
virtual void init_cell_finalize()
24420
/// Return the dimension of the global finite element function space
24421
virtual unsigned int global_dimension() const
24423
return __global_dimension;
24426
/// Return the dimension of the local finite element function space for a cell
24427
virtual unsigned int local_dimension(const ufc::cell& c) const
24432
/// Return the maximum dimension of the local finite element function space
24433
virtual unsigned int max_local_dimension() const
24438
// Return the geometric dimension of the coordinates this dof map provides
24439
virtual unsigned int geometric_dimension() const
24444
/// Return the number of dofs on each cell facet
24445
virtual unsigned int num_facet_dofs() const
24450
/// Return the number of dofs associated with each cell entity of dimension d
24451
virtual unsigned int num_entity_dofs(unsigned int d) const
24453
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24456
/// Tabulate the local-to-global mapping of dofs on a cell
24457
virtual void tabulate_dofs(unsigned int* dofs,
24458
const ufc::mesh& m,
24459
const ufc::cell& c) const
24461
dofs[0] = c.entity_indices[0][0];
24462
dofs[1] = c.entity_indices[0][1];
24463
dofs[2] = c.entity_indices[0][2];
24464
dofs[3] = c.entity_indices[0][3];
24467
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
24468
virtual void tabulate_facet_dofs(unsigned int* dofs,
24469
unsigned int facet) const
24496
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
24497
virtual void tabulate_entity_dofs(unsigned int* dofs,
24498
unsigned int d, unsigned int i) const
24500
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24503
/// Tabulate the coordinates of all dofs on a cell
24504
virtual void tabulate_coordinates(double** coordinates,
24505
const ufc::cell& c) const
24507
const double * const * x = c.coordinates;
24508
coordinates[0][0] = x[0][0];
24509
coordinates[0][1] = x[0][1];
24510
coordinates[0][2] = x[0][2];
24511
coordinates[1][0] = x[1][0];
24512
coordinates[1][1] = x[1][1];
24513
coordinates[1][2] = x[1][2];
24514
coordinates[2][0] = x[2][0];
24515
coordinates[2][1] = x[2][1];
24516
coordinates[2][2] = x[2][2];
24517
coordinates[3][0] = x[3][0];
24518
coordinates[3][1] = x[3][1];
24519
coordinates[3][2] = x[3][2];
24522
/// Return the number of sub dof maps (for a mixed element)
24523
virtual unsigned int num_sub_dof_maps() const
24528
/// Create a new dof_map for sub dof map i (for a mixed element)
24529
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
24531
return new hyperelasticity_1_dof_map_2_0();
24536
/// This class defines the interface for a local-to-global mapping of
24537
/// degrees of freedom (dofs).
24539
class hyperelasticity_1_dof_map_2_1: public ufc::dof_map
24543
unsigned int __global_dimension;
24548
hyperelasticity_1_dof_map_2_1() : ufc::dof_map()
24550
__global_dimension = 0;
24554
virtual ~hyperelasticity_1_dof_map_2_1()
24559
/// Return a string identifying the dof map
24560
virtual const char* signature() const
24562
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
24565
/// Return true iff mesh entities of topological dimension d are needed
24566
virtual bool needs_mesh_entities(unsigned int d) const
24586
/// Initialize dof map for mesh (return true iff init_cell() is needed)
24587
virtual bool init_mesh(const ufc::mesh& m)
24589
__global_dimension = m.num_entities[0];
24593
/// Initialize dof map for given cell
24594
virtual void init_cell(const ufc::mesh& m,
24595
const ufc::cell& c)
24600
/// Finish initialization of dof map for cells
24601
virtual void init_cell_finalize()
24606
/// Return the dimension of the global finite element function space
24607
virtual unsigned int global_dimension() const
24609
return __global_dimension;
24612
/// Return the dimension of the local finite element function space for a cell
24613
virtual unsigned int local_dimension(const ufc::cell& c) const
24618
/// Return the maximum dimension of the local finite element function space
24619
virtual unsigned int max_local_dimension() const
24624
// Return the geometric dimension of the coordinates this dof map provides
24625
virtual unsigned int geometric_dimension() const
24630
/// Return the number of dofs on each cell facet
24631
virtual unsigned int num_facet_dofs() const
24636
/// Return the number of dofs associated with each cell entity of dimension d
24637
virtual unsigned int num_entity_dofs(unsigned int d) const
24639
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24642
/// Tabulate the local-to-global mapping of dofs on a cell
24643
virtual void tabulate_dofs(unsigned int* dofs,
24644
const ufc::mesh& m,
24645
const ufc::cell& c) const
24647
dofs[0] = c.entity_indices[0][0];
24648
dofs[1] = c.entity_indices[0][1];
24649
dofs[2] = c.entity_indices[0][2];
24650
dofs[3] = c.entity_indices[0][3];
24653
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
24654
virtual void tabulate_facet_dofs(unsigned int* dofs,
24655
unsigned int facet) const
24682
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
24683
virtual void tabulate_entity_dofs(unsigned int* dofs,
24684
unsigned int d, unsigned int i) const
24686
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24689
/// Tabulate the coordinates of all dofs on a cell
24690
virtual void tabulate_coordinates(double** coordinates,
24691
const ufc::cell& c) const
24693
const double * const * x = c.coordinates;
24694
coordinates[0][0] = x[0][0];
24695
coordinates[0][1] = x[0][1];
24696
coordinates[0][2] = x[0][2];
24697
coordinates[1][0] = x[1][0];
24698
coordinates[1][1] = x[1][1];
24699
coordinates[1][2] = x[1][2];
24700
coordinates[2][0] = x[2][0];
24701
coordinates[2][1] = x[2][1];
24702
coordinates[2][2] = x[2][2];
24703
coordinates[3][0] = x[3][0];
24704
coordinates[3][1] = x[3][1];
24705
coordinates[3][2] = x[3][2];
24708
/// Return the number of sub dof maps (for a mixed element)
24709
virtual unsigned int num_sub_dof_maps() const
24714
/// Create a new dof_map for sub dof map i (for a mixed element)
24715
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
24717
return new hyperelasticity_1_dof_map_2_1();
24722
/// This class defines the interface for a local-to-global mapping of
24723
/// degrees of freedom (dofs).
24725
class hyperelasticity_1_dof_map_2_2: public ufc::dof_map
24729
unsigned int __global_dimension;
24734
hyperelasticity_1_dof_map_2_2() : ufc::dof_map()
24736
__global_dimension = 0;
24740
virtual ~hyperelasticity_1_dof_map_2_2()
24745
/// Return a string identifying the dof map
24746
virtual const char* signature() const
24748
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
24751
/// Return true iff mesh entities of topological dimension d are needed
24752
virtual bool needs_mesh_entities(unsigned int d) const
24772
/// Initialize dof map for mesh (return true iff init_cell() is needed)
24773
virtual bool init_mesh(const ufc::mesh& m)
24775
__global_dimension = m.num_entities[0];
24779
/// Initialize dof map for given cell
24780
virtual void init_cell(const ufc::mesh& m,
24781
const ufc::cell& c)
24786
/// Finish initialization of dof map for cells
24787
virtual void init_cell_finalize()
24792
/// Return the dimension of the global finite element function space
24793
virtual unsigned int global_dimension() const
24795
return __global_dimension;
24798
/// Return the dimension of the local finite element function space for a cell
24799
virtual unsigned int local_dimension(const ufc::cell& c) const
24804
/// Return the maximum dimension of the local finite element function space
24805
virtual unsigned int max_local_dimension() const
24810
// Return the geometric dimension of the coordinates this dof map provides
24811
virtual unsigned int geometric_dimension() const
24816
/// Return the number of dofs on each cell facet
24817
virtual unsigned int num_facet_dofs() const
24822
/// Return the number of dofs associated with each cell entity of dimension d
24823
virtual unsigned int num_entity_dofs(unsigned int d) const
24825
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24828
/// Tabulate the local-to-global mapping of dofs on a cell
24829
virtual void tabulate_dofs(unsigned int* dofs,
24830
const ufc::mesh& m,
24831
const ufc::cell& c) const
24833
dofs[0] = c.entity_indices[0][0];
24834
dofs[1] = c.entity_indices[0][1];
24835
dofs[2] = c.entity_indices[0][2];
24836
dofs[3] = c.entity_indices[0][3];
24839
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
24840
virtual void tabulate_facet_dofs(unsigned int* dofs,
24841
unsigned int facet) const
24868
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
24869
virtual void tabulate_entity_dofs(unsigned int* dofs,
24870
unsigned int d, unsigned int i) const
24872
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
24875
/// Tabulate the coordinates of all dofs on a cell
24876
virtual void tabulate_coordinates(double** coordinates,
24877
const ufc::cell& c) const
24879
const double * const * x = c.coordinates;
24880
coordinates[0][0] = x[0][0];
24881
coordinates[0][1] = x[0][1];
24882
coordinates[0][2] = x[0][2];
24883
coordinates[1][0] = x[1][0];
24884
coordinates[1][1] = x[1][1];
24885
coordinates[1][2] = x[1][2];
24886
coordinates[2][0] = x[2][0];
24887
coordinates[2][1] = x[2][1];
24888
coordinates[2][2] = x[2][2];
24889
coordinates[3][0] = x[3][0];
24890
coordinates[3][1] = x[3][1];
24891
coordinates[3][2] = x[3][2];
24894
/// Return the number of sub dof maps (for a mixed element)
24895
virtual unsigned int num_sub_dof_maps() const
24900
/// Create a new dof_map for sub dof map i (for a mixed element)
24901
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
24903
return new hyperelasticity_1_dof_map_2_2();
24908
/// This class defines the interface for a local-to-global mapping of
24909
/// degrees of freedom (dofs).
24911
class hyperelasticity_1_dof_map_2: public ufc::dof_map
24915
unsigned int __global_dimension;
24920
hyperelasticity_1_dof_map_2() : ufc::dof_map()
24922
__global_dimension = 0;
24926
virtual ~hyperelasticity_1_dof_map_2()
24931
/// Return a string identifying the dof map
24932
virtual const char* signature() const
24934
return "FFC dof map for VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
24937
/// Return true iff mesh entities of topological dimension d are needed
24938
virtual bool needs_mesh_entities(unsigned int d) const
24958
/// Initialize dof map for mesh (return true iff init_cell() is needed)
24959
virtual bool init_mesh(const ufc::mesh& m)
24961
__global_dimension = 3*m.num_entities[0];
24965
/// Initialize dof map for given cell
24966
virtual void init_cell(const ufc::mesh& m,
24967
const ufc::cell& c)
24972
/// Finish initialization of dof map for cells
24973
virtual void init_cell_finalize()
24978
/// Return the dimension of the global finite element function space
24979
virtual unsigned int global_dimension() const
24981
return __global_dimension;
24984
/// Return the dimension of the local finite element function space for a cell
24985
virtual unsigned int local_dimension(const ufc::cell& c) const
24990
/// Return the maximum dimension of the local finite element function space
24991
virtual unsigned int max_local_dimension() const
24996
// Return the geometric dimension of the coordinates this dof map provides
24997
virtual unsigned int geometric_dimension() const
25002
/// Return the number of dofs on each cell facet
25003
virtual unsigned int num_facet_dofs() const
25008
/// Return the number of dofs associated with each cell entity of dimension d
25009
virtual unsigned int num_entity_dofs(unsigned int d) const
25011
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25014
/// Tabulate the local-to-global mapping of dofs on a cell
25015
virtual void tabulate_dofs(unsigned int* dofs,
25016
const ufc::mesh& m,
25017
const ufc::cell& c) const
25019
dofs[0] = c.entity_indices[0][0];
25020
dofs[1] = c.entity_indices[0][1];
25021
dofs[2] = c.entity_indices[0][2];
25022
dofs[3] = c.entity_indices[0][3];
25023
unsigned int offset = m.num_entities[0];
25024
dofs[4] = offset + c.entity_indices[0][0];
25025
dofs[5] = offset + c.entity_indices[0][1];
25026
dofs[6] = offset + c.entity_indices[0][2];
25027
dofs[7] = offset + c.entity_indices[0][3];
25028
offset = offset + m.num_entities[0];
25029
dofs[8] = offset + c.entity_indices[0][0];
25030
dofs[9] = offset + c.entity_indices[0][1];
25031
dofs[10] = offset + c.entity_indices[0][2];
25032
dofs[11] = offset + c.entity_indices[0][3];
25035
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
25036
virtual void tabulate_facet_dofs(unsigned int* dofs,
25037
unsigned int facet) const
25088
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
25089
virtual void tabulate_entity_dofs(unsigned int* dofs,
25090
unsigned int d, unsigned int i) const
25092
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25095
/// Tabulate the coordinates of all dofs on a cell
25096
virtual void tabulate_coordinates(double** coordinates,
25097
const ufc::cell& c) const
25099
const double * const * x = c.coordinates;
25100
coordinates[0][0] = x[0][0];
25101
coordinates[0][1] = x[0][1];
25102
coordinates[0][2] = x[0][2];
25103
coordinates[1][0] = x[1][0];
25104
coordinates[1][1] = x[1][1];
25105
coordinates[1][2] = x[1][2];
25106
coordinates[2][0] = x[2][0];
25107
coordinates[2][1] = x[2][1];
25108
coordinates[2][2] = x[2][2];
25109
coordinates[3][0] = x[3][0];
25110
coordinates[3][1] = x[3][1];
25111
coordinates[3][2] = x[3][2];
25112
coordinates[4][0] = x[0][0];
25113
coordinates[4][1] = x[0][1];
25114
coordinates[4][2] = x[0][2];
25115
coordinates[5][0] = x[1][0];
25116
coordinates[5][1] = x[1][1];
25117
coordinates[5][2] = x[1][2];
25118
coordinates[6][0] = x[2][0];
25119
coordinates[6][1] = x[2][1];
25120
coordinates[6][2] = x[2][2];
25121
coordinates[7][0] = x[3][0];
25122
coordinates[7][1] = x[3][1];
25123
coordinates[7][2] = x[3][2];
25124
coordinates[8][0] = x[0][0];
25125
coordinates[8][1] = x[0][1];
25126
coordinates[8][2] = x[0][2];
25127
coordinates[9][0] = x[1][0];
25128
coordinates[9][1] = x[1][1];
25129
coordinates[9][2] = x[1][2];
25130
coordinates[10][0] = x[2][0];
25131
coordinates[10][1] = x[2][1];
25132
coordinates[10][2] = x[2][2];
25133
coordinates[11][0] = x[3][0];
25134
coordinates[11][1] = x[3][1];
25135
coordinates[11][2] = x[3][2];
25138
/// Return the number of sub dof maps (for a mixed element)
25139
virtual unsigned int num_sub_dof_maps() const
25144
/// Create a new dof_map for sub dof map i (for a mixed element)
25145
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
25150
return new hyperelasticity_1_dof_map_2_0();
25153
return new hyperelasticity_1_dof_map_2_1();
25156
return new hyperelasticity_1_dof_map_2_2();
25164
/// This class defines the interface for a local-to-global mapping of
25165
/// degrees of freedom (dofs).
25167
class hyperelasticity_1_dof_map_3_0: public ufc::dof_map
25171
unsigned int __global_dimension;
25176
hyperelasticity_1_dof_map_3_0() : ufc::dof_map()
25178
__global_dimension = 0;
25182
virtual ~hyperelasticity_1_dof_map_3_0()
25187
/// Return a string identifying the dof map
25188
virtual const char* signature() const
25190
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
25193
/// Return true iff mesh entities of topological dimension d are needed
25194
virtual bool needs_mesh_entities(unsigned int d) const
25214
/// Initialize dof map for mesh (return true iff init_cell() is needed)
25215
virtual bool init_mesh(const ufc::mesh& m)
25217
__global_dimension = m.num_entities[0];
25221
/// Initialize dof map for given cell
25222
virtual void init_cell(const ufc::mesh& m,
25223
const ufc::cell& c)
25228
/// Finish initialization of dof map for cells
25229
virtual void init_cell_finalize()
25234
/// Return the dimension of the global finite element function space
25235
virtual unsigned int global_dimension() const
25237
return __global_dimension;
25240
/// Return the dimension of the local finite element function space for a cell
25241
virtual unsigned int local_dimension(const ufc::cell& c) const
25246
/// Return the maximum dimension of the local finite element function space
25247
virtual unsigned int max_local_dimension() const
25252
// Return the geometric dimension of the coordinates this dof map provides
25253
virtual unsigned int geometric_dimension() const
25258
/// Return the number of dofs on each cell facet
25259
virtual unsigned int num_facet_dofs() const
25264
/// Return the number of dofs associated with each cell entity of dimension d
25265
virtual unsigned int num_entity_dofs(unsigned int d) const
25267
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25270
/// Tabulate the local-to-global mapping of dofs on a cell
25271
virtual void tabulate_dofs(unsigned int* dofs,
25272
const ufc::mesh& m,
25273
const ufc::cell& c) const
25275
dofs[0] = c.entity_indices[0][0];
25276
dofs[1] = c.entity_indices[0][1];
25277
dofs[2] = c.entity_indices[0][2];
25278
dofs[3] = c.entity_indices[0][3];
25281
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
25282
virtual void tabulate_facet_dofs(unsigned int* dofs,
25283
unsigned int facet) const
25310
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
25311
virtual void tabulate_entity_dofs(unsigned int* dofs,
25312
unsigned int d, unsigned int i) const
25314
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25317
/// Tabulate the coordinates of all dofs on a cell
25318
virtual void tabulate_coordinates(double** coordinates,
25319
const ufc::cell& c) const
25321
const double * const * x = c.coordinates;
25322
coordinates[0][0] = x[0][0];
25323
coordinates[0][1] = x[0][1];
25324
coordinates[0][2] = x[0][2];
25325
coordinates[1][0] = x[1][0];
25326
coordinates[1][1] = x[1][1];
25327
coordinates[1][2] = x[1][2];
25328
coordinates[2][0] = x[2][0];
25329
coordinates[2][1] = x[2][1];
25330
coordinates[2][2] = x[2][2];
25331
coordinates[3][0] = x[3][0];
25332
coordinates[3][1] = x[3][1];
25333
coordinates[3][2] = x[3][2];
25336
/// Return the number of sub dof maps (for a mixed element)
25337
virtual unsigned int num_sub_dof_maps() const
25342
/// Create a new dof_map for sub dof map i (for a mixed element)
25343
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
25345
return new hyperelasticity_1_dof_map_3_0();
25350
/// This class defines the interface for a local-to-global mapping of
25351
/// degrees of freedom (dofs).
25353
class hyperelasticity_1_dof_map_3_1: public ufc::dof_map
25357
unsigned int __global_dimension;
25362
hyperelasticity_1_dof_map_3_1() : ufc::dof_map()
25364
__global_dimension = 0;
25368
virtual ~hyperelasticity_1_dof_map_3_1()
25373
/// Return a string identifying the dof map
25374
virtual const char* signature() const
25376
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
25379
/// Return true iff mesh entities of topological dimension d are needed
25380
virtual bool needs_mesh_entities(unsigned int d) const
25400
/// Initialize dof map for mesh (return true iff init_cell() is needed)
25401
virtual bool init_mesh(const ufc::mesh& m)
25403
__global_dimension = m.num_entities[0];
25407
/// Initialize dof map for given cell
25408
virtual void init_cell(const ufc::mesh& m,
25409
const ufc::cell& c)
25414
/// Finish initialization of dof map for cells
25415
virtual void init_cell_finalize()
25420
/// Return the dimension of the global finite element function space
25421
virtual unsigned int global_dimension() const
25423
return __global_dimension;
25426
/// Return the dimension of the local finite element function space for a cell
25427
virtual unsigned int local_dimension(const ufc::cell& c) const
25432
/// Return the maximum dimension of the local finite element function space
25433
virtual unsigned int max_local_dimension() const
25438
// Return the geometric dimension of the coordinates this dof map provides
25439
virtual unsigned int geometric_dimension() const
25444
/// Return the number of dofs on each cell facet
25445
virtual unsigned int num_facet_dofs() const
25450
/// Return the number of dofs associated with each cell entity of dimension d
25451
virtual unsigned int num_entity_dofs(unsigned int d) const
25453
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25456
/// Tabulate the local-to-global mapping of dofs on a cell
25457
virtual void tabulate_dofs(unsigned int* dofs,
25458
const ufc::mesh& m,
25459
const ufc::cell& c) const
25461
dofs[0] = c.entity_indices[0][0];
25462
dofs[1] = c.entity_indices[0][1];
25463
dofs[2] = c.entity_indices[0][2];
25464
dofs[3] = c.entity_indices[0][3];
25467
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
25468
virtual void tabulate_facet_dofs(unsigned int* dofs,
25469
unsigned int facet) const
25496
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
25497
virtual void tabulate_entity_dofs(unsigned int* dofs,
25498
unsigned int d, unsigned int i) const
25500
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25503
/// Tabulate the coordinates of all dofs on a cell
25504
virtual void tabulate_coordinates(double** coordinates,
25505
const ufc::cell& c) const
25507
const double * const * x = c.coordinates;
25508
coordinates[0][0] = x[0][0];
25509
coordinates[0][1] = x[0][1];
25510
coordinates[0][2] = x[0][2];
25511
coordinates[1][0] = x[1][0];
25512
coordinates[1][1] = x[1][1];
25513
coordinates[1][2] = x[1][2];
25514
coordinates[2][0] = x[2][0];
25515
coordinates[2][1] = x[2][1];
25516
coordinates[2][2] = x[2][2];
25517
coordinates[3][0] = x[3][0];
25518
coordinates[3][1] = x[3][1];
25519
coordinates[3][2] = x[3][2];
25522
/// Return the number of sub dof maps (for a mixed element)
25523
virtual unsigned int num_sub_dof_maps() const
25528
/// Create a new dof_map for sub dof map i (for a mixed element)
25529
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
25531
return new hyperelasticity_1_dof_map_3_1();
25536
/// This class defines the interface for a local-to-global mapping of
25537
/// degrees of freedom (dofs).
25539
class hyperelasticity_1_dof_map_3_2: public ufc::dof_map
25543
unsigned int __global_dimension;
25548
hyperelasticity_1_dof_map_3_2() : ufc::dof_map()
25550
__global_dimension = 0;
25554
virtual ~hyperelasticity_1_dof_map_3_2()
25559
/// Return a string identifying the dof map
25560
virtual const char* signature() const
25562
return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
25565
/// Return true iff mesh entities of topological dimension d are needed
25566
virtual bool needs_mesh_entities(unsigned int d) const
25586
/// Initialize dof map for mesh (return true iff init_cell() is needed)
25587
virtual bool init_mesh(const ufc::mesh& m)
25589
__global_dimension = m.num_entities[0];
25593
/// Initialize dof map for given cell
25594
virtual void init_cell(const ufc::mesh& m,
25595
const ufc::cell& c)
25600
/// Finish initialization of dof map for cells
25601
virtual void init_cell_finalize()
25606
/// Return the dimension of the global finite element function space
25607
virtual unsigned int global_dimension() const
25609
return __global_dimension;
25612
/// Return the dimension of the local finite element function space for a cell
25613
virtual unsigned int local_dimension(const ufc::cell& c) const
25618
/// Return the maximum dimension of the local finite element function space
25619
virtual unsigned int max_local_dimension() const
25624
// Return the geometric dimension of the coordinates this dof map provides
25625
virtual unsigned int geometric_dimension() const
25630
/// Return the number of dofs on each cell facet
25631
virtual unsigned int num_facet_dofs() const
25636
/// Return the number of dofs associated with each cell entity of dimension d
25637
virtual unsigned int num_entity_dofs(unsigned int d) const
25639
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25642
/// Tabulate the local-to-global mapping of dofs on a cell
25643
virtual void tabulate_dofs(unsigned int* dofs,
25644
const ufc::mesh& m,
25645
const ufc::cell& c) const
25647
dofs[0] = c.entity_indices[0][0];
25648
dofs[1] = c.entity_indices[0][1];
25649
dofs[2] = c.entity_indices[0][2];
25650
dofs[3] = c.entity_indices[0][3];
25653
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
25654
virtual void tabulate_facet_dofs(unsigned int* dofs,
25655
unsigned int facet) const
25682
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
25683
virtual void tabulate_entity_dofs(unsigned int* dofs,
25684
unsigned int d, unsigned int i) const
25686
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25689
/// Tabulate the coordinates of all dofs on a cell
25690
virtual void tabulate_coordinates(double** coordinates,
25691
const ufc::cell& c) const
25693
const double * const * x = c.coordinates;
25694
coordinates[0][0] = x[0][0];
25695
coordinates[0][1] = x[0][1];
25696
coordinates[0][2] = x[0][2];
25697
coordinates[1][0] = x[1][0];
25698
coordinates[1][1] = x[1][1];
25699
coordinates[1][2] = x[1][2];
25700
coordinates[2][0] = x[2][0];
25701
coordinates[2][1] = x[2][1];
25702
coordinates[2][2] = x[2][2];
25703
coordinates[3][0] = x[3][0];
25704
coordinates[3][1] = x[3][1];
25705
coordinates[3][2] = x[3][2];
25708
/// Return the number of sub dof maps (for a mixed element)
25709
virtual unsigned int num_sub_dof_maps() const
25714
/// Create a new dof_map for sub dof map i (for a mixed element)
25715
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
25717
return new hyperelasticity_1_dof_map_3_2();
25722
/// This class defines the interface for a local-to-global mapping of
25723
/// degrees of freedom (dofs).
25725
class hyperelasticity_1_dof_map_3: public ufc::dof_map
25729
unsigned int __global_dimension;
25734
hyperelasticity_1_dof_map_3() : ufc::dof_map()
25736
__global_dimension = 0;
25740
virtual ~hyperelasticity_1_dof_map_3()
25745
/// Return a string identifying the dof map
25746
virtual const char* signature() const
25748
return "FFC dof map for VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3)";
25751
/// Return true iff mesh entities of topological dimension d are needed
25752
virtual bool needs_mesh_entities(unsigned int d) const
25772
/// Initialize dof map for mesh (return true iff init_cell() is needed)
25773
virtual bool init_mesh(const ufc::mesh& m)
25775
__global_dimension = 3*m.num_entities[0];
25779
/// Initialize dof map for given cell
25780
virtual void init_cell(const ufc::mesh& m,
25781
const ufc::cell& c)
25786
/// Finish initialization of dof map for cells
25787
virtual void init_cell_finalize()
25792
/// Return the dimension of the global finite element function space
25793
virtual unsigned int global_dimension() const
25795
return __global_dimension;
25798
/// Return the dimension of the local finite element function space for a cell
25799
virtual unsigned int local_dimension(const ufc::cell& c) const
25804
/// Return the maximum dimension of the local finite element function space
25805
virtual unsigned int max_local_dimension() const
25810
// Return the geometric dimension of the coordinates this dof map provides
25811
virtual unsigned int geometric_dimension() const
25816
/// Return the number of dofs on each cell facet
25817
virtual unsigned int num_facet_dofs() const
25822
/// Return the number of dofs associated with each cell entity of dimension d
25823
virtual unsigned int num_entity_dofs(unsigned int d) const
25825
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25828
/// Tabulate the local-to-global mapping of dofs on a cell
25829
virtual void tabulate_dofs(unsigned int* dofs,
25830
const ufc::mesh& m,
25831
const ufc::cell& c) const
25833
dofs[0] = c.entity_indices[0][0];
25834
dofs[1] = c.entity_indices[0][1];
25835
dofs[2] = c.entity_indices[0][2];
25836
dofs[3] = c.entity_indices[0][3];
25837
unsigned int offset = m.num_entities[0];
25838
dofs[4] = offset + c.entity_indices[0][0];
25839
dofs[5] = offset + c.entity_indices[0][1];
25840
dofs[6] = offset + c.entity_indices[0][2];
25841
dofs[7] = offset + c.entity_indices[0][3];
25842
offset = offset + m.num_entities[0];
25843
dofs[8] = offset + c.entity_indices[0][0];
25844
dofs[9] = offset + c.entity_indices[0][1];
25845
dofs[10] = offset + c.entity_indices[0][2];
25846
dofs[11] = offset + c.entity_indices[0][3];
25849
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
25850
virtual void tabulate_facet_dofs(unsigned int* dofs,
25851
unsigned int facet) const
25902
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
25903
virtual void tabulate_entity_dofs(unsigned int* dofs,
25904
unsigned int d, unsigned int i) const
25906
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
25909
/// Tabulate the coordinates of all dofs on a cell
25910
virtual void tabulate_coordinates(double** coordinates,
25911
const ufc::cell& c) const
25913
const double * const * x = c.coordinates;
25914
coordinates[0][0] = x[0][0];
25915
coordinates[0][1] = x[0][1];
25916
coordinates[0][2] = x[0][2];
25917
coordinates[1][0] = x[1][0];
25918
coordinates[1][1] = x[1][1];
25919
coordinates[1][2] = x[1][2];
25920
coordinates[2][0] = x[2][0];
25921
coordinates[2][1] = x[2][1];
25922
coordinates[2][2] = x[2][2];
25923
coordinates[3][0] = x[3][0];
25924
coordinates[3][1] = x[3][1];
25925
coordinates[3][2] = x[3][2];
25926
coordinates[4][0] = x[0][0];
25927
coordinates[4][1] = x[0][1];
25928
coordinates[4][2] = x[0][2];
25929
coordinates[5][0] = x[1][0];
25930
coordinates[5][1] = x[1][1];
25931
coordinates[5][2] = x[1][2];
25932
coordinates[6][0] = x[2][0];
25933
coordinates[6][1] = x[2][1];
25934
coordinates[6][2] = x[2][2];
25935
coordinates[7][0] = x[3][0];
25936
coordinates[7][1] = x[3][1];
25937
coordinates[7][2] = x[3][2];
25938
coordinates[8][0] = x[0][0];
25939
coordinates[8][1] = x[0][1];
25940
coordinates[8][2] = x[0][2];
25941
coordinates[9][0] = x[1][0];
25942
coordinates[9][1] = x[1][1];
25943
coordinates[9][2] = x[1][2];
25944
coordinates[10][0] = x[2][0];
25945
coordinates[10][1] = x[2][1];
25946
coordinates[10][2] = x[2][2];
25947
coordinates[11][0] = x[3][0];
25948
coordinates[11][1] = x[3][1];
25949
coordinates[11][2] = x[3][2];
25952
/// Return the number of sub dof maps (for a mixed element)
25953
virtual unsigned int num_sub_dof_maps() const
25958
/// Create a new dof_map for sub dof map i (for a mixed element)
25959
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
25964
return new hyperelasticity_1_dof_map_3_0();
25967
return new hyperelasticity_1_dof_map_3_1();
25970
return new hyperelasticity_1_dof_map_3_2();
25978
/// This class defines the interface for a local-to-global mapping of
25979
/// degrees of freedom (dofs).
25981
class hyperelasticity_1_dof_map_4: public ufc::dof_map
25985
unsigned int __global_dimension;
25990
hyperelasticity_1_dof_map_4() : ufc::dof_map()
25992
__global_dimension = 0;
25996
virtual ~hyperelasticity_1_dof_map_4()
26001
/// Return a string identifying the dof map
26002
virtual const char* signature() const
26004
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
26007
/// Return true iff mesh entities of topological dimension d are needed
26008
virtual bool needs_mesh_entities(unsigned int d) const
26028
/// Initialize dof map for mesh (return true iff init_cell() is needed)
26029
virtual bool init_mesh(const ufc::mesh& m)
26031
__global_dimension = m.num_entities[3];
26035
/// Initialize dof map for given cell
26036
virtual void init_cell(const ufc::mesh& m,
26037
const ufc::cell& c)
26042
/// Finish initialization of dof map for cells
26043
virtual void init_cell_finalize()
26048
/// Return the dimension of the global finite element function space
26049
virtual unsigned int global_dimension() const
26051
return __global_dimension;
26054
/// Return the dimension of the local finite element function space for a cell
26055
virtual unsigned int local_dimension(const ufc::cell& c) const
26060
/// Return the maximum dimension of the local finite element function space
26061
virtual unsigned int max_local_dimension() const
26066
// Return the geometric dimension of the coordinates this dof map provides
26067
virtual unsigned int geometric_dimension() const
26072
/// Return the number of dofs on each cell facet
26073
virtual unsigned int num_facet_dofs() const
26078
/// Return the number of dofs associated with each cell entity of dimension d
26079
virtual unsigned int num_entity_dofs(unsigned int d) const
26081
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
26084
/// Tabulate the local-to-global mapping of dofs on a cell
26085
virtual void tabulate_dofs(unsigned int* dofs,
26086
const ufc::mesh& m,
26087
const ufc::cell& c) const
26089
dofs[0] = c.entity_indices[3][0];
26092
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
26093
virtual void tabulate_facet_dofs(unsigned int* dofs,
26094
unsigned int facet) const
26113
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
26114
virtual void tabulate_entity_dofs(unsigned int* dofs,
26115
unsigned int d, unsigned int i) const
26117
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
26120
/// Tabulate the coordinates of all dofs on a cell
26121
virtual void tabulate_coordinates(double** coordinates,
26122
const ufc::cell& c) const
26124
const double * const * x = c.coordinates;
26125
coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
26126
coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
26127
coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
26130
/// Return the number of sub dof maps (for a mixed element)
26131
virtual unsigned int num_sub_dof_maps() const
26136
/// Create a new dof_map for sub dof map i (for a mixed element)
26137
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
26139
return new hyperelasticity_1_dof_map_4();
26144
/// This class defines the interface for a local-to-global mapping of
26145
/// degrees of freedom (dofs).
26147
class hyperelasticity_1_dof_map_5: public ufc::dof_map
26151
unsigned int __global_dimension;
26156
hyperelasticity_1_dof_map_5() : ufc::dof_map()
26158
__global_dimension = 0;
26162
virtual ~hyperelasticity_1_dof_map_5()
26167
/// Return a string identifying the dof map
26168
virtual const char* signature() const
26170
return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
26173
/// Return true iff mesh entities of topological dimension d are needed
26174
virtual bool needs_mesh_entities(unsigned int d) const
26194
/// Initialize dof map for mesh (return true iff init_cell() is needed)
26195
virtual bool init_mesh(const ufc::mesh& m)
26197
__global_dimension = m.num_entities[3];
26201
/// Initialize dof map for given cell
26202
virtual void init_cell(const ufc::mesh& m,
26203
const ufc::cell& c)
26208
/// Finish initialization of dof map for cells
26209
virtual void init_cell_finalize()
26214
/// Return the dimension of the global finite element function space
26215
virtual unsigned int global_dimension() const
26217
return __global_dimension;
26220
/// Return the dimension of the local finite element function space for a cell
26221
virtual unsigned int local_dimension(const ufc::cell& c) const
26226
/// Return the maximum dimension of the local finite element function space
26227
virtual unsigned int max_local_dimension() const
26232
// Return the geometric dimension of the coordinates this dof map provides
26233
virtual unsigned int geometric_dimension() const
26238
/// Return the number of dofs on each cell facet
26239
virtual unsigned int num_facet_dofs() const
26244
/// Return the number of dofs associated with each cell entity of dimension d
26245
virtual unsigned int num_entity_dofs(unsigned int d) const
26247
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
26250
/// Tabulate the local-to-global mapping of dofs on a cell
26251
virtual void tabulate_dofs(unsigned int* dofs,
26252
const ufc::mesh& m,
26253
const ufc::cell& c) const
26255
dofs[0] = c.entity_indices[3][0];
26258
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
26259
virtual void tabulate_facet_dofs(unsigned int* dofs,
26260
unsigned int facet) const
26279
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
26280
virtual void tabulate_entity_dofs(unsigned int* dofs,
26281
unsigned int d, unsigned int i) const
26283
throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
26286
/// Tabulate the coordinates of all dofs on a cell
26287
virtual void tabulate_coordinates(double** coordinates,
26288
const ufc::cell& c) const
26290
const double * const * x = c.coordinates;
26291
coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
26292
coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
26293
coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
26296
/// Return the number of sub dof maps (for a mixed element)
26297
virtual unsigned int num_sub_dof_maps() const
26302
/// Create a new dof_map for sub dof map i (for a mixed element)
26303
virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
26305
return new hyperelasticity_1_dof_map_5();
26310
/// This class defines the interface for the tabulation of the cell
26311
/// tensor corresponding to the local contribution to a form from
26312
/// the integral over a cell.
26314
class hyperelasticity_1_cell_integral_0_quadrature: public ufc::cell_integral
26319
hyperelasticity_1_cell_integral_0_quadrature() : ufc::cell_integral()
26325
virtual ~hyperelasticity_1_cell_integral_0_quadrature()
26330
/// Tabulate the tensor for the contribution from a local cell
26331
virtual void tabulate_tensor(double* A,
26332
const double * const * w,
26333
const ufc::cell& c) const
26335
// Extract vertex coordinates
26336
const double * const * x = c.coordinates;
26338
// Compute Jacobian of affine map from reference cell
26339
const double J_00 = x[1][0] - x[0][0];
26340
const double J_01 = x[2][0] - x[0][0];
26341
const double J_02 = x[3][0] - x[0][0];
26342
const double J_10 = x[1][1] - x[0][1];
26343
const double J_11 = x[2][1] - x[0][1];
26344
const double J_12 = x[3][1] - x[0][1];
26345
const double J_20 = x[1][2] - x[0][2];
26346
const double J_21 = x[2][2] - x[0][2];
26347
const double J_22 = x[3][2] - x[0][2];
26349
// Compute sub determinants
26350
const double d_00 = J_11*J_22 - J_12*J_21;
26351
const double d_01 = J_12*J_20 - J_10*J_22;
26352
const double d_02 = J_10*J_21 - J_11*J_20;
26354
const double d_10 = J_02*J_21 - J_01*J_22;
26355
const double d_11 = J_00*J_22 - J_02*J_20;
26356
const double d_12 = J_01*J_20 - J_00*J_21;
26358
const double d_20 = J_01*J_12 - J_02*J_11;
26359
const double d_21 = J_02*J_10 - J_00*J_12;
26360
const double d_22 = J_00*J_11 - J_01*J_10;
26362
// Compute determinant of Jacobian
26363
double detJ = J_00*d_00 + J_10*d_10 + J_20*d_20;
26365
// Compute inverse of Jacobian
26366
const double Jinv_00 = d_00 / detJ;
26367
const double Jinv_01 = d_10 / detJ;
26368
const double Jinv_02 = d_20 / detJ;
26369
const double Jinv_10 = d_01 / detJ;
26370
const double Jinv_11 = d_11 / detJ;
26371
const double Jinv_12 = d_21 / detJ;
26372
const double Jinv_20 = d_02 / detJ;
26373
const double Jinv_21 = d_12 / detJ;
26374
const double Jinv_22 = d_22 / detJ;
26376
// Set scale factor
26377
const double det = std::abs(detJ);
26380
// Array of quadrature weights
26381
static const double W8[8] = {0.0369798564, 0.0160270406, 0.0211570065, 0.00916942992, 0.0369798564, 0.0160270406, 0.0211570065, 0.00916942992};
26382
// Quadrature points on the UFC reference element: (0.156682637, 0.136054977, 0.122514823), (0.081395667, 0.0706797242, 0.544151844), (0.0658386871, 0.565933165, 0.122514823), (0.0342027932, 0.293998801, 0.544151844), (0.584747563, 0.136054977, 0.122514823), (0.303772765, 0.0706797242, 0.544151844), (0.245713325, 0.565933165, 0.122514823), (0.127646562, 0.293998801, 0.544151844)
26384
// Value of basis functions at quadrature points.
26385
static const double FE1_C0[8][12] = \
26386
{{0.584747563, 0.156682637, 0.136054977, 0.122514823, 0, 0, 0, 0, 0, 0, 0, 0},
26387
{0.303772765, 0.081395667, 0.0706797242, 0.544151844, 0, 0, 0, 0, 0, 0, 0, 0},
26388
{0.245713325, 0.0658386871, 0.565933165, 0.122514823, 0, 0, 0, 0, 0, 0, 0, 0},
26389
{0.127646562, 0.0342027932, 0.293998801, 0.544151844, 0, 0, 0, 0, 0, 0, 0, 0},
26390
{0.156682637, 0.584747563, 0.136054977, 0.122514823, 0, 0, 0, 0, 0, 0, 0, 0},
26391
{0.081395667, 0.303772765, 0.0706797242, 0.544151844, 0, 0, 0, 0, 0, 0, 0, 0},
26392
{0.0658386871, 0.245713325, 0.565933165, 0.122514823, 0, 0, 0, 0, 0, 0, 0, 0},
26393
{0.0342027932, 0.127646562, 0.293998801, 0.544151844, 0, 0, 0, 0, 0, 0, 0, 0}};
26395
static const double FE1_C0_D001[8][12] = \
26396
{{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
26397
{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
26398
{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
26399
{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
26400
{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
26401
{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
26402
{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
26403
{-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}};
26405
static const double FE1_C0_D010[8][12] = \
26406
{{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26407
{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26408
{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26409
{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26410
{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26411
{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26412
{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26413
{-1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
26415
static const double FE1_C0_D100[8][12] = \
26416
{{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26417
{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26418
{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26419
{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26420
{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26421
{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26422
{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26423
{-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
26425
static const double FE1_C1[8][12] = \
26426
{{0, 0, 0, 0, 0.584747563, 0.156682637, 0.136054977, 0.122514823, 0, 0, 0, 0},
26427
{0, 0, 0, 0, 0.303772765, 0.081395667, 0.0706797242, 0.544151844, 0, 0, 0, 0},
26428
{0, 0, 0, 0, 0.245713325, 0.0658386871, 0.565933165, 0.122514823, 0, 0, 0, 0},
26429
{0, 0, 0, 0, 0.127646562, 0.0342027932, 0.293998801, 0.544151844, 0, 0, 0, 0},
26430
{0, 0, 0, 0, 0.156682637, 0.584747563, 0.136054977, 0.122514823, 0, 0, 0, 0},
26431
{0, 0, 0, 0, 0.081395667, 0.303772765, 0.0706797242, 0.544151844, 0, 0, 0, 0},
26432
{0, 0, 0, 0, 0.0658386871, 0.245713325, 0.565933165, 0.122514823, 0, 0, 0, 0},
26433
{0, 0, 0, 0, 0.0342027932, 0.127646562, 0.293998801, 0.544151844, 0, 0, 0, 0}};
26435
static const double FE1_C1_D001[8][12] = \
26436
{{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0},
26437
{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0},
26438
{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0},
26439
{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0},
26440
{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0},
26441
{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0},
26442
{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0},
26443
{0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0}};
26445
static const double FE1_C1_D010[8][12] = \
26446
{{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0},
26447
{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0},
26448
{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0},
26449
{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0},
26450
{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0},
26451
{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0},
26452
{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0},
26453
{0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0}};
26455
static const double FE1_C1_D100[8][12] = \
26456
{{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0},
26457
{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0},
26458
{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0},
26459
{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0},
26460
{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0},
26461
{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0},
26462
{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0},
26463
{0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0}};
26465
static const double FE1_C2[8][12] = \
26466
{{0, 0, 0, 0, 0, 0, 0, 0, 0.584747563, 0.156682637, 0.136054977, 0.122514823},
26467
{0, 0, 0, 0, 0, 0, 0, 0, 0.303772765, 0.081395667, 0.0706797242, 0.544151844},
26468
{0, 0, 0, 0, 0, 0, 0, 0, 0.245713325, 0.0658386871, 0.565933165, 0.122514823},
26469
{0, 0, 0, 0, 0, 0, 0, 0, 0.127646562, 0.0342027932, 0.293998801, 0.544151844},
26470
{0, 0, 0, 0, 0, 0, 0, 0, 0.156682637, 0.584747563, 0.136054977, 0.122514823},
26471
{0, 0, 0, 0, 0, 0, 0, 0, 0.081395667, 0.303772765, 0.0706797242, 0.544151844},
26472
{0, 0, 0, 0, 0, 0, 0, 0, 0.0658386871, 0.245713325, 0.565933165, 0.122514823},
26473
{0, 0, 0, 0, 0, 0, 0, 0, 0.0342027932, 0.127646562, 0.293998801, 0.544151844}};
26475
static const double FE1_C2_D001[8][12] = \
26476
{{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1},
26477
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1},
26478
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1},
26479
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1},
26480
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1},
26481
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1},
26482
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1},
26483
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1}};
26485
static const double FE1_C2_D010[8][12] = \
26486
{{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0},
26487
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0},
26488
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0},
26489
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0},
26490
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0},
26491
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0},
26492
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0},
26493
{0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0}};
26495
static const double FE1_C2_D100[8][12] = \
26496
{{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0},
26497
{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0},
26498
{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0},
26499
{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0},
26500
{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0},
26501
{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0},
26502
{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0},
26503
{0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0}};
26506
// Compute element tensor using UFL quadrature representation
26507
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
26508
// Total number of operations to compute element tensor: 232128
26510
// Loop quadrature points for integral
26511
// Number of operations to compute element tensor for following IP loop = 232128
26512
for (unsigned int ip = 0; ip < 8; ip++)
26515
// Function declarations
26529
// Total number of operations to compute function values = 288
26530
for (unsigned int r = 0; r < 12; r++)
26532
F0 += FE1_C0_D100[ip][r]*w[0][r];
26533
F1 += FE1_C0_D010[ip][r]*w[0][r];
26534
F2 += FE1_C0_D001[ip][r]*w[0][r];
26535
F3 += FE1_C1_D100[ip][r]*w[0][r];
26536
F4 += FE1_C1_D010[ip][r]*w[0][r];
26537
F5 += FE1_C1_D001[ip][r]*w[0][r];
26538
F6 += FE1_C2_D100[ip][r]*w[0][r];
26539
F7 += FE1_C2_D010[ip][r]*w[0][r];
26540
F8 += FE1_C2_D001[ip][r]*w[0][r];
26541
F9 += FE1_C0[ip][r]*w[1][r];
26542
F10 += FE1_C1[ip][r]*w[1][r];
26543
F11 += FE1_C2[ip][r]*w[1][r];
26544
}// end loop over 'r'
26546
// Number of operations for primary indices: 28728
26547
for (unsigned int j = 0; j < 12; j++)
26549
// Number of operations to compute entry: 2394
26550
A[j] += ((FE1_C1[ip][j]*F10 + FE1_C0[ip][j]*F9 + FE1_C2[ip][j]*F11)*-1 + (((Jinv_00*FE1_C2_D100[ip][j] + Jinv_10*FE1_C2_D010[ip][j] + Jinv_20*FE1_C2_D001[ip][j])*((1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*w[3][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5))/(2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*w[3][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2))/(2) + (Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(w[3][0]*2*(((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2)) + (Jinv_00*FE1_C0_D100[ip][j] + Jinv_10*FE1_C0_D010[ip][j] + Jinv_20*FE1_C0_D001[ip][j])*((Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*w[3][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2))/(2) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*w[3][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5))/(2) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(w[3][0]*2*(((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2)) + (Jinv_00*FE1_C1_D100[ip][j] + Jinv_10*FE1_C1_D010[ip][j] + Jinv_20*FE1_C1_D001[ip][j])*((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*w[3][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5))/(2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(w[3][0]*2*(((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*w[3][0]*2*((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2))/(2))) + ((Jinv_02*FE1_C2_D100[ip][j] + Jinv_12*FE1_C2_D010[ip][j] + Jinv_22*FE1_C2_D001[ip][j])*((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*w[3][0]*2*((Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*w[3][0]*2*((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(w[3][0]*2*(((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2) + w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2)) + (Jinv_02*FE1_C1_D100[ip][j] + Jinv_12*FE1_C1_D010[ip][j] + Jinv_22*FE1_C1_D001[ip][j])*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*w[3][0]*2*((Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*w[3][0]*2*((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(w[3][0]*2*(((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2) + w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2)) + (Jinv_02*FE1_C0_D100[ip][j] + Jinv_12*FE1_C0_D010[ip][j] + Jinv_22*FE1_C0_D001[ip][j])*((1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*w[3][0]*2*((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*w[3][0]*2*((Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5)) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8))/(2) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(w[3][0]*2*(((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2) + w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2))) + ((Jinv_01*FE1_C2_D100[ip][j] + Jinv_11*FE1_C2_D010[ip][j] + Jinv_21*FE1_C2_D001[ip][j])*((1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*w[3][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)))/(2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[3][0]*2*(((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2)) + (Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*w[3][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2)) + (Jinv_01*FE1_C0_D100[ip][j] + Jinv_11*FE1_C0_D010[ip][j] + Jinv_21*FE1_C0_D001[ip][j])*((Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[3][0]*2*(((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2)) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*w[3][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*w[3][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)))/(2)) + (Jinv_01*FE1_C1_D100[ip][j] + Jinv_11*FE1_C1_D010[ip][j] + Jinv_21*FE1_C1_D001[ip][j])*((Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*w[3][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2)))/(2) + (Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*w[3][0]*2*((1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8)))/(2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(w[4][0]/(2)*((((Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8)*(Jinv_00*F6 + Jinv_10*F7 + Jinv_20*F8) + (Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5)*(Jinv_00*F3 + Jinv_10*F4 + Jinv_20*F5) + (1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))*(1 + (Jinv_00*F0 + Jinv_10*F1 + Jinv_20*F2))) + -1)/(2) + (((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2) + (((Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5)*(Jinv_02*F3 + Jinv_12*F4 + Jinv_22*F5) + (Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2)*(Jinv_02*F0 + Jinv_12*F1 + Jinv_22*F2) + (1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))*(1 + (Jinv_02*F6 + Jinv_12*F7 + Jinv_22*F8))) + -1)/(2))*2 + w[3][0]*2*(((Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8)*(Jinv_01*F6 + Jinv_11*F7 + Jinv_21*F8) + (Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2)*(Jinv_01*F0 + Jinv_11*F1 + Jinv_21*F2) + (1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))*(1 + (Jinv_01*F3 + Jinv_11*F4 + Jinv_21*F5))) + -1)/(2))))))*W8[ip]*det;
26551
}// end loop over 'j'
26552
}// end loop over 'ip'
26557
/// This class defines the interface for the tabulation of the cell
26558
/// tensor corresponding to the local contribution to a form from
26559
/// the integral over a cell.
26561
class hyperelasticity_1_cell_integral_0: public ufc::cell_integral
26565
hyperelasticity_1_cell_integral_0_quadrature integral_0_quadrature;
26570
hyperelasticity_1_cell_integral_0() : ufc::cell_integral()
26576
virtual ~hyperelasticity_1_cell_integral_0()
26581
/// Tabulate the tensor for the contribution from a local cell
26582
virtual void tabulate_tensor(double* A,
26583
const double * const * w,
26584
const ufc::cell& c) const
26586
// Reset values of the element tensor block
26587
for (unsigned int j = 0; j < 12; j++)
26590
// Add all contributions to element tensor
26591
integral_0_quadrature.tabulate_tensor(A, w, c);
26596
/// This class defines the interface for the tabulation of the
26597
/// exterior facet tensor corresponding to the local contribution to
26598
/// a form from the integral over an exterior facet.
26600
class hyperelasticity_1_exterior_facet_integral_0_quadrature: public ufc::exterior_facet_integral
26605
hyperelasticity_1_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
26611
virtual ~hyperelasticity_1_exterior_facet_integral_0_quadrature()
26616
/// Tabulate the tensor for the contribution from a local exterior facet
26617
virtual void tabulate_tensor(double* A,
26618
const double * const * w,
26619
const ufc::cell& c,
26620
unsigned int facet) const
26622
// Extract vertex coordinates
26623
const double * const * x = c.coordinates;
26625
// Compute Jacobian of affine map from reference cell
26627
// Compute sub determinants
26631
// Compute determinant of Jacobian
26633
// Compute inverse of Jacobian
26635
// Vertices on faces
26636
static unsigned int face_vertices[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
26639
const unsigned int v0 = face_vertices[facet][0];
26640
const unsigned int v1 = face_vertices[facet][1];
26641
const unsigned int v2 = face_vertices[facet][2];
26643
// Compute scale factor (area of face scaled by area of reference triangle)
26644
const double a0 = (x[v0][1]*x[v1][2] + x[v0][2]*x[v2][1] + x[v1][1]*x[v2][2])
26645
- (x[v2][1]*x[v1][2] + x[v2][2]*x[v0][1] + x[v1][1]*x[v0][2]);
26646
const double a1 = (x[v0][2]*x[v1][0] + x[v0][0]*x[v2][2] + x[v1][2]*x[v2][0])
26647
- (x[v2][2]*x[v1][0] + x[v2][0]*x[v0][2] + x[v1][2]*x[v0][0]);
26648
const double a2 = (x[v0][0]*x[v1][1] + x[v0][1]*x[v2][0] + x[v1][0]*x[v2][1])
26649
- (x[v2][0]*x[v1][1] + x[v2][1]*x[v0][0] + x[v1][0]*x[v0][1]);
26650
const double det = std::sqrt(a0*a0 + a1*a1 + a2*a2);
26652
// Compute facet normals from the facet scale factor constants
26655
// Array of quadrature weights
26656
static const double W4[4] = {0.159020691, 0.0909793091, 0.159020691, 0.0909793091};
26657
// Quadrature points on the UFC reference element: (0.178558728, 0.155051026), (0.0750311102, 0.644948974), (0.666390246, 0.155051026), (0.280019915, 0.644948974)
26659
// Value of basis functions at quadrature points.
26660
static const double FE0_f0_C0[4][12] = \
26661
{{0, 0.666390246, 0.178558728, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0},
26662
{0, 0.280019915, 0.0750311102, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0},
26663
{0, 0.178558728, 0.666390246, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0},
26664
{0, 0.0750311102, 0.280019915, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0}};
26666
static const double FE0_f0_C1[4][12] = \
26667
{{0, 0, 0, 0, 0, 0.666390246, 0.178558728, 0.155051026, 0, 0, 0, 0},
26668
{0, 0, 0, 0, 0, 0.280019915, 0.0750311102, 0.644948974, 0, 0, 0, 0},
26669
{0, 0, 0, 0, 0, 0.178558728, 0.666390246, 0.155051026, 0, 0, 0, 0},
26670
{0, 0, 0, 0, 0, 0.0750311102, 0.280019915, 0.644948974, 0, 0, 0, 0}};
26672
static const double FE0_f0_C2[4][12] = \
26673
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0.666390246, 0.178558728, 0.155051026},
26674
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0.280019915, 0.0750311102, 0.644948974},
26675
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0.178558728, 0.666390246, 0.155051026},
26676
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0750311102, 0.280019915, 0.644948974}};
26678
static const double FE0_f1_C0[4][12] = \
26679
{{0.666390246, 0, 0.178558728, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0},
26680
{0.280019915, 0, 0.0750311102, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0},
26681
{0.178558728, 0, 0.666390246, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0},
26682
{0.0750311102, 0, 0.280019915, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0}};
26684
static const double FE0_f1_C1[4][12] = \
26685
{{0, 0, 0, 0, 0.666390246, 0, 0.178558728, 0.155051026, 0, 0, 0, 0},
26686
{0, 0, 0, 0, 0.280019915, 0, 0.0750311102, 0.644948974, 0, 0, 0, 0},
26687
{0, 0, 0, 0, 0.178558728, 0, 0.666390246, 0.155051026, 0, 0, 0, 0},
26688
{0, 0, 0, 0, 0.0750311102, 0, 0.280019915, 0.644948974, 0, 0, 0, 0}};
26690
static const double FE0_f1_C2[4][12] = \
26691
{{0, 0, 0, 0, 0, 0, 0, 0, 0.666390246, 0, 0.178558728, 0.155051026},
26692
{0, 0, 0, 0, 0, 0, 0, 0, 0.280019915, 0, 0.0750311102, 0.644948974},
26693
{0, 0, 0, 0, 0, 0, 0, 0, 0.178558728, 0, 0.666390246, 0.155051026},
26694
{0, 0, 0, 0, 0, 0, 0, 0, 0.0750311102, 0, 0.280019915, 0.644948974}};
26696
static const double FE0_f2_C0[4][12] = \
26697
{{0.666390246, 0.178558728, 0, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0},
26698
{0.280019915, 0.0750311102, 0, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0},
26699
{0.178558728, 0.666390246, 0, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0},
26700
{0.0750311102, 0.280019915, 0, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0}};
26702
static const double FE0_f2_C1[4][12] = \
26703
{{0, 0, 0, 0, 0.666390246, 0.178558728, 0, 0.155051026, 0, 0, 0, 0},
26704
{0, 0, 0, 0, 0.280019915, 0.0750311102, 0, 0.644948974, 0, 0, 0, 0},
26705
{0, 0, 0, 0, 0.178558728, 0.666390246, 0, 0.155051026, 0, 0, 0, 0},
26706
{0, 0, 0, 0, 0.0750311102, 0.280019915, 0, 0.644948974, 0, 0, 0, 0}};
26708
static const double FE0_f2_C2[4][12] = \
26709
{{0, 0, 0, 0, 0, 0, 0, 0, 0.666390246, 0.178558728, 0, 0.155051026},
26710
{0, 0, 0, 0, 0, 0, 0, 0, 0.280019915, 0.0750311102, 0, 0.644948974},
26711
{0, 0, 0, 0, 0, 0, 0, 0, 0.178558728, 0.666390246, 0, 0.155051026},
26712
{0, 0, 0, 0, 0, 0, 0, 0, 0.0750311102, 0.280019915, 0, 0.644948974}};
26714
static const double FE0_f3_C0[4][12] = \
26715
{{0.666390246, 0.178558728, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26716
{0.280019915, 0.0750311102, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26717
{0.178558728, 0.666390246, 0.155051026, 0, 0, 0, 0, 0, 0, 0, 0, 0},
26718
{0.0750311102, 0.280019915, 0.644948974, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
26720
static const double FE0_f3_C1[4][12] = \
26721
{{0, 0, 0, 0, 0.666390246, 0.178558728, 0.155051026, 0, 0, 0, 0, 0},
26722
{0, 0, 0, 0, 0.280019915, 0.0750311102, 0.644948974, 0, 0, 0, 0, 0},
26723
{0, 0, 0, 0, 0.178558728, 0.666390246, 0.155051026, 0, 0, 0, 0, 0},
26724
{0, 0, 0, 0, 0.0750311102, 0.280019915, 0.644948974, 0, 0, 0, 0, 0}};
26726
static const double FE0_f3_C2[4][12] = \
26727
{{0, 0, 0, 0, 0, 0, 0, 0, 0.666390246, 0.178558728, 0.155051026, 0},
26728
{0, 0, 0, 0, 0, 0, 0, 0, 0.280019915, 0.0750311102, 0.644948974, 0},
26729
{0, 0, 0, 0, 0, 0, 0, 0, 0.178558728, 0.666390246, 0.155051026, 0},
26730
{0, 0, 0, 0, 0, 0, 0, 0, 0.0750311102, 0.280019915, 0.644948974, 0}};
26733
// Compute element tensor using UFL quadrature representation
26734
// Optimisations: ('simplify expressions', False), ('ignore zero tables', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False)
26739
// Total number of operations to compute element tensor (from this point): 720
26741
// Loop quadrature points for integral
26742
// Number of operations to compute element tensor for following IP loop = 720
26743
for (unsigned int ip = 0; ip < 4; ip++)
26746
// Function declarations
26751
// Total number of operations to compute function values = 72
26752
for (unsigned int r = 0; r < 12; r++)
26754
F0 += FE0_f0_C0[ip][r]*w[2][r];
26755
F1 += FE0_f0_C1[ip][r]*w[2][r];
26756
F2 += FE0_f0_C2[ip][r]*w[2][r];
26757
}// end loop over 'r'
26759
// Number of operations for primary indices: 108
26760
for (unsigned int j = 0; j < 12; j++)
26762
// Number of operations to compute entry: 9
26763
A[j] += (FE0_f0_C0[ip][j]*F0 + FE0_f0_C1[ip][j]*F1 + FE0_f0_C2[ip][j]*F2)*-1*W4[ip]*det;
26764
}// end loop over 'j'
26765
}// end loop over 'ip'
26770
// Total number of operations to compute element tensor (from this point): 720
26772
// Loop quadrature points for integral
26773
// Number of operations to compute element tensor for following IP loop = 720
26774
for (unsigned int ip = 0; ip < 4; ip++)
26777
// Function declarations
26782
// Total number of operations to compute function values = 72
26783
for (unsigned int r = 0; r < 12; r++)
26785
F0 += FE0_f1_C0[ip][r]*w[2][r];
26786
F1 += FE0_f1_C1[ip][r]*w[2][r];
26787
F2 += FE0_f1_C2[ip][r]*w[2][r];
26788
}// end loop over 'r'
26790
// Number of operations for primary indices: 108
26791
for (unsigned int j = 0; j < 12; j++)
26793
// Number of operations to compute entry: 9
26794
A[j] += (FE0_f1_C2[ip][j]*F2 + FE0_f1_C0[ip][j]*F0 + FE0_f1_C1[ip][j]*F1)*-1*W4[ip]*det;
26795
}// end loop over 'j'
26796
}// end loop over 'ip'
26801
// Total number of operations to compute element tensor (from this point): 720
26803
// Loop quadrature points for integral
26804
// Number of operations to compute element tensor for following IP loop = 720
26805
for (unsigned int ip = 0; ip < 4; ip++)
26808
// Function declarations
26813
// Total number of operations to compute function values = 72
26814
for (unsigned int r = 0; r < 12; r++)
26816
F0 += FE0_f2_C0[ip][r]*w[2][r];
26817
F1 += FE0_f2_C1[ip][r]*w[2][r];
26818
F2 += FE0_f2_C2[ip][r]*w[2][r];
26819
}// end loop over 'r'
26821
// Number of operations for primary indices: 108
26822
for (unsigned int j = 0; j < 12; j++)
26824
// Number of operations to compute entry: 9
26825
A[j] += (FE0_f2_C2[ip][j]*F2 + FE0_f2_C1[ip][j]*F1 + FE0_f2_C0[ip][j]*F0)*-1*W4[ip]*det;
26826
}// end loop over 'j'
26827
}// end loop over 'ip'
26832
// Total number of operations to compute element tensor (from this point): 720
26834
// Loop quadrature points for integral
26835
// Number of operations to compute element tensor for following IP loop = 720
26836
for (unsigned int ip = 0; ip < 4; ip++)
26839
// Function declarations
26844
// Total number of operations to compute function values = 72
26845
for (unsigned int r = 0; r < 12; r++)
26847
F0 += FE0_f3_C0[ip][r]*w[2][r];
26848
F1 += FE0_f3_C1[ip][r]*w[2][r];
26849
F2 += FE0_f3_C2[ip][r]*w[2][r];
26850
}// end loop over 'r'
26852
// Number of operations for primary indices: 108
26853
for (unsigned int j = 0; j < 12; j++)
26855
// Number of operations to compute entry: 9
26856
A[j] += (FE0_f3_C1[ip][j]*F1 + FE0_f3_C2[ip][j]*F2 + FE0_f3_C0[ip][j]*F0)*-1*W4[ip]*det;
26857
}// end loop over 'j'
26858
}// end loop over 'ip'
26866
/// This class defines the interface for the tabulation of the
26867
/// exterior facet tensor corresponding to the local contribution to
26868
/// a form from the integral over an exterior facet.
26870
class hyperelasticity_1_exterior_facet_integral_0: public ufc::exterior_facet_integral
26874
hyperelasticity_1_exterior_facet_integral_0_quadrature integral_0_quadrature;
26879
hyperelasticity_1_exterior_facet_integral_0() : ufc::exterior_facet_integral()
26885
virtual ~hyperelasticity_1_exterior_facet_integral_0()
26890
/// Tabulate the tensor for the contribution from a local exterior facet
26891
virtual void tabulate_tensor(double* A,
26892
const double * const * w,
26893
const ufc::cell& c,
26894
unsigned int facet) const
26896
// Reset values of the element tensor block
26897
for (unsigned int j = 0; j < 12; j++)
26900
// Add all contributions to element tensor
26901
integral_0_quadrature.tabulate_tensor(A, w, c, facet);
26906
/// This class defines the interface for the assembly of the global
26907
/// tensor corresponding to a form with r + n arguments, that is, a
26910
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
26912
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
26913
/// global tensor A is defined by
26915
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
26917
/// where each argument Vj represents the application to the
26918
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
26919
/// fixed functions (coefficients).
26921
class hyperelasticity_form_1: public ufc::form
26926
hyperelasticity_form_1() : ufc::form()
26932
virtual ~hyperelasticity_form_1()
26937
/// Return a string identifying the form
26938
virtual const char* signature() const
26940
return "Form([Integral(Sum(IndexSum(IndexSum(Product(Indexed(ComponentTensor(IndexSum(Product(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), MultiIndex((Index(1), Index(0)), {Index(0): 3, Index(1): 3})), Identity(3)), MultiIndex((Index(2), Index(3)), {Index(2): 3, Index(3): 3})), Indexed(Sum(ComponentTensor(Product(Constant(Cell('tetrahedron', 1, Space(3)), 3), Indexed(IndexSum(ComponentTensor(Indexed(ComponentTensor(Indexed(IndexSum(Sum(ComponentTensor(Product(Indexed(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(8), Index(9), Index(10), Index(11)), {Index(11): 3, Index(8): 3, Index(9): 3, Index(10): 3})), MultiIndex((Index(10), Index(11)), {Index(11): 3, Index(10): 3})), MultiIndex((Index(12), Index(13)), {Index(13): 3, Index(12): 3})), Indexed(Variable(ComponentTensor(Division(Indexed(Sum(ComponentTensor(IndexSum(Product(Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), ComponentTensor(Product(IntValue(-1, (), (), {}), Indexed(Identity(3), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), Label(0)), MultiIndex((Index(9), Index(27)), {Index(9): 3, Index(27): 3}))), MultiIndex((Index(12), Index(13)), {Index(13): 3, Index(12): 3})), ComponentTensor(Product(Indexed(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(9), Index(27), Index(28), Index(29)), {Index(29): 3, Index(9): 3, Index(28): 3, Index(27): 3})), MultiIndex((Index(28), Index(29)), {Index(29): 3, Index(28): 3})), MultiIndex((Index(30), Index(31)), {Index(31): 3, Index(30): 3})), Indexed(Variable(ComponentTensor(Division(Indexed(Sum(ComponentTensor(IndexSum(Product(Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), ComponentTensor(Product(IntValue(-1, (), (), {}), Indexed(Identity(3), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), Label(0)), MultiIndex((Index(8), Index(9)), {Index(8): 3, Index(9): 3}))), MultiIndex((Index(30), Index(31)), {Index(31): 3, Index(30): 3}))), MultiIndex((Index(9),), {Index(9): 3})), MultiIndex((Index(32), Index(33)), {Index(33): 3, Index(32): 3})), MultiIndex((Index(8), Index(27), Index(32), Index(33)), {Index(33): 3, Index(27): 3, Index(32): 3, Index(8): 3})), MultiIndex((Index(34), Index(34), Index(35), Index(36)), {Index(35): 3, Index(36): 3, Index(34): 3})), MultiIndex((Index(35), Index(36)), {Index(35): 3, Index(36): 3})), MultiIndex((Index(34),), {Index(34): 3})), MultiIndex((Index(37), Index(38)), {Index(37): 3, Index(38): 3}))), MultiIndex((Index(37), Index(38)), {Index(37): 3, Index(38): 3})), ComponentTensor(Product(Division(Constant(Cell('tetrahedron', 1, Space(3)), 4), IntValue(2, (), (), {})), Indexed(ComponentTensor(Product(IndexSum(Indexed(Variable(ComponentTensor(Division(Indexed(Sum(ComponentTensor(IndexSum(Product(Indexed(ComponentTensor(Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(14),), {Index(14): 3})), MultiIndex((Index(15),), {Index(15): 3})), MultiIndex((Index(15), Index(14)), {Index(14): 3, Index(15): 3})), Identity(3)), MultiIndex((Index(16), Index(17)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(17), Index(16)), {Index(17): 3, Index(16): 3})), MultiIndex((Index(18), Index(19)), {Index(19): 3, Index(18): 3})), Indexed(Sum(ComponentTensor(Indexed(SpatialDerivative(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(20),), {Index(20): 3})), MultiIndex((Index(21),), {Index(21): 3})), MultiIndex((Index(21), Index(20)), {Index(21): 3, Index(20): 3})), Identity(3)), MultiIndex((Index(19), Index(22)), {Index(22): 3, Index(19): 3}))), MultiIndex((Index(19),), {Index(19): 3})), MultiIndex((Index(18), Index(22)), {Index(22): 3, Index(18): 3})), ComponentTensor(Product(IntValue(-1, (), (), {}), Indexed(Identity(3), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(23), Index(24)), {Index(24): 3, Index(23): 3}))), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), IntValue(2, (), (), {})), MultiIndex((Index(25), Index(26)), {Index(26): 3, Index(25): 3})), Label(0)), MultiIndex((Index(39), Index(39)), {Index(39): 3})), MultiIndex((Index(39),), {Index(39): 3})), Indexed(ComponentTensor(Product(IntValue(2, (), (), {}), Indexed(IndexSum(ComponentTensor(Indexed(ComponentTensor(Product(Indexed(Identity(3), MultiIndex((Index(4), Index(5)), {Index(4): 3, Index(5): 3})), Indexed(Identity(3), MultiIndex((Index(6), Index(7)), {Index(7): 3, Index(6): 3}))), MultiIndex((Index(4), Index(6), Index(5), Index(7)), {Index(7): 3, Index(4): 3, Index(5): 3, Index(6): 3})), MultiIndex((Index(39), Index(39), Index(40), Index(41)), {Index(40): 3, Index(41): 3, Index(39): 3})), MultiIndex((Index(40), Index(41)), {Index(40): 3, Index(41): 3})), MultiIndex((Index(39),), {Index(39): 3})), MultiIndex((Index(42), Index(43)), {Index(43): 3, Index(42): 3}))), MultiIndex((Index(42), Index(43)), {Index(43): 3, Index(42): 3})), MultiIndex((Index(44), Index(45)), {Index(44): 3, Index(45): 3}))), MultiIndex((Index(44), Index(45)), {Index(44): 3, Index(45): 3})), MultiIndex((Index(46), Index(47)), {Index(46): 3, Index(47): 3}))), MultiIndex((Index(46), Index(47)), {Index(46): 3, Index(47): 3}))), MultiIndex((Index(3), Index(48)), {Index(48): 3, Index(3): 3}))), MultiIndex((Index(3),), {Index(3): 3})), MultiIndex((Index(2), Index(48)), {Index(48): 3, Index(2): 3})), MultiIndex((Index(49), Index(50)), {Index(50): 3, Index(49): 3})), Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(51),), {Index(51): 3})), MultiIndex((Index(52),), {Index(52): 3})), MultiIndex((Index(52), Index(51)), {Index(52): 3, Index(51): 3})), MultiIndex((Index(49), Index(50)), {Index(50): 3, Index(49): 3}))), MultiIndex((Index(49),), {Index(49): 3})), MultiIndex((Index(50),), {Index(50): 3})), Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(53),), {Index(53): 3})), Indexed(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 1), MultiIndex((Index(53),), {Index(53): 3}))), MultiIndex((Index(53),), {Index(53): 3})))), Measure('cell', 0, None)), Integral(Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 0), MultiIndex((Index(54),), {Index(54): 3})), Indexed(Function(VectorElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1, 3), 2), MultiIndex((Index(54),), {Index(54): 3}))), MultiIndex((Index(54),), {Index(54): 3}))), Measure('exterior_facet', 0, None))])";
26943
/// Return the rank of the global tensor (r)
26944
virtual unsigned int rank() const
26949
/// Return the number of coefficients (n)
26950
virtual unsigned int num_coefficients() const
26955
/// Return the number of cell integrals
26956
virtual unsigned int num_cell_integrals() const
26961
/// Return the number of exterior facet integrals
26962
virtual unsigned int num_exterior_facet_integrals() const
26967
/// Return the number of interior facet integrals
26968
virtual unsigned int num_interior_facet_integrals() const
26973
/// Create a new finite element for argument function i
26974
virtual ufc::finite_element* create_finite_element(unsigned int i) const
26979
return new hyperelasticity_1_finite_element_0();
26982
return new hyperelasticity_1_finite_element_1();
26985
return new hyperelasticity_1_finite_element_2();
26988
return new hyperelasticity_1_finite_element_3();
26991
return new hyperelasticity_1_finite_element_4();
26994
return new hyperelasticity_1_finite_element_5();
27000
/// Create a new dof map for argument function i
27001
virtual ufc::dof_map* create_dof_map(unsigned int i) const
27006
return new hyperelasticity_1_dof_map_0();
27009
return new hyperelasticity_1_dof_map_1();
27012
return new hyperelasticity_1_dof_map_2();
27015
return new hyperelasticity_1_dof_map_3();
27018
return new hyperelasticity_1_dof_map_4();
27021
return new hyperelasticity_1_dof_map_5();
27027
/// Create a new cell integral on sub domain i
27028
virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
27030
return new hyperelasticity_1_cell_integral_0();
27033
/// Create a new exterior facet integral on sub domain i
27034
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
27036
return new hyperelasticity_1_exterior_facet_integral_0();
27039
/// Create a new interior facet integral on sub domain i
27040
virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const